diff options
author | Aura Linden <aura@lindenlab.com> | 2012-12-11 16:01:35 -0800 |
---|---|---|
committer | Aura Linden <aura@lindenlab.com> | 2012-12-11 16:01:35 -0800 |
commit | e85e6ca4104df14b0bb2d625d82578c81430d28e (patch) | |
tree | 533a7ef96345e04dc32ccebff9a453f00fca845d | |
parent | 6b059d183b9516f45e775bde00f255cef8aab7c0 (diff) | |
parent | a334f41f8ebec5ef812334e5086e54256e2bf7df (diff) |
Merged from viewer-release
922 files changed, 37740 insertions, 13208 deletions
@@ -331,9 +331,44 @@ f7cbd60a3f57ff1101157eeb79ea21e8898bedae DRTVWR-235 baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236 18498afcdb835d6fc4d36ed935347d3b65307bad 3.4.1-beta11 b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237 -853a202426398cb0b7676aa498603a25d8ad20fb 3.4.1-beta12 -853a202426398cb0b7676aa498603a25d8ad20fb 3.4.1-beta12 -b6b68f3c2c6dd04ad88bd0575aad67bf87a9c108 3.4.1-beta12 -b6b68f3c2c6dd04ad88bd0575aad67bf87a9c108 3.4.1-beta12 3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12 e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release +81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186 +cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181 +c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188 +4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191 +78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194 +248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203 +de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202 +34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag +6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205 +7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206 +b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219 +32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217 +704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1 +288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216 +e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2 +0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242 +710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3 +e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243 +73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4 +16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release +d799593b53ed733862e9a13871e318e886469377 DRTVWR-208 +e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223 +93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240 +2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209 +f7bedce18ad52283e6072814db23318907261487 DRTVWR-238 +7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210 +5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241 +f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232 +4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245 +94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1 +965b9a35e260c0f53be1a25f0db7abc8a67eaf47 DRTVWR-252 +bb10adc4f76cf0067fca7075146f00cdc0740e9d DRTVWR-251 +ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253 +48382ec79741671d19ce4cc3e8cd59e9a521e4a7 DRTVWR-254 +937ec902bb9a1cbceff17bd89e3923352b0a5fbc DRTVWR-256 +44e764a6ac9e672a4f3bce821a4b6a218590c374 DRTVWR-258 +c23d734065ed593b2413385aecd8366d8e0ee96b DRTVWR-257 +452ce96d4046dc05a3ecaecc203e2cc8ddd72e76 DRTVWR-259 +5cba5f39d0a81d659f24ebc4b5efd025a39e3db1 3.4.3-release diff --git a/BuildParams b/BuildParams index 8d529c63b9..e63336cb19 100644 --- a/BuildParams +++ b/BuildParams @@ -64,6 +64,7 @@ viewer-release.build_debug_release_separately = true viewer-release.build_viewer_update_version_manager = true viewer-release.codeticket_add_context = false + # ======================================== # mesh-development # ======================================== @@ -203,4 +204,5 @@ runway.build_debug_release_separately = true runway.build_CYGWIN_Debug = false runway.build_viewer_update_version_manager = false + # eof diff --git a/autobuild.xml b/autobuild.xml index 63ba9d4a86..9a92614dfd 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -186,9 +186,9 @@ <key>archive</key> <map> <key>hash</key> - <string>d98078791ce345bf6168ce9ba53ca2d7</string> + <string>36aa500e13cdde61607b6e93065206ec</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/222752/arch/Darwin/installer/boost-1.45.0-darwin-20110304.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/261457/arch/Darwin/installer/boost-1.48.0-darwin-20120710.tar.bz2</string> </map> <key>name</key> <string>darwin</string> @@ -198,9 +198,9 @@ <key>archive</key> <map> <key>hash</key> - <string>a34e7fffdb94a6a4d8a2966b1f216da3</string> + <string>18602d44bd435eb0d7189f436ff2cb0f</string> <key>url</key> - <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.45.0-linux-20110310.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/261457/arch/Linux/installer/boost-1.48.0-linux-20120710.tar.bz2</string> </map> <key>name</key> <string>linux</string> @@ -210,9 +210,9 @@ <key>archive</key> <map> <key>hash</key> - <string>98be22c8833aa2bca184b9fa09fbb82b</string> + <string>dc8f5dc6be04c64bf3460b4932b18457</string> <key>url</key> - <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.45.0-windows-20110124.tar.bz2</string> + <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/261457/arch/CYGWIN/installer/boost-1.48.0-windows-20120710.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -1062,9 +1062,9 @@ <key>archive</key> <map> <key>hash</key> - <string>d91e1f483209cd3eba04135c6a59e829</string> + <string>a5b2dff0d97b643227a58473e5c57906</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/221672/arch/Darwin/installer/kdu-6.4.1-darwin-20110218.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/256978/arch/Darwin/installer/kdu-7.0.0-darwin-20120515.tar.bz2</string> </map> <key>name</key> <string>darwin</string> @@ -1086,9 +1086,9 @@ <key>archive</key> <map> <key>hash</key> - <string>6cd9f36465ef73a3df34bf2b3bba2ced</string> + <string>6d80d35524e1c0c32d3385014d02d48c</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/221672/arch/CYGWIN/installer/kdu-6.4.1-windows-20110218.tar.bz2</string> + <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/256978/arch/CYGWIN/installer/kdu-7.0.0-windows-20120515.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -2183,6 +2183,8 @@ <array> <string>-configuration Release</string> <string>-project SecondLife.xcodeproj</string> + <string>-DENABLE_SIGNING:BOOL=YES</string> + <string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string> </array> </map> <key>configure</key> @@ -2210,6 +2212,8 @@ <array> <string>-configuration Release</string> <string>-project SecondLife.xcodeproj</string> + <string>-DENABLE_SIGNING:BOOL=YES</string> + <string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string> </array> </map> <key>configure</key> @@ -2459,6 +2463,18 @@ </map> <key>configure</key> <map> + <key>arguments</key> + <array> + <string>..\indra</string> + <string>&&</string> + <string>..\indra\tools\vstool\VSTool.exe</string> + <string>--solution</string> + <string>SecondLife.sln</string> + <string>--config</string> + <string>Debug</string> + <string>--startup</string> + <string>secondlife-bin</string> + </array> <key>options</key> <array> <string>-G</string> @@ -2535,6 +2551,18 @@ </map> <key>configure</key> <map> + <key>arguments</key> + <array> + <string>..\indra</string> + <string>&&</string> + <string>..\indra\tools\vstool\VSTool.exe</string> + <string>--solution</string> + <string>SecondLife.sln</string> + <string>--config</string> + <string>RelWithDebInfo</string> + <string>--startup</string> + <string>secondlife-bin</string> + </array> <key>options</key> <array> <string>-G</string> @@ -2611,6 +2639,18 @@ </map> <key>configure</key> <map> + <key>arguments</key> + <array> + <string>..\indra</string> + <string>&&</string> + <string>..\indra\tools\vstool\VSTool.exe</string> + <string>--solution</string> + <string>SecondLife.sln</string> + <string>--config</string> + <string>Release</string> + <string>--startup</string> + <string>secondlife-bin</string> + </array> <key>options</key> <array> <string>-G</string> diff --git a/doc/contributions.txt b/doc/contributions.txt index df504e4a8a..f18985adcd 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -174,6 +174,7 @@ Ansariel Hiller VWR-26150 STORM-1685 STORM-1713 + STORM-1899 Aralara Rajal Ardy Lay STORM-859 @@ -400,6 +401,7 @@ Gaberoonie Zanzibar Ganymedes Costagravas Geenz Spad STORM-1823 + STORM-1900 Gene Frostbite GeneJ Composer Geneko Nemeth @@ -636,6 +638,7 @@ Jonathan Yap STORM-1809 STORM-1793 STORM-1810 + STORM-1877 STORM-1860 STORM-1852 STORM-1870 @@ -644,6 +647,7 @@ Jonathan Yap STORM-1862 Kadah Coba STORM-1060 + STORM-1843 Jondan Lundquist Josef Munster Josette Windlow @@ -654,6 +658,8 @@ Kage Pixel VWR-11 Kagehi Kohn Kaimen Takahe +Katharine Berry + STORM-1900 Keklily Longfall Ken Lavender Ken March @@ -739,6 +745,7 @@ Marianne McCann Marine Kelley STORM-281 MartinRJ Fayray + STORM-1844 STORM-1845 Matthew Anthony Matthew Dowd @@ -883,6 +890,8 @@ Nicholaz Beresford VWR-2682 VWR-2684 Nick Rhodes +Nicky Dasmijn + VWR-29228 Nicky Perian OPEN-1 STORM-1087 @@ -1108,10 +1117,14 @@ Sudane Erato Synystyr Texan Takeda Terrawyng TankMaster Finesmith + OPEN-140 + OPEN-142 STORM-1100 - STORM-1602 STORM-1258 + STORM-1602 + STORM-1868 VWR-26622 + VWR-29224 Talamasca Tali Rosca Tayra Dagostino @@ -1228,6 +1241,8 @@ Watty Berkson Westley Schridde Westley Streeter Whimsy Winx +Whirly Fizzle + STORM-1895 Whoops Babii VWR-631 VWR-1640 @@ -1256,6 +1271,8 @@ Whoops Babii Winter Ventura Wilton Lundquist VWR-7682 +Wolf Loonie + STORM-1868 WolfPup Lowenhar OPEN-1 OPEN-37 diff --git a/etc/message.xml b/etc/message.xml index 7b133ab205..6d8160abb5 100644 --- a/etc/message.xml +++ b/etc/message.xml @@ -385,14 +385,6 @@ <key>trusted-sender</key> <boolean>true</boolean> </map> - - <key>ParcelMediaURLFilter</key> - <map> - <key>flavor</key> - <string>llsd</string> - <key>trusted-sender</key> - <boolean>false</boolean> - </map> <key>ParcelNavigateMedia</key> <map> diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 1cebb53a07..24c98bfada 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -43,6 +43,7 @@ add_subdirectory(cmake) add_subdirectory(${LIBS_OPEN_PREFIX}llaudio) add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter) add_subdirectory(${LIBS_OPEN_PREFIX}llcommon) +add_subdirectory(${LIBS_OPEN_PREFIX}llcorehttp) add_subdirectory(${LIBS_OPEN_PREFIX}llimage) add_subdirectory(${LIBS_OPEN_PREFIX}llkdu) add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 666c94af86..452fd5f356 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -51,6 +51,7 @@ if (WINDOWS) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0" CACHE STRING "C++ compiler release options" FORCE) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") set(CMAKE_CXX_STANDARD_LIBRARIES "") set(CMAKE_C_STANDARD_LIBRARIES "") @@ -206,6 +207,10 @@ if (DARWIN) # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_C_FLAGS_RELWITHDEBINFO}") + if (XCODE_VERSION GREATER 4.2) + set(ENABLE_SIGNING TRUE) + set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.") + endif (XCODE_VERSION GREATER 4.2) endif (DARWIN) diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 2135f0584c..2af0bc1b30 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -12,12 +12,13 @@ if (STANDALONE) set(BOOST_SIGNALS_LIBRARY boost_signals-mt) set(BOOST_SYSTEM_LIBRARY boost_system-mt) set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) + set(BOOST_THREAD_LIBRARY boost_thread-mt) else (STANDALONE) use_prebuilt_binary(boost) set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) if (WINDOWS) - set(BOOST_VERSION 1_45) + set(BOOST_VERSION 1_48) if(MSVC80) set(BOOST_PROGRAM_OPTIONS_LIBRARY optimized libboost_program_options-vc80-mt-${BOOST_VERSION} @@ -37,22 +38,55 @@ else (STANDALONE) else(MSVC80) # MSVC 10.0 config set(BOOST_PROGRAM_OPTIONS_LIBRARY - optimized libboost_program_options-vc100-mt-${BOOST_VERSION} - debug libboost_program_options-vc100-mt-gd-${BOOST_VERSION}) + optimized libboost_program_options-mt + debug libboost_program_options-mt-gd) set(BOOST_REGEX_LIBRARY - optimized libboost_regex-vc100-mt-${BOOST_VERSION} - debug libboost_regex-vc100-mt-gd-${BOOST_VERSION}) + optimized libboost_regex-mt + debug libboost_regex-mt-gd) set(BOOST_SYSTEM_LIBRARY - optimized libboost_system-vc100-mt-${BOOST_VERSION} - debug libboost_system-vc100-mt-gd-${BOOST_VERSION}) + optimized libboost_system-mt + debug libboost_system-mt-gd) set(BOOST_FILESYSTEM_LIBRARY - optimized libboost_filesystem-vc100-mt-${BOOST_VERSION} - debug libboost_filesystem-vc100-mt-gd-${BOOST_VERSION}) + optimized libboost_filesystem-mt + debug libboost_filesystem-mt-gd) + set(BOOST_THREAD_LIBRARY + optimized libboost_thread-mt + debug libboost_thread-mt-gd) endif (MSVC80) - elseif (DARWIN OR LINUX) - set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options) - set(BOOST_REGEX_LIBRARY boost_regex) - set(BOOST_SYSTEM_LIBRARY boost_system) - set(BOOST_FILESYSTEM_LIBRARY boost_filesystem) + elseif (LINUX) + set(BOOST_PROGRAM_OPTIONS_LIBRARY + optimized boost_program_options-mt + debug boost_program_options-mt-d) + set(BOOST_REGEX_LIBRARY + optimized boost_regex-mt + debug boost_regex-mt-d) + set(BOOST_SYSTEM_LIBRARY + optimized boost_system-mt + debug boost_system-mt-d) + set(BOOST_FILESYSTEM_LIBRARY + optimized boost_filesystem-mt + debug boost_filesystem-mt-d) + set(BOOST_THREAD_LIBRARY + optimized boost_thread-mt + debug boost_thread-mt-d) + elseif (DARWIN) + set(BOOST_PROGRAM_OPTIONS_LIBRARY + optimized boost_program_options-mt + debug boost_program_options-mt-d) + set(BOOST_PROGRAM_OPTIONS_LIBRARY + optimized boost_program_options-mt + debug boost_program_options-mt-d) + set(BOOST_REGEX_LIBRARY + optimized boost_regex-mt + debug boost_regex-mt-d) + set(BOOST_SYSTEM_LIBRARY + optimized boost_system-mt + debug boost_system-mt-d) + set(BOOST_FILESYSTEM_LIBRARY + optimized boost_filesystem-mt + debug boost_filesystem-mt-d) + set(BOOST_THREAD_LIBRARY + optimized boost_thread-mt + debug boost_thread-mt-d) endif (WINDOWS) endif (STANDALONE) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 9f05c4cff2..a5483ba678 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -254,6 +254,12 @@ elseif(LINUX) libapr-1.so.0 libaprutil-1.so.0 libatk-1.0.so + libboost_program_options-mt.so.1.48.0 + libboost_regex-mt.so.1.48.0 + libboost_thread-mt.so.1.48.0 + libboost_filesystem-mt.so.1.48.0 + libboost_signals-mt.so.1.48.0 + libboost_system-mt.so.1.48.0 libbreakpad_client.so.0 libcollada14dom.so libcrypto.so.1.0.0 diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 543075db5b..543075db5b 100755..100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index d4694ad37a..8f7bb296ce 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -24,7 +24,7 @@ endif (LINUX) add_definitions(${TCMALLOC_FLAG}) -set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a shared library.") +set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") if(LLCOMMON_LINK_SHARED) add_definitions(-DLL_COMMON_LINK_SHARED=1) endif(LLCOMMON_LINK_SHARED) diff --git a/indra/cmake/LLCoreHttp.cmake b/indra/cmake/LLCoreHttp.cmake new file mode 100644 index 0000000000..61e4b23d98 --- /dev/null +++ b/indra/cmake/LLCoreHttp.cmake @@ -0,0 +1,16 @@ +# -*- cmake -*- + +include(CARes) +include(CURL) +include(OpenSSL) +include(Boost) + +set(LLCOREHTTP_INCLUDE_DIRS + ${LIBS_OPEN_DIR}/llcorehttp + ${CARES_INCLUDE_DIRS} + ${CURL_INCLUDE_DIRS} + ${OPENSSL_INCLUDE_DIRS} + ${BOOST_INCLUDE_DIRS} + ) + +set(LLCOREHTTP_LIBRARIES llcorehttp) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index f15a2c2649..ab39cbb6be 100644 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -15,10 +15,10 @@ if (WINDOWS) optimized llprimitive debug libcollada14dom22-d optimized libcollada14dom22 - debug libboost_filesystem-vc100-mt-gd-1_45 - optimized libboost_filesystem-vc100-mt-1_45 - debug libboost_system-vc100-mt-gd-1_45 - optimized libboost_system-vc100-mt-1_45 + debug libboost_filesystem-mt-gd + optimized libboost_filesystem-mt + debug libboost_system-mt-gd + optimized libboost_system-mt ) else (WINDOWS) set(LLPRIMITIVE_LIBRARIES diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 56ced20abf..4b459f1a48 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -99,10 +99,20 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(DARWIN 1) + execute_process( + COMMAND sh -c "xcodebuild -version | grep Xcode | cut -d ' ' -f2 | cut -d'.' -f1-2" + OUTPUT_VARIABLE XCODE_VERSION ) + # To support a different SDK update these Xcode settings: - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5) + if (XCODE_VERSION GREATER 4.2) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) + else (XCODE_VERSION GREATER 4.2) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5) + endif (XCODE_VERSION GREATER 4.2) + set(CMAKE_OSX_SYSROOT macosx10.6) set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") + set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym) # NOTE: To attempt an i386/PPC Universal build, add this on the configure line: @@ -134,6 +144,11 @@ set(VIEWER ON CACHE BOOL "Build Second Life viewer.") set(VIEWER_CHANNEL "LindenDeveloper" CACHE STRING "Viewer Channel Name") set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing") +if (XCODE_VERSION GREATER 4.2) + set(ENABLE_SIGNING OFF CACHE BOOL "Enable signing the viewer") + set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.") +endif (XCODE_VERSION GREATER 4.2) + set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside") set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.") set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.") diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 36c5b67826..034c816742 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -240,7 +240,7 @@ void store_input_file(std::list<std::string> &input_filenames, const std::string LLDirIterator iter(dir, name); while (iter.next(next_name)) { - std::string file_name = dir + gDirUtilp->getDirDelimiter() + next_name; + std::string file_name = gDirUtilp->add(dir, next_name); input_filenames.push_back(file_name); } } diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp index 217e26c3ca..38aa1bbeb2 100644 --- a/indra/integration_tests/llui_libtest/llui_libtest.cpp +++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp @@ -107,12 +107,6 @@ public: }; TestImageProvider gTestImageProvider; -static std::string get_xui_dir() -{ - std::string delim = gDirUtilp->getDirDelimiter(); - return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim; -} - void init_llui() { // Font lookup needs directory support @@ -122,13 +116,12 @@ void init_llui() const char* newview_path = "../../../newview"; #endif gDirUtilp->initAppDirs("SecondLife", newview_path); - gDirUtilp->setSkinFolder("default"); + gDirUtilp->setSkinFolder("default", "en"); // colors are no longer stored in a LLControlGroup file LLUIColorTable::instance().loadFromSettings(); - std::string config_filename = gDirUtilp->getExpandedFilename( - LL_PATH_APP_SETTINGS, "settings.xml"); + std::string config_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings.xml"); gSavedSettings.loadFromFile(config_filename); // See LLAppViewer::init() @@ -143,9 +136,7 @@ void init_llui() const bool no_register_widgets = false; LLWidgetReg::initClass( no_register_widgets ); - - // Unclear if this is needed - LLUI::setupPaths(); + // Otherwise we get translation warnings when setting up floaters // (tooltips for buttons) std::set<std::string> default_args; @@ -157,7 +148,6 @@ void init_llui() // otherwise it crashes. LLFontGL::initClass(96.f, 1.f, 1.f, gDirUtilp->getAppRODataDir(), - LLUI::getXUIPaths(), false ); // don't create gl textures LLFloaterView::Params fvparams; @@ -169,6 +159,14 @@ void init_llui() gFloaterView = LLUICtrlFactory::create<LLFloaterView> (fvparams); } +/*==========================================================================*| +static std::string get_xui_dir() +{ + std::string delim = gDirUtilp->getDirDelimiter(); + return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim; +} + +// buildFromFile() no longer supports generate-output-LLXMLNode void export_test_floaters() { // Convert all test floaters to new XML format @@ -191,7 +189,7 @@ void export_test_floaters() floater->buildFromFile( filename, // FALSE, // don't open floater output_node); - std::string out_filename = xui_dir + filename; + std::string out_filename = gDirUtilp->add(xui_dir, filename); std::string::size_type extension_pos = out_filename.rfind(".xml"); out_filename.resize(extension_pos); out_filename += "_new.xml"; @@ -203,6 +201,7 @@ void export_test_floaters() fclose(floater_file); } } +|*==========================================================================*/ int main(int argc, char** argv) { @@ -211,7 +210,7 @@ int main(int argc, char** argv) init_llui(); - export_test_floaters(); +// export_test_floaters(); return 0; } diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index a4fb77357c..97cc31bba0 100644 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -167,7 +167,12 @@ ARGUMENTS=[ dict(name='version', description="""This specifies the version of Second Life that is being packaged up.""", - default=get_default_version) + default=get_default_version), + dict(name='signature', + description="""This specifies an identity to sign the viewer with, if any. + If no value is supplied, the default signature will be used, if any. Currently + only used on Mac OS X.""", + default=None) ] def usage(srctree=""): @@ -621,6 +626,23 @@ class LLManifest(object): d = src_re.sub(d_template, s.replace('\\', '/')) yield os.path.normpath(s), os.path.normpath(d) + def path2basename(self, path, file): + """ + It is a common idiom to write: + self.path(os.path.join(somedir, somefile), somefile) + + So instead you can write: + self.path2basename(somedir, somefile) + + Note that this is NOT the same as: + self.path(os.path.join(somedir, somefile)) + + which is the same as: + temppath = os.path.join(somedir, somefile) + self.path(temppath, temppath) + """ + return self.path(os.path.join(path, file), file) + def path(self, src, dst=None): sys.stdout.write("Processing %s => %s ... " % (src, dst)) sys.stdout.flush() @@ -666,6 +688,10 @@ class LLManifest(object): print "%d files" % count + # Let caller check whether we processed as many files as expected. In + # particular, let caller notice 0. + return count + def do(self, *actions): self.actions = actions self.construct() diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp index 277f0a5367..991dfd9dce 100644 --- a/indra/linux_updater/linux_updater.cpp +++ b/indra/linux_updater/linux_updater.cpp @@ -251,7 +251,7 @@ std::string next_image_filename(std::string& image_path, LLDirIterator& iter) { std::string image_filename; iter.next(image_filename); - return image_path + "/" + image_filename; + return gDirUtilp->add(image_path, image_filename); } void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data) diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 72c0091d17..ef560cd7fc 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -1792,5 +1792,3 @@ bool LLAudioData::load() mBufferp->mAudioDatap = this; return true; } - - diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index 66b3c2bd25..0d0b85ba60 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -214,8 +214,10 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) target = target * target_dist; if (!target.isFinite()) { - llerrs << "Non finite target in editing motion with target distance of " << target_dist << + // Don't error out here, set a fail-safe target vector + llwarns << "Non finite target in editing motion with target distance of " << target_dist << " and focus point " << focus_pt << llendl; + target.setVec(1.f, 1.f, 1.f); } mTarget.setPosition( target + mParentJoint.getPosition()); diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp index 63937d8255..696dba0d95 100644 --- a/indra/llcharacter/llhandmotion.cpp +++ b/indra/llcharacter/llhandmotion.cpp @@ -132,18 +132,68 @@ BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask) { if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose) { - mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); + // Only set param weight for poses other than + // default (HAND_POSE_SPREAD); HAND_POSE_SPREAD + // is not an animatable morph! + if (mNewPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); + } + + // Reset morph weight for current pose back to its + // full extend or it might be stuck somewhere in the middle if a + // pose is requested and the old pose is requested again shortly + // after while still blending to the other pose! + if (mCurrentPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); + } + + // Update visual params now if we won't blend + if (mCurrentPose == HAND_POSE_RELAXED) + { + mCharacter->updateVisualParams(); + } } mNewPose = HAND_POSE_RELAXED; } else { - // this is a new morph we didn't know about before - if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose && mNewPose != HAND_POSE_SPREAD) + // Sometimes we seem to get garbage here, with poses that are out of bounds. + // So check for a valid pose first. + if (*requestedHandPose >= 0 && *requestedHandPose < NUM_HAND_POSES) + { + // This is a new morph we didn't know about before: + // Reset morph weight for both current and new pose + // back their starting values while still blending. + if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose) + { + if (mNewPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); + } + + // Reset morph weight for current pose back to its full extend + // or it might be stuck somewhere in the middle if a pose is + // requested and the old pose is requested again shortly after + // while still blending to the other pose! + if (mCurrentPose != HAND_POSE_SPREAD) + { + mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f); + } + + // Update visual params now if we won't blend + if (mCurrentPose == *requestedHandPose) + { + mCharacter->updateVisualParams(); + } + } + mNewPose = *requestedHandPose; + } + else { - mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f); + llwarns << "Requested hand pose out of range. Ignoring requested pose." << llendl; } - mNewPose = *requestedHandPose; } mCharacter->removeAnimationData("Hand Pose"); diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index dd7b8c6eb8..36a8319189 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -174,6 +174,7 @@ set(llcommon_HEADER_FILES llfoldertype.h llformat.h llframetimer.h + llhandle.h llhash.h llheartbeat.h llhttpstatuscodes.h diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 0745696ef3..0da83720bd 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -62,6 +62,7 @@ enum LAND_STAT_FLAGS STAT_FILTER_BY_PARCEL = 0x00000001, STAT_FILTER_BY_OWNER = 0x00000002, STAT_FILTER_BY_OBJECT = 0x00000004, + STAT_FILTER_BY_PARCEL_NAME = 0x00000008, STAT_REQUEST_LAST_ENTRY = 0x80000000, }; diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index 5cfcdab41c..f0a5603d06 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -59,4 +59,8 @@ #include "llerror.h" #include "llfile.h" +// Boost 1.45 had version 2 as the default for the filesystem library, +// 1.48 has version 3 as the default. Keep compatibility for now. +#define BOOST_FILESYSTEM_VERSION 2 + #endif diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index af33ce666f..034546c3f3 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -168,7 +168,7 @@ public: void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); } void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); } Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++ - Type operator --(int) { return apr_atomic_dec32(&mData); } // Type-- + Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise) private: apr_uint32_t mData; diff --git a/indra/llui/llhandle.h b/indra/llcommon/llhandle.h index 37c657dd92..6af5e198d6 100644 --- a/indra/llui/llhandle.h +++ b/indra/llcommon/llhandle.h @@ -31,6 +31,10 @@ #include <boost/type_traits/is_convertible.hpp> #include <boost/utility/enable_if.hpp> +/** + * Helper object for LLHandle. Don't instantiate these directly, used + * exclusively by LLHandle. + */ class LLTombStone : public LLRefCount { public: @@ -42,15 +46,37 @@ private: mutable void* mTarget; }; -// LLHandles are used to refer to objects whose lifetime you do not control or influence. -// Calling get() on a handle will return a pointer to the referenced object or NULL, -// if the object no longer exists. Note that during the lifetime of the returned pointer, -// you are assuming that the object will not be deleted by any action you perform, -// or any other thread, as normal when using pointers, so avoid using that pointer outside of -// the local code block. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 - +/** + * LLHandles are used to refer to objects whose lifetime you do not control or influence. + * Calling get() on a handle will return a pointer to the referenced object or NULL, + * if the object no longer exists. Note that during the lifetime of the returned pointer, + * you are assuming that the object will not be deleted by any action you perform, + * or any other thread, as normal when using pointers, so avoid using that pointer outside of + * the local code block. + * + * https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + * + * The implementation is like some "weak pointer" implementations. When we + * can't control the lifespan of the referenced object of interest, we can + * still instantiate a proxy object whose lifespan we DO control, and store in + * the proxy object a dumb pointer to the actual target. Then we just have to + * ensure that on destruction of the target object, the proxy's dumb pointer + * is set NULL. + * + * LLTombStone is our proxy object. LLHandle contains an LLPointer to the + * LLTombStone, so every copy of an LLHandle increments the LLTombStone's ref + * count as usual. + * + * One copy of the LLHandle, specifically the LLRootHandle, must be stored in + * the referenced object. Destroying the LLRootHandle is what NULLs the + * proxy's target pointer. + * + * Minor optimization: we want LLHandle's mTombStone to always be a valid + * LLPointer, saving some conditionals in dereferencing. That's the + * getDefaultTombStone() mechanism. The default LLTombStone object's target + * pointer is always NULL, so it's semantically identical to allowing + * mTombStone to be invalid. + */ template <typename T> class LLHandle { @@ -108,6 +134,14 @@ private: } }; +/** + * LLRootHandle isa LLHandle which must be stored in the referenced object. + * You can either store it directly and explicitly bind(this), or derive from + * LLHandleProvider (q.v.) which automates that for you. The essential point + * is that destroying the LLRootHandle (as a consequence of destroying the + * referenced object) calls unbind(), setting the LLTombStone's target pointer + * NULL. + */ template <typename T> class LLRootHandle : public LLHandle<T> { @@ -144,8 +178,10 @@ private: LLRootHandle(const LLRootHandle& other) {}; }; -// Use this as a mixin for simple classes that need handles and when you don't -// want handles at multiple points of the inheritance hierarchy +/** + * Use this as a mixin for simple classes that need handles and when you don't + * want handles at multiple points of the inheritance hierarchy + */ template <typename T> class LLHandleProvider { diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 99983a19cb..9a6d1eff5c 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -35,7 +35,7 @@ #include <boost/shared_ptr.hpp> #include "llerror.h" -#include "lltypeinfolookup.h" +#include "llstl.h" namespace LLInitParam { @@ -212,14 +212,6 @@ namespace LLInitParam public: - struct CompareTypeID - { - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } - }; - typedef std::vector<std::pair<std::string, bool> > name_stack_t; typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t; typedef std::vector<std::string> possible_values_t; @@ -228,9 +220,9 @@ namespace LLInitParam typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&); typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t; - typedef LLTypeInfoLookup<parser_read_func_t> parser_read_func_map_t; - typedef LLTypeInfoLookup<parser_write_func_t> parser_write_func_map_t; - typedef LLTypeInfoLookup<parser_inspect_func_t> parser_inspect_func_map_t; + typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t; + typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t; + typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t; Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) : mParseSilently(false), diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 36d7f7a44c..853c427a13 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -31,30 +31,16 @@ #include <boost/type_traits.hpp> #include "llsingleton.h" -#include "lltypeinfolookup.h" +#include "llstl.h" template <typename T> -class LLRegistryDefaultComparator +struct LLRegistryDefaultComparator { - bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; } -}; - -template <typename KEY, typename VALUE> -struct LLRegistryMapSelector -{ - typedef std::map<KEY, VALUE> type; -}; - -template <typename VALUE> -struct LLRegistryMapSelector<std::type_info*, VALUE> -{ - typedef LLTypeInfoLookup<VALUE> type; -}; - -template <typename VALUE> -struct LLRegistryMapSelector<const std::type_info*, VALUE> -{ - typedef LLTypeInfoLookup<VALUE> type; + bool operator()(const T& lhs, const T& rhs) const + { + using std::less; + return less<T>()(lhs, rhs); + } }; template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> > @@ -72,7 +58,7 @@ public: { friend class LLRegistry<KEY, VALUE, COMPARATOR>; public: - typedef typename LLRegistryMapSelector<KEY, VALUE>::type registry_map_t; + typedef std::map<KEY, VALUE, COMPARATOR> registry_map_t; bool add(ref_const_key_t key, ref_const_value_t value) { diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 7f4f670ed0..6b549e4b6f 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -1451,9 +1451,12 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option } case LLSD::TypeUUID: + { ostr.put('u'); - ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES); + LLSD::UUID value = data.asUUID(); + ostr.write((const char*)(&value.mData), UUID_BYTES); break; + } case LLSD::TypeString: ostr.put('s'); diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 8ad12c9a03..d3941e1bc9 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -33,6 +33,7 @@ #include <vector> #include <set> #include <deque> +#include <typeinfo> // Use to compare the first element only of a pair // e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t; @@ -470,4 +471,54 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); } +/** + * Compare std::type_info* pointers a la std::less. We break this out as a + * separate function for use in two different std::less specializations. + */ +inline +bool before(const std::type_info* lhs, const std::type_info* rhs) +{ +#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) + // If we're building on Linux with gcc, and it's either gcc 3.x or + // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on + // Mac too, and some people build with gcc on Windows (cygwin or mingw). + // On Linux, different load modules may produce different type_info* + // pointers for the same type. Have to compare name strings to get good + // results. + return strcmp(lhs->name(), rhs->name()) < 0; +#else // not Linux, or gcc 4.4+ + // Just use before(), as we normally would + return lhs->before(*rhs); +#endif +} + +/** + * Specialize std::less<std::type_info*> to use std::type_info::before(). + * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* + * because, on Linux, you might get different std::type_info* pointers for the + * same type (from different load modules)! + */ +namespace std +{ + template <> + struct less<const std::type_info*>: + public std::binary_function<const std::type_info*, const std::type_info*, bool> + { + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; + + template <> + struct less<std::type_info*>: + public std::binary_function<std::type_info*, std::type_info*, bool> + { + bool operator()(std::type_info* lhs, std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; +} // std + #endif // LL_LLSTL_H diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index fa0eb9f72c..0c32679744 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -47,7 +47,8 @@ std::string ll_safe_string(const char* in) std::string ll_safe_string(const char* in, S32 maxlen) { - if(in) return std::string(in, maxlen); + if(in && maxlen > 0 ) return std::string(in, maxlen); + return std::string(); } diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index c2fbb544a8..1d56a52c32 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -71,6 +71,13 @@ LL_COMMON_API void assert_main_thread() } } +void LLThread::registerThreadID() +{ +#if !LL_DARWIN + sThreadID = ++sIDIter; +#endif +} + // // Handed to the APR thread creation function // diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 115bf47553..5c8bbca2ca 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -88,6 +88,11 @@ public: U32 getID() const { return mID; } + // Called by threads *not* created via LLThread to register some + // internal state used by LLMutex. You must call this once early + // in the running thread to prevent collisions with the main thread. + static void registerThreadID(); + private: BOOL mPaused; diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h index 7510cc12ed..0b6862444e 100644 --- a/indra/llcommon/lltypeinfolookup.h +++ b/indra/llcommon/lltypeinfolookup.h @@ -12,10 +12,50 @@ #if ! defined(LL_LLTYPEINFOLOOKUP_H) #define LL_LLTYPEINFOLOOKUP_H -#include "llsortedvector.h" +#include <boost/unordered_map.hpp> +#include <boost/functional/hash.hpp> +#include <boost/optional.hpp> +#include <functional> // std::binary_function #include <typeinfo> /** + * The following helper classes are based on the Boost.Unordered documentation: + * http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html + */ + +/** + * Compute hash for a string passed as const char* + */ +struct const_char_star_hash: public std::unary_function<const char*, std::size_t> +{ + std::size_t operator()(const char* str) const + { + std::size_t seed = 0; + for ( ; *str; ++str) + { + boost::hash_combine(seed, *str); + } + return seed; + } +}; + +/** + * Compute equality for strings passed as const char* + * + * I (nat) suspect that this is where the default behavior breaks for the + * const char* values returned from std::type_info::name(). If you compare the + * two const char* pointer values, as a naive, unspecialized implementation + * will surely do, they'll compare unequal. + */ +struct const_char_star_equal: public std::binary_function<const char*, const char*, bool> +{ + bool operator()(const char* lhs, const char* rhs) const + { + return strcmp(lhs, rhs) == 0; + } +}; + +/** * LLTypeInfoLookup is specifically designed for use cases for which you might * consider std::map<std::type_info*, VALUE>. We have several such data * structures in the viewer. The trouble with them is that at least on Linux, @@ -23,88 +63,55 @@ * different load modules will produce different std::type_info*. * LLTypeInfoLookup contains a workaround to address this issue. * - * Specifically, when we don't find the passed std::type_info*, - * LLTypeInfoLookup performs a linear search over registered entries to - * compare name() strings. Presuming that this succeeds, we cache the new - * (previously unrecognized) std::type_info* to speed future lookups. - * - * This worst-case fallback search (linear search with string comparison) - * should only happen the first time we look up a given type from a particular - * load module other than the one from which we initially registered types. - * (However, a lookup which wouldn't succeed anyway will always have - * worst-case performance.) This class is probably best used with less than a - * few dozen different types. + * The API deliberately diverges from std::map in several respects: + * * It avoids iterators, not only begin()/end() but also as return values + * from insert() and find(). This bypasses transform_iterator overhead. + * * Since we literally use compile-time types as keys, the essential insert() + * and find() methods accept the key type as a @em template parameter, + * accepting and returning value_type as a normal runtime value. This is to + * permit future optimization (e.g. compile-time type hashing) without + * changing the API. */ template <typename VALUE> class LLTypeInfoLookup { + // Use this for our underlying implementation: lookup by + // std::type_info::name() string. This is one of the rare cases in which I + // dare use const char* directly, rather than std::string, because I'm + // sure that every value returned by std::type_info::name() is static. + // HOWEVER, specify our own hash + equality functors: naively comparing + // distinct const char* values won't work. + typedef boost::unordered_map<const char*, VALUE, + const_char_star_hash, const_char_star_equal> impl_map_type; + public: - typedef LLTypeInfoLookup<VALUE> self; - typedef LLSortedVector<const std::type_info*, VALUE> vector_type; - typedef typename vector_type::key_type key_type; - typedef typename vector_type::mapped_type mapped_type; - typedef typename vector_type::value_type value_type; - typedef typename vector_type::iterator iterator; - typedef typename vector_type::const_iterator const_iterator; + typedef VALUE value_type; LLTypeInfoLookup() {} - iterator begin() { return mVector.begin(); } - iterator end() { return mVector.end(); } - const_iterator begin() const { return mVector.begin(); } - const_iterator end() const { return mVector.end(); } - bool empty() const { return mVector.empty(); } - std::size_t size() const { return mVector.size(); } - - std::pair<iterator, bool> insert(const std::type_info* key, const VALUE& value) - { - return insert(value_type(key, value)); - } - - std::pair<iterator, bool> insert(const value_type& pair) - { - return mVector.insert(pair); - } + bool empty() const { return mMap.empty(); } + std::size_t size() const { return mMap.size(); } - // const find() forwards to non-const find(): this can alter mVector! - const_iterator find(const std::type_info* key) const + template <typename KEY> + bool insert(const value_type& value) { - return const_cast<self*>(this)->find(key); + // Obtain and store the std::type_info::name() string as the key. + // Return just the bool from std::map::insert()'s return pair. + return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second; } - // non-const find() caches previously-unknown type_info* to speed future - // lookups. - iterator find(const std::type_info* key) + template <typename KEY> + boost::optional<value_type> find() const { - iterator found = mVector.find(key); - if (found != mVector.end()) - { - // If LLSortedVector::find() found, great, we're done. - return found; - } - // Here we didn't find the passed type_info*. On Linux, though, even - // for the same type, typeid(sametype) produces a different type_info* - // when used in different load modules. So the fact that we didn't - // find the type_info* we seek doesn't mean this type isn't - // registered. Scan for matching name() string. - for (typename vector_type::iterator ti(mVector.begin()), tend(mVector.end()); - ti != tend; ++ti) - { - if (std::string(ti->first->name()) == key->name()) - { - // This unrecognized 'key' is for the same type as ti->first. - // To speed future lookups, insert a new entry that lets us - // look up ti->second using this same 'key'. - return insert(key, ti->second).first; - } - } - // We simply have never seen a type with this type_info* from any load - // module. - return mVector.end(); + // Use the std::type_info::name() string as the key. + typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name()); + if (found == mMap.end()) + return boost::optional<value_type>(); + return found->second; } private: - vector_type mVector; + impl_map_type mMap; }; #endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */ diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index b39ea0c6f2..21456a599b 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -37,6 +37,8 @@ // system includes #include <boost/tokenizer.hpp> +#include <boost/algorithm/string/find_iterator.hpp> +#include <boost/algorithm/string/finder.hpp> void encode_character(std::ostream& ostr, std::string::value_type val) { @@ -317,7 +319,7 @@ LLURI LLURI::buildHTTP(const std::string& prefix, const LLSD& path) { LLURI result; - + // TODO: deal with '/' '?' '#' in host_port if (prefix.find("://") != prefix.npos) { @@ -342,15 +344,41 @@ LLURI LLURI::buildHTTP(const std::string& prefix, result.mEscapedPath += "/" + escapePathComponent(it->asString()); } } - else if(path.isString()) + else if (path.isString()) { - result.mEscapedPath += "/" + escapePathComponent(path.asString()); + std::string pathstr(path); + // Trailing slash is significant in HTTP land. If caller specified, + // make a point of preserving. + std::string last_slash; + std::string::size_type len(pathstr.length()); + if (len && pathstr[len-1] == '/') + { + last_slash = "/"; + } + + // Escape every individual path component, recombining with slashes. + for (boost::split_iterator<std::string::const_iterator> + ti(pathstr, boost::first_finder("/")), tend; + ti != tend; ++ti) + { + // Eliminate a leading slash or duplicate slashes anywhere. (Extra + // slashes show up here as empty components.) This test also + // eliminates a trailing slash, hence last_slash above. + if (! ti->empty()) + { + result.mEscapedPath + += "/" + escapePathComponent(std::string(ti->begin(), ti->end())); + } + } + + // Reinstate trailing slash, if any. + result.mEscapedPath += last_slash; } else if(path.isUndefined()) { // do nothing } - else + else { llwarns << "Valid path arguments to buildHTTP are array, string, or undef, you passed type" << path.type() << llendl; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index bcc661a920..91008eb5d6 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@ const S32 LL_VERSION_MAJOR = 3; const S32 LL_VERSION_MINOR = 4; -const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_PATCH = 3; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp index 05289881d0..4c3bc674af 100644 --- a/indra/llcommon/tests/bitpack_test.cpp +++ b/indra/llcommon/tests/bitpack_test.cpp @@ -95,6 +95,7 @@ namespace tut ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]); unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4); + ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize); } // U32 packing diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp index f6d4221256..4c64f15ca7 100644 --- a/indra/llcommon/tests/lluri_test.cpp +++ b/indra/llcommon/tests/lluri_test.cpp @@ -58,12 +58,12 @@ namespace tut ensure_equals("escape/unescape escaped", uri_esc_2, uri_esc_1); } }; - + typedef test_group<URITestData> URITestGroup; typedef URITestGroup::object URITestObject; URITestGroup uriTestGroup("LLURI"); - + template<> template<> void URITestObject::test<1>() { @@ -89,14 +89,14 @@ namespace tut template<> template<> void URITestObject::test<2>() { - // empty string + set_test_name("empty string"); checkParts(LLURI(""), "", "", "", ""); } - + template<> template<> void URITestObject::test<3>() { - // no scheme + set_test_name("no scheme"); checkParts(LLURI("foo"), "", "foo", "", ""); checkParts(LLURI("foo%3A"), "", "foo:", "", ""); } @@ -104,7 +104,7 @@ namespace tut template<> template<> void URITestObject::test<4>() { - // scheme w/o paths + set_test_name("scheme w/o paths"); checkParts(LLURI("mailto:zero@ll.com"), "mailto", "zero@ll.com", "", ""); checkParts(LLURI("silly://abc/def?foo"), @@ -114,16 +114,16 @@ namespace tut template<> template<> void URITestObject::test<5>() { - // authority section + set_test_name("authority section"); checkParts(LLURI("http:///"), "http", "///", "", "/"); - + checkParts(LLURI("http://abc"), "http", "//abc", "abc", ""); - + checkParts(LLURI("http://a%2Fb/cd"), "http", "//a/b/cd", "a/b", "/cd"); - + checkParts(LLURI("http://host?"), "http", "//host?", "host", ""); } @@ -131,13 +131,13 @@ namespace tut template<> template<> void URITestObject::test<6>() { - // path section + set_test_name("path section"); checkParts(LLURI("http://host/a/b/"), "http", "//host/a/b/", "host", "/a/b/"); - + checkParts(LLURI("http://host/a%3Fb/"), "http", "//host/a?b/", "host", "/a?b/"); - + checkParts(LLURI("http://host/a:b/"), "http", "//host/a:b/", "host", "/a:b/"); } @@ -145,16 +145,16 @@ namespace tut template<> template<> void URITestObject::test<7>() { - // query string + set_test_name("query string"); checkParts(LLURI("http://host/?"), "http", "//host/?", "host", "/", ""); - + checkParts(LLURI("http://host/?x"), "http", "//host/?x", "host", "/", "x"); - + checkParts(LLURI("http://host/??"), "http", "//host/??", "host", "/", "?"); - + checkParts(LLURI("http://host/?%3F"), "http", "//host/??", "host", "/", "?"); } @@ -167,19 +167,44 @@ namespace tut path.append("123"); checkParts(LLURI::buildHTTP("host", path), "http", "//host/x/123", "host", "/x/123"); - + LLSD query; query["123"] = "12"; query["abcd"] = "abc"; checkParts(LLURI::buildHTTP("host", path, query), "http", "//host/x/123?123=12&abcd=abc", "host", "/x/123", "123=12&abcd=abc"); + + ensure_equals(LLURI::buildHTTP("host", "").asString(), + "http://host"); + ensure_equals(LLURI::buildHTTP("host", "/").asString(), + "http://host/"); + ensure_equals(LLURI::buildHTTP("host", "//").asString(), + "http://host/"); + ensure_equals(LLURI::buildHTTP("host", "dir name").asString(), + "http://host/dir%20name"); + ensure_equals(LLURI::buildHTTP("host", "dir name/").asString(), + "http://host/dir%20name/"); + ensure_equals(LLURI::buildHTTP("host", "/dir name").asString(), + "http://host/dir%20name"); + ensure_equals(LLURI::buildHTTP("host", "/dir name/").asString(), + "http://host/dir%20name/"); + ensure_equals(LLURI::buildHTTP("host", "dir name/subdir name").asString(), + "http://host/dir%20name/subdir%20name"); + ensure_equals(LLURI::buildHTTP("host", "dir name/subdir name/").asString(), + "http://host/dir%20name/subdir%20name/"); + ensure_equals(LLURI::buildHTTP("host", "/dir name/subdir name").asString(), + "http://host/dir%20name/subdir%20name"); + ensure_equals(LLURI::buildHTTP("host", "/dir name/subdir name/").asString(), + "http://host/dir%20name/subdir%20name/"); + ensure_equals(LLURI::buildHTTP("host", "//dir name//subdir name//").asString(), + "http://host/dir%20name/subdir%20name/"); } template<> template<> void URITestObject::test<9>() { - // test unescaped path components + set_test_name("test unescaped path components"); LLSD path; path.append("x@*//*$&^"); path.append("123"); @@ -190,7 +215,7 @@ namespace tut template<> template<> void URITestObject::test<10>() { - // test unescaped query components + set_test_name("test unescaped query components"); LLSD path; path.append("x"); path.append("123"); @@ -205,7 +230,7 @@ namespace tut template<> template<> void URITestObject::test<11>() { - // test unescaped host components + set_test_name("test unescaped host components"); LLSD path; path.append("x"); path.append("123"); @@ -216,16 +241,16 @@ namespace tut "http", "//hi123*33--}{:portstuffs/x/123?123=12&abcd=abc", "hi123*33--}{:portstuffs", "/x/123", "123=12&abcd=abc"); } - + template<> template<> void URITestObject::test<12>() { - // test funky host_port values that are actually prefixes - + set_test_name("test funky host_port values that are actually prefixes"); + checkParts(LLURI::buildHTTP("http://example.com:8080", LLSD()), "http", "//example.com:8080", "example.com:8080", ""); - + checkParts(LLURI::buildHTTP("http://example.com:8080/", LLSD()), "http", "//example.com:8080/", "example.com:8080", "/"); @@ -242,7 +267,7 @@ namespace tut "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789" "-._~"; - // test escape + set_test_name("test escape"); ensure_equals("escaping", LLURI::escape("abcdefg", "abcdef"), "abcdef%67"); ensure_equals("escaping", LLURI::escape("|/&\\+-_!@", ""), "%7C%2F%26%5C%2B%2D%5F%21%40"); ensure_equals("escaping as query variable", @@ -259,13 +284,12 @@ namespace tut cedilla.push_back( (char)0xA7 ); ensure_equals("escape UTF8", LLURI::escape( cedilla, unreserved), "%C3%A7"); } - + template<> template<> void URITestObject::test<14>() { - // make sure escape and unescape of empty strings return empty - // strings. + set_test_name("make sure escape and unescape of empty strings return empty strings."); std::string uri_esc(LLURI::escape("")); ensure("escape string empty", uri_esc.empty()); std::string uri_raw(LLURI::unescape("")); @@ -275,7 +299,7 @@ namespace tut template<> template<> void URITestObject::test<15>() { - // do some round-trip tests + set_test_name("do some round-trip tests"); escapeRoundTrip("http://secondlife.com"); escapeRoundTrip("http://secondlife.com/url with spaces"); escapeRoundTrip("http://bad[domain]name.com/"); @@ -286,7 +310,7 @@ namespace tut template<> template<> void URITestObject::test<16>() { - // Test the default escaping + set_test_name("Test the default escaping"); // yes -- this mangles the url. This is expected behavior std::string simple("http://secondlife.com"); ensure_equals( @@ -302,7 +326,7 @@ namespace tut template<> template<> void URITestObject::test<17>() { - // do some round-trip tests with very long strings. + set_test_name("do some round-trip tests with very long strings."); escapeRoundTrip("Welcome to Second Life.We hope you'll have a richly rewarding experience, filled with creativity, self expression and fun.The goals of the Community Standards are simple: treat each other with respect and without harassment, adhere to local standards as indicated by simulator ratings, and refrain from any hate activity which slurs a real-world individual or real-world community. Behavioral Guidelines - The Big Six"); escapeRoundTrip( "'asset_data':b(12100){'task_id':ucc706f2d-0b68-68f8-11a4-f1043ff35ca0}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444921\n\ttotal_crc\t323\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.368634403\t0.00781063363\t-0.569040775\n\toldpos\t150.117996\t25.8658009\t8.19664001\n\trotation\t-0.06293071806430816650390625\t-0.6995697021484375\t-0.7002241611480712890625\t0.1277817934751510620117188\n\tchildpos\t-0.00499999989\t-0.0359999985\t0.307999998\n\tchildrot\t-0.515492737293243408203125\t-0.46601200103759765625\t0.529055416584014892578125\t0.4870323240756988525390625\n\tscale" @@ -322,7 +346,7 @@ namespace tut "D STRING RW SV 20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t8747acbc-d391-1e59-69f1-41d06830e6c0\n\torig_item_id\t20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tfrom_task_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tlinked\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n"); } - + template<> template<> void URITestObject::test<18>() { @@ -335,7 +359,7 @@ namespace tut ensure_equals("pathmap", u.pathArray()[1].asString(), "login"); ensure_equals("query", u.query(), "first_name=Testert4&last_name=Tester&web_login_key=test"); ensure_equals("query map element", u.queryMap()["last_name"].asString(), "Tester"); - + u = LLURI("secondlife://Da Boom/128/128/128"); // if secondlife is the scheme, LLURI should parse /128/128/128 as path, with Da Boom as authority ensure_equals("scheme", u.scheme(), "secondlife"); @@ -350,7 +374,7 @@ namespace tut template<> template<> void URITestObject::test<19>() { - // Parse about: schemes + set_test_name("Parse about: schemes"); LLURI u("about:blank?redirect-http-hack=secondlife%3A%2F%2F%2Fapp%2Flogin%3Ffirst_name%3DCallum%26last_name%3DLinden%26location%3Dspecify%26grid%3Dvaak%26region%3D%2FMorris%2F128%2F128%26web_login_key%3Defaa4795-c2aa-4c58-8966-763c27931e78"); ensure_equals("scheme", u.scheme(), "about"); ensure_equals("authority", u.authority(), ""); diff --git a/indra/llcommon/tests/reflection_test.cpp b/indra/llcommon/tests/reflection_test.cpp index 59491cd1fe..8980ebb1f1 100644 --- a/indra/llcommon/tests/reflection_test.cpp +++ b/indra/llcommon/tests/reflection_test.cpp @@ -207,7 +207,7 @@ namespace tut const LLReflective* reflective = property->get(aggregated_data); // Wrong reflective type, should throw exception. // useless op to get rid of compiler warning. - reflective = NULL; + reflective = reflective; } catch(...) { diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt new file mode 100644 index 0000000000..8632a2b722 --- /dev/null +++ b/indra/llcorehttp/CMakeLists.txt @@ -0,0 +1,184 @@ +# -*- cmake -*- + +project(llcorehttp) + +include(00-Common) +include(GoogleMock) +include(CURL) +include(CARes) +include(OpenSSL) +include(ZLIB) +include(LLCoreHttp) +include(LLAddBuildTest) +include(LLMessage) +include(LLCommon) +include(Tut) + +include_directories (${CMAKE_CURRENT_SOURCE_DIR}) + +include_directories( + ${LLMESSAGE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLCOREHTTP_INCLUDE_DIRS} + ) + +set(llcorehttp_SOURCE_FILES + bufferarray.cpp + bufferstream.cpp + httpcommon.cpp + httpheaders.cpp + httpoptions.cpp + httprequest.cpp + httpresponse.cpp + _httplibcurl.cpp + _httpopcancel.cpp + _httpoperation.cpp + _httpoprequest.cpp + _httpopsetget.cpp + _httpopsetpriority.cpp + _httppolicy.cpp + _httppolicyclass.cpp + _httppolicyglobal.cpp + _httpreplyqueue.cpp + _httprequestqueue.cpp + _httpservice.cpp + _refcounted.cpp + ) + +set(llcorehttp_HEADER_FILES + CMakeLists.txt + + bufferarray.h + bufferstream.h + httpcommon.h + httphandler.h + httpheaders.h + httpoptions.h + httprequest.h + httpresponse.h + _httpinternal.h + _httplibcurl.h + _httpopcancel.h + _httpoperation.h + _httpoprequest.h + _httpopsetget.h + _httpopsetpriority.h + _httppolicy.h + _httppolicyclass.h + _httppolicyglobal.h + _httpreadyqueue.h + _httpreplyqueue.h + _httprequestqueue.h + _httpservice.h + _mutex.h + _refcounted.h + _thread.h + ) + +set_source_files_properties(${llcorehttp_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) +if (DARWIN OR LINUX) + # Boost headers define unused members in condition_variable so... + set_source_files_properties(${llcorehttp_SOURCE_FILES} + PROPERTIES COMPILE_FLAGS -Wno-unused-variable) +endif (DARWIN OR LINUX) + +list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES}) + +add_library (llcorehttp ${llcorehttp_SOURCE_FILES}) +target_link_libraries( + llcorehttp + ${CURL_LIBRARIES} + ${CARES_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CRYPTO_LIBRARIES} + ${BOOST_THREAD_LIBRARY} + ) + +# tests +if (LL_TESTS) + SET(llcorehttp_TEST_SOURCE_FILES + tests/test_allocator.cpp + ) + + set(llcorehttp_TEST_HEADER_FILS + tests/test_httpstatus.hpp + tests/test_refcounted.hpp + tests/test_httpoperation.hpp + tests/test_httprequest.hpp + tests/test_httprequestqueue.hpp + tests/test_httpheaders.hpp + tests/test_bufferarray.hpp + tests/test_bufferstream.hpp + ) + + set_source_files_properties(${llcorehttp_TEST_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + + list(APPEND llcorehttp_TEST_SOURCE_FILES ${llcorehttp_TEST_HEADER_FILES}) + + # LL_ADD_PROJECT_UNIT_TESTS(llcorehttp "${llcorehttp_TEST_SOURCE_FILES}") + + # set(TEST_DEBUG on) + set(test_libs + ${LLCOREHTTP_LIBRARIES} + ${WINDOWS_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${GOOGLEMOCK_LIBRARIES} + ${CURL_LIBRARIES} + ${CARES_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CRYPTO_LIBRARIES} + ${BOOST_THREAD_LIBRARY} + ) + + LL_ADD_INTEGRATION_TEST(llcorehttp + "${llcorehttp_TEST_SOURCE_FILES}" + "${test_libs}" + ${PYTHON_EXECUTABLE} + "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py" + ) + + # + # Example Programs + # + SET(llcorehttp_EXAMPLE_SOURCE_FILES + examples/http_texture_load.cpp + ) + + set(example_libs + ${LLCOREHTTP_LIBRARIES} + ${WINDOWS_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${GOOGLEMOCK_LIBRARIES} + ${CURL_LIBRARIES} + ${CARES_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CRYPTO_LIBRARIES} + ${BOOST_THREAD_LIBRARY} + ) + + add_executable(http_texture_load + ${llcorehttp_EXAMPLE_SOURCE_FILES} + ) + set_target_properties(http_texture_load + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}" + ) + + if (WINDOWS) + # The following come from LLAddBuildTest.cmake's INTEGRATION_TEST_xxxx target. + set_target_properties(http_texture_load + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" + LINK_FLAGS_RELEASE "" + ) + endif (WINDOWS) + + target_link_libraries(http_texture_load ${example_libs}) + +endif (LL_TESTS) + diff --git a/indra/llcorehttp/_httpinternal.h b/indra/llcorehttp/_httpinternal.h new file mode 100644 index 0000000000..14f744a9f1 --- /dev/null +++ b/indra/llcorehttp/_httpinternal.h @@ -0,0 +1,154 @@ +/** + * @file _httpinternal.h + * @brief Implementation constants and magic numbers + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_INTERNAL_H_ +#define _LLCORE_HTTP_INTERNAL_H_ + + +// If you find this included in a public interface header, +// something wrong is probably happening. + + +// -------------------------------------------------------------------- +// General library to-do list +// +// - Implement policy classes. Structure is mostly there just didn't +// need it for the first consumer. +// - Consider Removing 'priority' from the request interface. Its use +// in an always active class can lead to starvation of low-priority +// requests. Requires coodination of priority values across all +// components that share a class. Changing priority across threads +// is slightly expensive (relative to gain) and hasn't been completely +// implemented. And the major user of priority, texture fetches, +// may not really need it. +// - Set/get for global policy and policy classes is clumsy. Rework +// it heading in a direction that allows for more dynamic behavior. +// - Move HttpOpRequest::prepareRequest() to HttpLibcurl for the +// pedantic. +// - Update downloader and other long-duration services are going to +// need a progress notification. Initial idea is to introduce a +// 'repeating request' which can piggyback on another request and +// persist until canceled or carrier completes. Current queue +// structures allow an HttpOperation object to be enqueued +// repeatedly, so... +// - Investigate making c-ares' re-implementation of a resolver library +// more resilient or more intelligent on Mac. Part of the DNS failure +// lies in here. The mechanism also looks a little less dynamic +// than needed in an environments where networking is changing. +// - Global optimizations: 'borrowing' connections from other classes, +// HTTP pipelining. +// - Dynamic/control system stuff: detect problems and self-adjust. +// This won't help in the face of the router problems we've looked +// at, however. Detect starvation due to UDP activity and provide +// feedback to it. +// +// Integration to-do list +// - LLTextureFetch still needs a major refactor. The use of +// LLQueuedThread makes it hard to inspect workers and do the +// resource waiting we're now doing. Rebuild along simpler lines +// some of which are suggested in new commentary at the top of +// the main source file. +// - Expand areas of usage eventually leading to the removal of LLCurl. +// Rough order of expansion: +// . Mesh fetch +// . Avatar names +// . Group membership lists +// . Caps access in general +// . 'The rest' +// - Adapt texture cache, image decode and other image consumers to +// the BufferArray model to reduce data copying. Alternatively, +// adapt this library to something else. +// +// -------------------------------------------------------------------- + + +// If '1', internal ready queues will not order ready +// requests by priority, instead it's first-come-first-served. +// Reprioritization requests have the side-effect of then +// putting the modified request at the back of the ready queue. + +#define LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY 1 + + +namespace LLCore +{ + +// Maxium number of policy classes that can be defined. +// *TODO: Currently limited to the default class, extend. +const int HTTP_POLICY_CLASS_LIMIT = 1; + +// Debug/informational tracing. Used both +// as a global option and in per-request traces. +const int HTTP_TRACE_OFF = 0; +const int HTTP_TRACE_LOW = 1; +const int HTTP_TRACE_CURL_HEADERS = 2; +const int HTTP_TRACE_CURL_BODIES = 3; + +const int HTTP_TRACE_MIN = HTTP_TRACE_OFF; +const int HTTP_TRACE_MAX = HTTP_TRACE_CURL_BODIES; + +// Request retry limits +// +// At a minimum, retries need to extend past any throttling +// window we're expecting from central services. In the case +// of Linden services running through the caps routers, there's +// a five-second or so window for throttling with some spillover. +// We want to span a few windows to allow transport to slow +// after onset of the throttles and then recover without a final +// failure. Other systems may need other constants. +const int HTTP_RETRY_COUNT_DEFAULT = 8; +const int HTTP_RETRY_COUNT_MIN = 0; +const int HTTP_RETRY_COUNT_MAX = 100; + +const int HTTP_REDIRECTS_DEFAULT = 10; + +// Timeout value used for both connect and protocol exchange. +// Retries and time-on-queue are not included and aren't +// accounted for. +const long HTTP_REQUEST_TIMEOUT_DEFAULT = 30L; +const long HTTP_REQUEST_TIMEOUT_MIN = 0L; +const long HTTP_REQUEST_TIMEOUT_MAX = 3600L; + +// Limits on connection counts +const int HTTP_CONNECTION_LIMIT_DEFAULT = 8; +const int HTTP_CONNECTION_LIMIT_MIN = 1; +const int HTTP_CONNECTION_LIMIT_MAX = 256; + +// Tuning parameters + +// Time worker thread sleeps after a pass through the +// request, ready and active queues. +const int HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS = 2; + +// Block allocation size (a tuning parameter) is found +// in bufferarray.h. + +// Compatibility controls +const bool HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX = true; + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_INTERNAL_H_ diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp new file mode 100644 index 0000000000..6fe0bfc7d1 --- /dev/null +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -0,0 +1,373 @@ +/** + * @file _httplibcurl.cpp + * @brief Internal definitions of the Http libcurl thread + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httplibcurl.h" + +#include "httpheaders.h" +#include "bufferarray.h" +#include "_httpoprequest.h" +#include "_httppolicy.h" + +#include "llhttpstatuscodes.h" + + +namespace LLCore +{ + + +HttpLibcurl::HttpLibcurl(HttpService * service) + : mService(service), + mPolicyCount(0), + mMultiHandles(NULL) +{} + + +HttpLibcurl::~HttpLibcurl() +{ + shutdown(); + + mService = NULL; +} + + +void HttpLibcurl::shutdown() +{ + while (! mActiveOps.empty()) + { + HttpOpRequest * op(* mActiveOps.begin()); + mActiveOps.erase(mActiveOps.begin()); + + cancelRequest(op); + op->release(); + } + + if (mMultiHandles) + { + for (int policy_class(0); policy_class < mPolicyCount; ++policy_class) + { + if (mMultiHandles[policy_class]) + { + curl_multi_cleanup(mMultiHandles[policy_class]); + mMultiHandles[policy_class] = 0; + } + } + + delete [] mMultiHandles; + mMultiHandles = NULL; + } + + mPolicyCount = 0; +} + + +void HttpLibcurl::start(int policy_count) +{ + llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT); + llassert_always(! mMultiHandles); // One-time call only + + mPolicyCount = policy_count; + mMultiHandles = new CURLM * [mPolicyCount]; + for (int policy_class(0); policy_class < mPolicyCount; ++policy_class) + { + mMultiHandles[policy_class] = curl_multi_init(); + } +} + + +// Give libcurl some cycles, invoke it's callbacks, process +// completed requests finalizing or issuing retries as needed. +// +// If active list goes empty *and* we didn't queue any +// requests for retry, we return a request for a hard +// sleep otherwise ask for a normal polling interval. +HttpService::ELoopSpeed HttpLibcurl::processTransport() +{ + HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP); + + // Give libcurl some cycles to do I/O & callbacks + for (int policy_class(0); policy_class < mPolicyCount; ++policy_class) + { + if (! mMultiHandles[policy_class]) + continue; + + int running(0); + CURLMcode status(CURLM_CALL_MULTI_PERFORM); + do + { + running = 0; + status = curl_multi_perform(mMultiHandles[policy_class], &running); + } + while (0 != running && CURLM_CALL_MULTI_PERFORM == status); + + // Run completion on anything done + CURLMsg * msg(NULL); + int msgs_in_queue(0); + while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue))) + { + if (CURLMSG_DONE == msg->msg) + { + CURL * handle(msg->easy_handle); + CURLcode result(msg->data.result); + + if (completeRequest(mMultiHandles[policy_class], handle, result)) + { + // Request is still active, don't get too sleepy + ret = HttpService::NORMAL; + } + handle = NULL; // No longer valid on return + } + else if (CURLMSG_NONE == msg->msg) + { + // Ignore this... it shouldn't mean anything. + ; + } + else + { + LL_WARNS_ONCE("CoreHttp") << "Unexpected message from libcurl. Msg code: " + << msg->msg + << LL_ENDL; + } + msgs_in_queue = 0; + } + } + + if (! mActiveOps.empty()) + { + ret = HttpService::NORMAL; + } + return ret; +} + + +// Caller has provided us with a ref count on op. +void HttpLibcurl::addOp(HttpOpRequest * op) +{ + llassert_always(op->mReqPolicy < mPolicyCount); + llassert_always(mMultiHandles[op->mReqPolicy] != NULL); + + // Create standard handle + if (! op->prepareRequest(mService)) + { + // Couldn't issue request, fail with notification + // *TODO: Need failure path + return; + } + + // Make the request live + curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle); + op->mCurlActive = true; + + if (op->mTracing > HTTP_TRACE_OFF) + { + HttpPolicy & policy(mService->getPolicy()); + + LL_INFOS("CoreHttp") << "TRACE, ToActiveQueue, Handle: " + << static_cast<HttpHandle>(op) + << ", Actives: " << mActiveOps.size() + << ", Readies: " << policy.getReadyCount(op->mReqPolicy) + << LL_ENDL; + } + + // On success, make operation active + mActiveOps.insert(op); +} + + +// Implements the transport part of any cancel operation. +// See if the handle is an active operation and if so, +// use the more complicated transport-based cancelation +// method to kill the request. +bool HttpLibcurl::cancel(HttpHandle handle) +{ + HttpOpRequest * op(static_cast<HttpOpRequest *>(handle)); + active_set_t::iterator it(mActiveOps.find(op)); + if (mActiveOps.end() == it) + { + return false; + } + + // Cancel request + cancelRequest(op); + + // Drop references + mActiveOps.erase(it); + op->release(); + + return true; +} + + +// *NOTE: cancelRequest logic parallels completeRequest logic. +// Keep them synchronized as necessary. Caller is expected to +// remove the op from the active list and release the op *after* +// calling this method. It must be called first to deliver the +// op to the reply queue with refcount intact. +void HttpLibcurl::cancelRequest(HttpOpRequest * op) +{ + // Deactivate request + op->mCurlActive = false; + + // Detach from multi and recycle handle + curl_multi_remove_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle); + curl_easy_cleanup(op->mCurlHandle); + op->mCurlHandle = NULL; + + // Tracing + if (op->mTracing > HTTP_TRACE_OFF) + { + LL_INFOS("CoreHttp") << "TRACE, RequestCanceled, Handle: " + << static_cast<HttpHandle>(op) + << ", Status: " << op->mStatus.toHex() + << LL_ENDL; + } + + // Cancel op and deliver for notification + op->cancel(); +} + + +// *NOTE: cancelRequest logic parallels completeRequest logic. +// Keep them synchronized as necessary. +bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) +{ + HttpOpRequest * op(NULL); + curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op); + + if (handle != op->mCurlHandle || ! op->mCurlActive) + { + LL_WARNS("CoreHttp") << "libcurl handle and HttpOpRequest handle in disagreement or inactive request." + << " Handle: " << static_cast<HttpHandle>(handle) + << LL_ENDL; + return false; + } + + active_set_t::iterator it(mActiveOps.find(op)); + if (mActiveOps.end() == it) + { + LL_WARNS("CoreHttp") << "libcurl completion for request not on active list. Continuing." + << " Handle: " << static_cast<HttpHandle>(handle) + << LL_ENDL; + return false; + } + + // Deactivate request + mActiveOps.erase(it); + op->mCurlActive = false; + + // Set final status of request if it hasn't failed by other mechanisms yet + if (op->mStatus) + { + op->mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, status); + } + if (op->mStatus) + { + int http_status(HTTP_OK); + + curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_status); + if (http_status >= 100 && http_status <= 999) + { + char * cont_type(NULL); + curl_easy_getinfo(handle, CURLINFO_CONTENT_TYPE, &cont_type); + if (cont_type) + { + op->mReplyConType = cont_type; + } + op->mStatus = HttpStatus(http_status); + } + else + { + LL_WARNS("CoreHttp") << "Invalid HTTP response code (" + << http_status << ") received from server." + << LL_ENDL; + op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INVALID_HTTP_STATUS); + } + } + + // Detach from multi and recycle handle + curl_multi_remove_handle(multi_handle, handle); + curl_easy_cleanup(handle); + op->mCurlHandle = NULL; + + // Tracing + if (op->mTracing > HTTP_TRACE_OFF) + { + LL_INFOS("CoreHttp") << "TRACE, RequestComplete, Handle: " + << static_cast<HttpHandle>(op) + << ", Status: " << op->mStatus.toHex() + << LL_ENDL; + } + + // Dispatch to next stage + HttpPolicy & policy(mService->getPolicy()); + bool still_active(policy.stageAfterCompletion(op)); + + return still_active; +} + + +int HttpLibcurl::getActiveCount() const +{ + return mActiveOps.size(); +} + + +int HttpLibcurl::getActiveCountInClass(int policy_class) const +{ + int count(0); + + for (active_set_t::const_iterator iter(mActiveOps.begin()); + mActiveOps.end() != iter; + ++iter) + { + if ((*iter)->mReqPolicy == policy_class) + { + ++count; + } + } + + return count; +} + + +// --------------------------------------- +// Free functions +// --------------------------------------- + + +struct curl_slist * append_headers_to_slist(const HttpHeaders * headers, struct curl_slist * slist) +{ + for (HttpHeaders::container_t::const_iterator it(headers->mHeaders.begin()); + + headers->mHeaders.end() != it; + ++it) + { + slist = curl_slist_append(slist, (*it).c_str()); + } + return slist; +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httplibcurl.h b/indra/llcorehttp/_httplibcurl.h new file mode 100644 index 0000000000..611f029ef5 --- /dev/null +++ b/indra/llcorehttp/_httplibcurl.h @@ -0,0 +1,129 @@ +/** + * @file _httplibcurl.h + * @brief Declarations for internal class providing libcurl transport. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_LIBCURL_H_ +#define _LLCORE_HTTP_LIBCURL_H_ + +#include "linden_common.h" // Modifies curl/curl.h interfaces + +#include <curl/curl.h> +#include <curl/multi.h> + +#include <set> + +#include "httprequest.h" +#include "_httpservice.h" +#include "_httpinternal.h" + + +namespace LLCore +{ + + +class HttpPolicy; +class HttpOpRequest; +class HttpHeaders; + + +/// Implements libcurl-based transport for an HttpService instance. +/// +/// Threading: Single-threaded. Other than for construction/destruction, +/// all methods are expected to be invoked in a single thread, typically +/// a worker thread of some sort. + +class HttpLibcurl +{ +public: + HttpLibcurl(HttpService * service); + virtual ~HttpLibcurl(); + +private: + HttpLibcurl(const HttpLibcurl &); // Not defined + void operator=(const HttpLibcurl &); // Not defined + +public: + /// Give cycles to libcurl to run active requests. Completed + /// operations (successful or failed) will be retried or handed + /// over to the reply queue as final responses. + /// + /// @return Indication of how long this method is + /// willing to wait for next service call. + HttpService::ELoopSpeed processTransport(); + + /// Add request to the active list. Caller is expected to have + /// provided us with a reference count on the op to hold the + /// request. (No additional references will be added.) + void addOp(HttpOpRequest * op); + + /// One-time call to set the number of policy classes to be + /// serviced and to create the resources for each. Value + /// must agree with HttpPolicy::setPolicies() call. + void start(int policy_count); + + /// Synchronously stop libcurl operations. All active requests + /// are canceled and removed from libcurl's handling. Easy + /// handles are detached from their multi handles and released. + /// Multi handles are also released. Canceled requests are + /// completed with canceled status and made available on their + /// respective reply queues. + /// + /// Can be restarted with a start() call. + void shutdown(); + + /// Return global and per-class counts of active requests. + int getActiveCount() const; + int getActiveCountInClass(int policy_class) const; + + /// Attempt to cancel a request identified by handle. + /// + /// Interface shadows HttpService's method. + /// + /// @return True if handle was found and operation canceled. + /// + bool cancel(HttpHandle handle); + +protected: + /// Invoked when libcurl has indicated a request has been processed + /// to completion and we need to move the request to a new state. + bool completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status); + + /// Invoked to cancel an active request, mainly during shutdown + /// and destroy. + void cancelRequest(HttpOpRequest * op); + +protected: + typedef std::set<HttpOpRequest *> active_set_t; + +protected: + HttpService * mService; // Simple reference, not owner + active_set_t mActiveOps; + int mPolicyCount; + CURLM ** mMultiHandles; +}; // end class HttpLibcurl + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_LIBCURL_H_ diff --git a/indra/llcorehttp/_httpopcancel.cpp b/indra/llcorehttp/_httpopcancel.cpp new file mode 100644 index 0000000000..c1912eb3db --- /dev/null +++ b/indra/llcorehttp/_httpopcancel.cpp @@ -0,0 +1,73 @@ +/** + * @file _httpopcancel.cpp + * @brief Definitions for internal class HttpOpCancel + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httpopcancel.h" + +#include "httpcommon.h" +#include "httphandler.h" +#include "httpresponse.h" + +#include "_httpservice.h" + + +namespace LLCore +{ + + +// ================================== +// HttpOpCancel +// ================================== + + +HttpOpCancel::HttpOpCancel(HttpHandle handle) + : HttpOperation(), + mHandle(handle) +{} + + +HttpOpCancel::~HttpOpCancel() +{} + + +// Immediately search for the request on various queues +// and cancel operations if found. Return the status of +// the search and cancel as the status of this request. +// The canceled request will return a canceled status to +// its handler. +void HttpOpCancel::stageFromRequest(HttpService * service) +{ + if (! service->cancel(mHandle)) + { + mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND); + } + + addAsReply(); +} + + +} // end namespace LLCore + + diff --git a/indra/llcorehttp/_httpopcancel.h b/indra/llcorehttp/_httpopcancel.h new file mode 100644 index 0000000000..336dfdc573 --- /dev/null +++ b/indra/llcorehttp/_httpopcancel.h @@ -0,0 +1,78 @@ +/** + * @file _httpopcancel.h + * @brief Internal declarations for the HttpOpCancel subclass + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_OPCANCEL_H_ +#define _LLCORE_HTTP_OPCANCEL_H_ + + +#include "linden_common.h" // Modifies curl/curl.h interfaces + +#include "httpcommon.h" + +#include <curl/curl.h> + +#include "_httpoperation.h" +#include "_refcounted.h" + + +namespace LLCore +{ + + +/// HttpOpCancel requests that a previously issued request +/// be canceled, if possible. This includes active requests +/// that may be in the middle of an HTTP transaction. Any +/// completed request will not be canceled and will return +/// its final status unchanged and *this* request will complete +/// with an HE_HANDLE_NOT_FOUND error status. + +class HttpOpCancel : public HttpOperation +{ +public: + /// @param handle Handle of previously-issued request to + /// be canceled. + HttpOpCancel(HttpHandle handle); + +protected: + virtual ~HttpOpCancel(); // Use release() + +private: + HttpOpCancel(const HttpOpCancel &); // Not defined + void operator=(const HttpOpCancel &); // Not defined + +public: + virtual void stageFromRequest(HttpService *); + +public: + // Request data + HttpHandle mHandle; +}; // end class HttpOpCancel + + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_OPCANCEL_H_ + diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp new file mode 100644 index 0000000000..5cf5bc5930 --- /dev/null +++ b/indra/llcorehttp/_httpoperation.cpp @@ -0,0 +1,248 @@ +/** + * @file _httpoperation.cpp + * @brief Definitions for internal classes based on HttpOperation + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httpoperation.h" + +#include "httphandler.h" +#include "httpresponse.h" +#include "httprequest.h" + +#include "_httprequestqueue.h" +#include "_httpreplyqueue.h" +#include "_httpservice.h" +#include "_httpinternal.h" + +#include "lltimer.h" + + +namespace LLCore +{ + + +// ================================== +// HttpOperation +// ================================== + + +HttpOperation::HttpOperation() + : LLCoreInt::RefCounted(true), + mReplyQueue(NULL), + mUserHandler(NULL), + mReqPolicy(HttpRequest::DEFAULT_POLICY_ID), + mReqPriority(0U), + mTracing(0) +{ + mMetricCreated = totalTime(); +} + + +HttpOperation::~HttpOperation() +{ + setReplyPath(NULL, NULL); +} + + +void HttpOperation::setReplyPath(HttpReplyQueue * reply_queue, + HttpHandler * user_handler) +{ + if (reply_queue != mReplyQueue) + { + if (mReplyQueue) + { + mReplyQueue->release(); + } + + if (reply_queue) + { + reply_queue->addRef(); + } + + mReplyQueue = reply_queue; + } + + // Not refcounted + mUserHandler = user_handler; +} + + + +void HttpOperation::stageFromRequest(HttpService *) +{ + // Default implementation should never be called. This + // indicates an operation making a transition that isn't + // defined. + LL_ERRS("HttpCore") << "Default stageFromRequest method may not be called." + << LL_ENDL; +} + + +void HttpOperation::stageFromReady(HttpService *) +{ + // Default implementation should never be called. This + // indicates an operation making a transition that isn't + // defined. + LL_ERRS("HttpCore") << "Default stageFromReady method may not be called." + << LL_ENDL; +} + + +void HttpOperation::stageFromActive(HttpService *) +{ + // Default implementation should never be called. This + // indicates an operation making a transition that isn't + // defined. + LL_ERRS("HttpCore") << "Default stageFromActive method may not be called." + << LL_ENDL; +} + + +void HttpOperation::visitNotifier(HttpRequest *) +{ + if (mUserHandler) + { + HttpResponse * response = new HttpResponse(); + + response->setStatus(mStatus); + mUserHandler->onCompleted(static_cast<HttpHandle>(this), response); + + response->release(); + } +} + + +HttpStatus HttpOperation::cancel() +{ + HttpStatus status; + + return status; +} + + +void HttpOperation::addAsReply() +{ + if (mTracing > HTTP_TRACE_OFF) + { + LL_INFOS("CoreHttp") << "TRACE, ToReplyQueue, Handle: " + << static_cast<HttpHandle>(this) + << LL_ENDL; + } + + if (mReplyQueue) + { + addRef(); + mReplyQueue->addOp(this); + } +} + + +// ================================== +// HttpOpStop +// ================================== + + +HttpOpStop::HttpOpStop() + : HttpOperation() +{} + + +HttpOpStop::~HttpOpStop() +{} + + +void HttpOpStop::stageFromRequest(HttpService * service) +{ + // Do operations + service->stopRequested(); + + // Prepare response if needed + addAsReply(); +} + + +// ================================== +// HttpOpNull +// ================================== + + +HttpOpNull::HttpOpNull() + : HttpOperation() +{} + + +HttpOpNull::~HttpOpNull() +{} + + +void HttpOpNull::stageFromRequest(HttpService * service) +{ + // Perform op + // Nothing to perform. This doesn't fall into the libcurl + // ready/active queues, it just bounces over to the reply + // queue directly. + + // Prepare response if needed + addAsReply(); +} + + +// ================================== +// HttpOpSpin +// ================================== + + +HttpOpSpin::HttpOpSpin(int mode) + : HttpOperation(), + mMode(mode) +{} + + +HttpOpSpin::~HttpOpSpin() +{} + + +void HttpOpSpin::stageFromRequest(HttpService * service) +{ + if (0 == mMode) + { + // Spin forever + while (true) + { + ms_sleep(100); + } + } + else + { + ms_sleep(1); // backoff interlock plumbing a bit + this->addRef(); + if (! service->getRequestQueue().addOp(this)) + { + this->release(); + } + } +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h new file mode 100644 index 0000000000..914627fad0 --- /dev/null +++ b/indra/llcorehttp/_httpoperation.h @@ -0,0 +1,262 @@ +/** + * @file _httpoperation.h + * @brief Internal declarations for HttpOperation and sub-classes + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_OPERATION_H_ +#define _LLCORE_HTTP_OPERATION_H_ + + +#include "httpcommon.h" +#include "httprequest.h" +#include "_refcounted.h" + + +namespace LLCore +{ + +class HttpReplyQueue; +class HttpHandler; +class HttpService; + +/// HttpOperation is the base class for all request/reply +/// pairs. +/// +/// Operations are expected to be of two types: immediate +/// and queued. Immediate requests go to the singleton +/// request queue and when picked up by the worker thread +/// are executed immediately and there results placed on +/// the supplied reply queue. Queued requests (namely for +/// HTTP operations), go to the request queue, are picked +/// up and moved to a ready queue where they're ordered by +/// priority and managed by the policy component, are +/// then activated issuing HTTP requests and moved to an +/// active list managed by the transport (libcurl) component +/// and eventually finalized when a response is available +/// and status and data return via reply queue. +/// +/// To manage these transitions, derived classes implement +/// three methods: stageFromRequest, stageFromReady and +/// stageFromActive. Immediate requests will only override +/// stageFromRequest which will perform the operation and +/// return the result by invoking addAsReply() to put the +/// request on a reply queue. Queued requests will involve +/// all three stage methods. +/// +/// Threading: not thread-safe. Base and derived classes +/// provide no locking. Instances move across threads +/// via queue-like interfaces that are thread compatible +/// and those interfaces establish the access rules. + +class HttpOperation : public LLCoreInt::RefCounted +{ +public: + /// Threading: called by a consumer/application thread. + HttpOperation(); + +protected: + /// Threading: called by any thread. + virtual ~HttpOperation(); // Use release() + +private: + HttpOperation(const HttpOperation &); // Not defined + void operator=(const HttpOperation &); // Not defined + +public: + /// Register a reply queue and a handler for completion notifications. + /// + /// Invokers of operations that want to receive notification that an + /// operation has been completed do so by binding a reply queue and + /// a handler object to the request. + /// + /// @param reply_queue Pointer to the reply queue where completion + /// notifications are to be queued (typically + /// by addAsReply()). This will typically be + /// the reply queue referenced by the request + /// object. This method will increment the + /// refcount on the queue holding the queue + /// until delivery is complete. Using a reply_queue + /// even if the handler is NULL has some benefits + /// for memory deallocation by keeping it in the + /// originating thread. + /// + /// @param handler Possibly NULL pointer to a non-refcounted + //// handler object to be invoked (onCompleted) + /// when the operation is finished. Note that + /// the handler object is never dereferenced + /// by the worker thread. This is passible data + /// until notification is performed. + /// + /// Threading: called by application thread. + /// + void setReplyPath(HttpReplyQueue * reply_queue, + HttpHandler * handler); + + /// The three possible staging steps in an operation's lifecycle. + /// Asynchronous requests like HTTP operations move from the + /// request queue to the ready queue via stageFromRequest. Then + /// from the ready queue to the active queue by stageFromReady. And + /// when complete, to the reply queue via stageFromActive and the + /// addAsReply utility. + /// + /// Immediate mode operations (everything else) move from the + /// request queue to the reply queue directly via stageFromRequest + /// and addAsReply with no existence on the ready or active queues. + /// + /// These methods will take out a reference count on the request, + /// caller only needs to dispose of its reference when done with + /// the request. + /// + /// Threading: called by worker thread. + /// + virtual void stageFromRequest(HttpService *); + virtual void stageFromReady(HttpService *); + virtual void stageFromActive(HttpService *); + + /// Delivers a notification to a handler object on completion. + /// + /// Once a request is complete and it has been removed from its + /// reply queue, a handler notification may be delivered by a + /// call to HttpRequest::update(). This method does the necessary + /// dispatching. + /// + /// Threading: called by application thread. + /// + virtual void visitNotifier(HttpRequest *); + + /// Cancels the operation whether queued or active. + /// Final status of the request becomes canceled (an error) and + /// that will be delivered to caller via notification scheme. + /// + /// Threading: called by worker thread. + /// + virtual HttpStatus cancel(); + +protected: + /// Delivers request to reply queue on completion. After this + /// call, worker thread no longer accesses the object and it + /// is owned by the reply queue. + /// + /// Threading: called by worker thread. + /// + void addAsReply(); + +protected: + HttpReplyQueue * mReplyQueue; // Have refcount + HttpHandler * mUserHandler; // Naked pointer + +public: + // Request Data + HttpRequest::policy_t mReqPolicy; + HttpRequest::priority_t mReqPriority; + + // Reply Data + HttpStatus mStatus; + + // Tracing, debug and metrics + HttpTime mMetricCreated; + int mTracing; +}; // end class HttpOperation + + +/// HttpOpStop requests the servicing thread to shutdown +/// operations, cease pulling requests from the request +/// queue and release shared resources (particularly +/// those shared via reference count). The servicing +/// thread will then exit. The underlying thread object +/// remains so that another thread can join on the +/// servicing thread prior to final cleanup. The +/// request *does* generate a reply on the response +/// queue, if requested. + +class HttpOpStop : public HttpOperation +{ +public: + HttpOpStop(); + +protected: + virtual ~HttpOpStop(); + +private: + HttpOpStop(const HttpOpStop &); // Not defined + void operator=(const HttpOpStop &); // Not defined + +public: + virtual void stageFromRequest(HttpService *); + +}; // end class HttpOpStop + + +/// HttpOpNull is a do-nothing operation used for testing via +/// a basic loopback pattern. It's executed immediately by +/// the servicing thread which bounces a reply back to the +/// caller without any further delay. + +class HttpOpNull : public HttpOperation +{ +public: + HttpOpNull(); + +protected: + virtual ~HttpOpNull(); + +private: + HttpOpNull(const HttpOpNull &); // Not defined + void operator=(const HttpOpNull &); // Not defined + +public: + virtual void stageFromRequest(HttpService *); + +}; // end class HttpOpNull + + +/// HttpOpSpin is a test-only request that puts the worker +/// thread into a cpu spin. Used for unit tests and cleanup +/// evaluation. You do not want to use this in production. +class HttpOpSpin : public HttpOperation +{ +public: + // 0 does a hard spin in the operation + // 1 does a soft spin continuously requeuing itself + HttpOpSpin(int mode); + +protected: + virtual ~HttpOpSpin(); + +private: + HttpOpSpin(const HttpOpSpin &); // Not defined + void operator=(const HttpOpSpin &); // Not defined + +public: + virtual void stageFromRequest(HttpService *); + +protected: + int mMode; +}; // end class HttpOpSpin + + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_OPERATION_H_ + diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp new file mode 100644 index 0000000000..7db19b1841 --- /dev/null +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -0,0 +1,906 @@ +/** + * @file _httpoprequest.cpp + * @brief Definitions for internal class HttpOpRequest + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httpoprequest.h" + +#include <cstdio> +#include <algorithm> + +#include "httpcommon.h" +#include "httphandler.h" +#include "httpresponse.h" +#include "bufferarray.h" +#include "httpheaders.h" +#include "httpoptions.h" + +#include "_httprequestqueue.h" +#include "_httpreplyqueue.h" +#include "_httpservice.h" +#include "_httppolicy.h" +#include "_httppolicyglobal.h" +#include "_httplibcurl.h" +#include "_httpinternal.h" + +#include "llhttpstatuscodes.h" +#include "llproxy.h" + +namespace +{ + +// Attempts to parse a 'Content-Range:' header. Caller must already +// have verified that the header tag is present. The 'buffer' argument +// will be processed by strtok_r calls which will modify the buffer. +// +// @return -1 if invalid and response should be dropped, 0 if valid an +// correct, 1 if couldn't be parsed. If 0, the first, last, +// and length arguments are also written. 'length' may be +// 0 if the length wasn't available to the server. +// +int parse_content_range_header(char * buffer, + unsigned int * first, + unsigned int * last, + unsigned int * length); + + +// Take data from libcurl's CURLOPT_DEBUGFUNCTION callback and +// escape and format it for a tracing line in logging. Absolutely +// anything including NULs can be in the data. If @scrub is true, +// non-printing or non-ascii characters are replaced with spaces +// otherwise a %XX form of escaping is used. +void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub, + std::string & safe_line); + + +// OS-neutral string comparisons of various types +int os_strncasecmp(const char *s1, const char *s2, size_t n); +int os_strcasecmp(const char *s1, const char *s2); +char * os_strtok_r(char *str, const char *delim, char **saveptr); + + +static const char * const hdr_whitespace(" \t"); +static const char * const hdr_separator(": \t"); + +} // end anonymous namespace + + +namespace LLCore +{ + + +HttpOpRequest::HttpOpRequest() + : HttpOperation(), + mProcFlags(0U), + mReqMethod(HOR_GET), + mReqBody(NULL), + mReqOffset(0), + mReqLength(0), + mReqHeaders(NULL), + mReqOptions(NULL), + mCurlActive(false), + mCurlHandle(NULL), + mCurlService(NULL), + mCurlHeaders(NULL), + mCurlBodyPos(0), + mReplyBody(NULL), + mReplyOffset(0), + mReplyLength(0), + mReplyFullLength(0), + mReplyHeaders(NULL), + mPolicyRetries(0), + mPolicyRetryAt(HttpTime(0)), + mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT) +{ + // *NOTE: As members are added, retry initialization/cleanup + // may need to be extended in @see prepareRequest(). +} + + + +HttpOpRequest::~HttpOpRequest() +{ + if (mReqBody) + { + mReqBody->release(); + mReqBody = NULL; + } + + if (mReqOptions) + { + mReqOptions->release(); + mReqOptions = NULL; + } + + if (mReqHeaders) + { + mReqHeaders->release(); + mReqHeaders = NULL; + } + + if (mCurlHandle) + { + curl_easy_cleanup(mCurlHandle); + mCurlHandle = NULL; + } + + mCurlService = NULL; + + if (mCurlHeaders) + { + curl_slist_free_all(mCurlHeaders); + mCurlHeaders = NULL; + } + + if (mReplyBody) + { + mReplyBody->release(); + mReplyBody = NULL; + } + + if (mReplyHeaders) + { + mReplyHeaders->release(); + mReplyHeaders = NULL; + } +} + + +void HttpOpRequest::stageFromRequest(HttpService * service) +{ + addRef(); + service->getPolicy().addOp(this); // transfers refcount +} + + +void HttpOpRequest::stageFromReady(HttpService * service) +{ + addRef(); + service->getTransport().addOp(this); // transfers refcount +} + + +void HttpOpRequest::stageFromActive(HttpService * service) +{ + if (mReplyLength) + { + // If non-zero, we received and processed a Content-Range + // header with the response. Verify that what it says + // is consistent with the received data. + if (mReplyLength != mReplyBody->size()) + { + // Not as expected, fail the request + mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR); + } + } + + if (mCurlHeaders) + { + // We take these headers out of the request now as they were + // allocated originally in this thread and the notifier doesn't + // need them. This eliminates one source of heap moving across + // threads. + + curl_slist_free_all(mCurlHeaders); + mCurlHeaders = NULL; + } + + addAsReply(); +} + + +void HttpOpRequest::visitNotifier(HttpRequest * request) +{ + if (mUserHandler) + { + HttpResponse * response = new HttpResponse(); + response->setStatus(mStatus); + response->setBody(mReplyBody); + response->setHeaders(mReplyHeaders); + if (mReplyOffset || mReplyLength) + { + // Got an explicit offset/length in response + response->setRange(mReplyOffset, mReplyLength, mReplyFullLength); + } + response->setContentType(mReplyConType); + + mUserHandler->onCompleted(static_cast<HttpHandle>(this), response); + + response->release(); + } +} + + +HttpStatus HttpOpRequest::cancel() +{ + mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED); + + addAsReply(); + + return HttpStatus(); +} + + +HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + HttpOptions * options, + HttpHeaders * headers) +{ + setupCommon(policy_id, priority, url, NULL, options, headers); + mReqMethod = HOR_GET; + + return HttpStatus(); +} + + +HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + size_t offset, + size_t len, + HttpOptions * options, + HttpHeaders * headers) +{ + setupCommon(policy_id, priority, url, NULL, options, headers); + mReqMethod = HOR_GET; + mReqOffset = offset; + mReqLength = len; + if (offset || len) + { + mProcFlags |= PF_SCAN_RANGE_HEADER; + } + + return HttpStatus(); +} + + +HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers) +{ + setupCommon(policy_id, priority, url, body, options, headers); + mReqMethod = HOR_POST; + + return HttpStatus(); +} + + +HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers) +{ + setupCommon(policy_id, priority, url, body, options, headers); + mReqMethod = HOR_PUT; + + return HttpStatus(); +} + + +void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers) +{ + mProcFlags = 0U; + mReqPolicy = policy_id; + mReqPriority = priority; + mReqURL = url; + if (body) + { + body->addRef(); + mReqBody = body; + } + if (headers && ! mReqHeaders) + { + headers->addRef(); + mReqHeaders = headers; + } + if (options && ! mReqOptions) + { + options->addRef(); + mReqOptions = options; + if (options->getWantHeaders()) + { + mProcFlags |= PF_SAVE_HEADERS; + } + mPolicyRetryLimit = options->getRetries(); + mPolicyRetryLimit = llclamp(mPolicyRetryLimit, HTTP_RETRY_COUNT_MIN, HTTP_RETRY_COUNT_MAX); + mTracing = (std::max)(mTracing, llclamp(options->getTrace(), HTTP_TRACE_MIN, HTTP_TRACE_MAX)); + } +} + + +// Sets all libcurl options and data for a request. +// +// Used both for initial requests and to 'reload' for +// a retry, generally with a different CURL handle. +// Junk may be left around from a failed request and that +// needs to be cleaned out. +// +HttpStatus HttpOpRequest::prepareRequest(HttpService * service) +{ + // Scrub transport and result data for retried op case + mCurlActive = false; + mCurlHandle = NULL; + mCurlService = NULL; + if (mCurlHeaders) + { + curl_slist_free_all(mCurlHeaders); + mCurlHeaders = NULL; + } + mCurlBodyPos = 0; + + if (mReplyBody) + { + mReplyBody->release(); + mReplyBody = NULL; + } + mReplyOffset = 0; + mReplyLength = 0; + mReplyFullLength = 0; + if (mReplyHeaders) + { + mReplyHeaders->release(); + mReplyHeaders = NULL; + } + mReplyConType.clear(); + + // *FIXME: better error handling later + HttpStatus status; + + // Get policy options + HttpPolicyGlobal & policy(service->getPolicy().getGlobalOptions()); + + mCurlHandle = curl_easy_init(); + curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str()); + curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this); + curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); + + if (HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX) + { + // The Linksys WRT54G V5 router has an issue with frequent + // DNS lookups from LAN machines. If they happen too often, + // like for every HTTP request, the router gets annoyed after + // about 700 or so requests and starts issuing TCP RSTs to + // new connections. Reuse the DNS lookups for even a few + // seconds and no RSTs. + curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15); + } + else + { + // *TODO: Revisit this old DNS timeout setting - may no longer be valid + // I don't think this is valid anymore, the Multi shared DNS + // cache is working well. For the case of naked easy handles, + // consider using a shared DNS object. + curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); + } + curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1); + curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT); + curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback); + curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, this); + curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback); + curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this); + curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, 0); + + const std::string * opt_value(NULL); + long opt_long(0L); + policy.get(HttpRequest::GP_LLPROXY, &opt_long); + if (opt_long) + { + // Use the viewer-based thread-safe API which has a + // fast/safe check for proxy enable. Would like to + // encapsulate this someway... + LLProxy::getInstance()->applyProxySettings(mCurlHandle); + } + else if (policy.get(HttpRequest::GP_HTTP_PROXY, &opt_value)) + { + // *TODO: This is fine for now but get fuller socks5/ + // authentication thing going later.... + curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, opt_value->c_str()); + curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); + } + if (policy.get(HttpRequest::GP_CA_PATH, &opt_value)) + { + curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, opt_value->c_str()); + } + if (policy.get(HttpRequest::GP_CA_FILE, &opt_value)) + { + curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, opt_value->c_str()); + } + + switch (mReqMethod) + { + case HOR_GET: + curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive"); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300"); + break; + + case HOR_POST: + { + curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1); + curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); + long data_size(0); + if (mReqBody) + { + data_size = mReqBody->size(); + } + curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL)); + curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:"); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive"); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300"); + } + break; + + case HOR_PUT: + { + curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1); + long data_size(0); + if (mReqBody) + { + data_size = mReqBody->size(); + } + curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size); + curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:"); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive"); + mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300"); + } + break; + + default: + LL_ERRS("CoreHttp") << "Invalid HTTP method in request: " + << int(mReqMethod) << ". Can't recover." + << LL_ENDL; + break; + } + + // Tracing + if (mTracing >= HTTP_TRACE_CURL_HEADERS) + { + curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1); + curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this); + curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback); + } + + // There's a CURLOPT for this now... + if ((mReqOffset || mReqLength) && HOR_GET == mReqMethod) + { + static const char * const fmt1("Range: bytes=%lu-%lu"); + static const char * const fmt2("Range: bytes=%lu-"); + + char range_line[64]; + +#if LL_WINDOWS + _snprintf_s(range_line, sizeof(range_line), sizeof(range_line) - 1, + (mReqLength ? fmt1 : fmt2), + (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1)); +#else + snprintf(range_line, sizeof(range_line), + (mReqLength ? fmt1 : fmt2), + (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1)); +#endif // LL_WINDOWS + range_line[sizeof(range_line) - 1] = '\0'; + mCurlHeaders = curl_slist_append(mCurlHeaders, range_line); + } + + mCurlHeaders = curl_slist_append(mCurlHeaders, "Pragma:"); + + // Request options + long timeout(HTTP_REQUEST_TIMEOUT_DEFAULT); + if (mReqOptions) + { + timeout = mReqOptions->getTimeout(); + timeout = llclamp(timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX); + } + curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, timeout); + curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout); + + // Request headers + if (mReqHeaders) + { + // Caller's headers last to override + mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders); + } + curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders); + + if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS)) + { + curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback); + curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this); + } + + if (status) + { + mCurlService = service; + } + return status; +} + + +size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void * userdata) +{ + HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + + if (! op->mReplyBody) + { + op->mReplyBody = new BufferArray(); + } + const size_t req_size(size * nmemb); + const size_t write_size(op->mReplyBody->append(static_cast<char *>(data), req_size)); + return write_size; +} + + +size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata) +{ + HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + + if (! op->mReqBody) + { + return 0; + } + const size_t req_size(size * nmemb); + const size_t body_size(op->mReqBody->size()); + if (body_size <= op->mCurlBodyPos) + { + LL_WARNS("HttpCore") << "Request body position beyond body size. Aborting request." + << LL_ENDL; + return 0; + } + + const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos)); + const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size)); + op->mCurlBodyPos += read_size; + return read_size; +} + + +size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata) +{ + static const char status_line[] = "HTTP/"; + static const size_t status_line_len = sizeof(status_line) - 1; + + static const char con_ran_line[] = "content-range:"; + static const size_t con_ran_line_len = sizeof(con_ran_line) - 1; + + HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + + const size_t hdr_size(size * nmemb); + const char * hdr_data(static_cast<const char *>(data)); // Not null terminated + + if (hdr_size >= status_line_len && ! strncmp(status_line, hdr_data, status_line_len)) + { + // One of possibly several status lines. Reset what we know and start over + // taking results from the last header stanza we receive. + op->mReplyOffset = 0; + op->mReplyLength = 0; + op->mReplyFullLength = 0; + op->mStatus = HttpStatus(); + if (op->mReplyHeaders) + { + op->mReplyHeaders->mHeaders.clear(); + } + } + + // Nothing in here wants a final CR/LF combination. Remove + // it as much as possible. + size_t wanted_hdr_size(hdr_size); + if (wanted_hdr_size && '\n' == hdr_data[wanted_hdr_size - 1]) + { + if (--wanted_hdr_size && '\r' == hdr_data[wanted_hdr_size - 1]) + { + --wanted_hdr_size; + } + } + + // Save header if caller wants them in the response + if (op->mProcFlags & PF_SAVE_HEADERS) + { + // Save headers in response + if (! op->mReplyHeaders) + { + op->mReplyHeaders = new HttpHeaders; + } + op->mReplyHeaders->mHeaders.push_back(std::string(hdr_data, wanted_hdr_size)); + } + + // Detect and parse 'Content-Range' headers + if (op->mProcFlags & PF_SCAN_RANGE_HEADER) + { + char hdr_buffer[128]; // Enough for a reasonable header + size_t frag_size((std::min)(wanted_hdr_size, sizeof(hdr_buffer) - 1)); + + memcpy(hdr_buffer, hdr_data, frag_size); + hdr_buffer[frag_size] = '\0'; + if (frag_size > con_ran_line_len && + ! os_strncasecmp(hdr_buffer, con_ran_line, con_ran_line_len)) + { + unsigned int first(0), last(0), length(0); + int status; + + if (! (status = parse_content_range_header(hdr_buffer, &first, &last, &length))) + { + // Success, record the fragment position + op->mReplyOffset = first; + op->mReplyLength = last - first + 1; + op->mReplyFullLength = length; + } + else if (-1 == status) + { + // Response is badly formed and shouldn't be accepted + op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR); + } + else + { + // Ignore the unparsable. + LL_INFOS_ONCE("CoreHttp") << "Problem parsing odd Content-Range header: '" + << std::string(hdr_data, frag_size) + << "'. Ignoring." + << LL_ENDL; + } + } + } + + return hdr_size; +} + + +int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata) +{ + HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + + std::string safe_line; + std::string tag; + bool logit(false); + len = (std::min)(len, size_t(256)); // Keep things reasonable in all cases + + switch (info) + { + case CURLINFO_TEXT: + if (op->mTracing >= HTTP_TRACE_CURL_HEADERS) + { + tag = "TEXT"; + escape_libcurl_debug_data(buffer, len, true, safe_line); + logit = true; + } + break; + + case CURLINFO_HEADER_IN: + if (op->mTracing >= HTTP_TRACE_CURL_HEADERS) + { + tag = "HEADERIN"; + escape_libcurl_debug_data(buffer, len, true, safe_line); + logit = true; + } + break; + + case CURLINFO_HEADER_OUT: + if (op->mTracing >= HTTP_TRACE_CURL_HEADERS) + { + tag = "HEADEROUT"; + escape_libcurl_debug_data(buffer, 2 * len, true, safe_line); // Goes out as one line + logit = true; + } + break; + + case CURLINFO_DATA_IN: + if (op->mTracing >= HTTP_TRACE_CURL_HEADERS) + { + tag = "DATAIN"; + logit = true; + if (op->mTracing >= HTTP_TRACE_CURL_BODIES) + { + escape_libcurl_debug_data(buffer, len, false, safe_line); + } + else + { + std::ostringstream out; + out << len << " Bytes"; + safe_line = out.str(); + } + } + break; + + case CURLINFO_DATA_OUT: + if (op->mTracing >= HTTP_TRACE_CURL_HEADERS) + { + tag = "DATAOUT"; + logit = true; + if (op->mTracing >= HTTP_TRACE_CURL_BODIES) + { + escape_libcurl_debug_data(buffer, len, false, safe_line); + } + else + { + std::ostringstream out; + out << len << " Bytes"; + safe_line = out.str(); + } + } + break; + + default: + logit = false; + break; + } + + if (logit) + { + LL_INFOS("CoreHttp") << "TRACE, LibcurlDebug, Handle: " + << static_cast<HttpHandle>(op) + << ", Type: " << tag + << ", Data: " << safe_line + << LL_ENDL; + } + + return 0; +} + + +} // end namespace LLCore + + +// ======================================= +// Anonymous Namespace +// ======================================= + +namespace +{ + +int parse_content_range_header(char * buffer, + unsigned int * first, + unsigned int * last, + unsigned int * length) +{ + char * tok_state(NULL), * tok(NULL); + bool match(true); + + if (! os_strtok_r(buffer, hdr_separator, &tok_state)) + match = false; + if (match && (tok = os_strtok_r(NULL, hdr_whitespace, &tok_state))) + match = 0 == os_strcasecmp("bytes", tok); + if (match && ! (tok = os_strtok_r(NULL, " \t", &tok_state))) + match = false; + if (match) + { + unsigned int lcl_first(0), lcl_last(0), lcl_len(0); + +#if LL_WINDOWS + if (3 == sscanf_s(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len)) +#else + if (3 == sscanf(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len)) +#endif // LL_WINDOWS + { + if (lcl_first > lcl_last || lcl_last >= lcl_len) + return -1; + *first = lcl_first; + *last = lcl_last; + *length = lcl_len; + return 0; + } +#if LL_WINDOWS + if (2 == sscanf_s(tok, "%u-%u/*", &lcl_first, &lcl_last)) +#else + if (2 == sscanf(tok, "%u-%u/*", &lcl_first, &lcl_last)) +#endif // LL_WINDOWS + { + if (lcl_first > lcl_last) + return -1; + *first = lcl_first; + *last = lcl_last; + *length = 0; + return 0; + } + } + + // Header is there but badly/unexpectedly formed, try to ignore it. + return 1; +} + + +void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub, std::string & safe_line) +{ + std::string out; + len = (std::min)(len, size_t(200)); + out.reserve(3 * len); + for (int i(0); i < len; ++i) + { + unsigned char uc(static_cast<unsigned char>(buffer[i])); + + if (uc < 32 || uc > 126) + { + if (scrub) + { + out.append(1, ' '); + } + else + { + static const char hex[] = "0123456789ABCDEF"; + char convert[4]; + + convert[0] = '%'; + convert[1] = hex[(uc >> 4) % 16]; + convert[2] = hex[uc % 16]; + convert[3] = '\0'; + out.append(convert); + } + } + else + { + out.append(1, buffer[i]); + } + } + safe_line.swap(out); +} + + +int os_strncasecmp(const char *s1, const char *s2, size_t n) +{ +#if LL_WINDOWS + return _strnicmp(s1, s2, n); +#else + return strncasecmp(s1, s2, n); +#endif // LL_WINDOWS +} + + +int os_strcasecmp(const char *s1, const char *s2) +{ +#if LL_WINDOWS + return _stricmp(s1, s2); +#else + return strcasecmp(s1, s2); +#endif // LL_WINDOWS +} + + +char * os_strtok_r(char *str, const char *delim, char ** savestate) +{ +#if LL_WINDOWS + return strtok_s(str, delim, savestate); +#else + return strtok_r(str, delim, savestate); +#endif +} + + +} // end anonymous namespace + + diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h new file mode 100644 index 0000000000..7b65d17783 --- /dev/null +++ b/indra/llcorehttp/_httpoprequest.h @@ -0,0 +1,219 @@ +/** + * @file _httpoprequest.h + * @brief Internal declarations for the HttpOpRequest subclass + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_OPREQUEST_H_ +#define _LLCORE_HTTP_OPREQUEST_H_ + + +#include "linden_common.h" // Modifies curl/curl.h interfaces + +#include <string> +#include <curl/curl.h> + +#include "httpcommon.h" +#include "httprequest.h" +#include "_httpoperation.h" +#include "_refcounted.h" + + +namespace LLCore +{ + + +class BufferArray; +class HttpHeaders; +class HttpOptions; + + +/// HttpOpRequest requests a supported HTTP method invocation with +/// option and header overrides. +/// +/// Essentially an RPC to get an HTTP GET, POST or PUT executed +/// asynchronously with options to override behaviors and HTTP +/// headers. +/// +/// Constructor creates a raw object incapable of useful work. +/// A subsequent call to one of the setupXXX() methods provides +/// the information needed to make a working request which can +/// then be enqueued to a request queue. +/// + +class HttpOpRequest : public HttpOperation +{ +public: + HttpOpRequest(); + +protected: + virtual ~HttpOpRequest(); // Use release() + +private: + HttpOpRequest(const HttpOpRequest &); // Not defined + void operator=(const HttpOpRequest &); // Not defined + +public: + enum EMethod + { + HOR_GET, + HOR_POST, + HOR_PUT + }; + + virtual void stageFromRequest(HttpService *); + virtual void stageFromReady(HttpService *); + virtual void stageFromActive(HttpService *); + + virtual void visitNotifier(HttpRequest * request); + +public: + /// Setup Methods + /// + /// Basically an RPC setup for each type of HTTP method + /// invocation with one per method type. These are + /// generally invoked right after construction. + /// + /// Threading: called by application thread + /// + HttpStatus setupGet(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + HttpOptions * options, + HttpHeaders * headers); + + HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + size_t offset, + size_t len, + HttpOptions * options, + HttpHeaders * headers); + + HttpStatus setupPost(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers); + + HttpStatus setupPut(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers); + + // Internal method used to setup the libcurl options for a request. + // Does all the libcurl handle setup in one place. + // + // Threading: called by worker thread + // + HttpStatus prepareRequest(HttpService * service); + + virtual HttpStatus cancel(); + +protected: + // Common setup for all the request methods. + // + // Threading: called by application thread + // + void setupCommon(HttpRequest::policy_t policy_id, + HttpRequest::priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers); + + // libcurl operational callbacks + // + // Threading: called by worker thread + // + static size_t writeCallback(void * data, size_t size, size_t nmemb, void * userdata); + static size_t readCallback(void * data, size_t size, size_t nmemb, void * userdata); + static size_t headerCallback(void * data, size_t size, size_t nmemb, void * userdata); + static int debugCallback(CURL *, curl_infotype info, char * buffer, size_t len, void * userdata); + +protected: + unsigned int mProcFlags; + static const unsigned int PF_SCAN_RANGE_HEADER = 0x00000001U; + static const unsigned int PF_SAVE_HEADERS = 0x00000002U; + +public: + // Request data + EMethod mReqMethod; + std::string mReqURL; + BufferArray * mReqBody; + off_t mReqOffset; + size_t mReqLength; + HttpHeaders * mReqHeaders; + HttpOptions * mReqOptions; + + // Transport data + bool mCurlActive; + CURL * mCurlHandle; + HttpService * mCurlService; + curl_slist * mCurlHeaders; + size_t mCurlBodyPos; + + // Result data + HttpStatus mStatus; + BufferArray * mReplyBody; + off_t mReplyOffset; + size_t mReplyLength; + size_t mReplyFullLength; + HttpHeaders * mReplyHeaders; + std::string mReplyConType; + + // Policy data + int mPolicyRetries; + HttpTime mPolicyRetryAt; + int mPolicyRetryLimit; +}; // end class HttpOpRequest + + +/// HttpOpRequestCompare isn't an operation but a uniform comparison +/// functor for STL containers that order by priority. Mainly +/// used for the ready queue container but defined here. +class HttpOpRequestCompare +{ +public: + bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs) + { + return lhs->mReqPriority > rhs->mReqPriority; + } +}; // end class HttpOpRequestCompare + + +// --------------------------------------- +// Free functions +// --------------------------------------- + +// Internal function to append the contents of an HttpHeaders +// instance to a curl_slist object. +curl_slist * append_headers_to_slist(const HttpHeaders *, curl_slist * slist); + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_OPREQUEST_H_ + diff --git a/indra/llcorehttp/_httpopsetget.cpp b/indra/llcorehttp/_httpopsetget.cpp new file mode 100644 index 0000000000..8198528a9b --- /dev/null +++ b/indra/llcorehttp/_httpopsetget.cpp @@ -0,0 +1,97 @@ +/** + * @file _httpopsetget.cpp + * @brief Definitions for internal class HttpOpSetGet + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httpopsetget.h" + +#include "httpcommon.h" + +#include "_httpservice.h" +#include "_httppolicy.h" + + +namespace LLCore +{ + + +// ================================== +// HttpOpSetget +// ================================== + + +HttpOpSetGet::HttpOpSetGet() + : HttpOperation(), + mIsGlobal(false), + mDoSet(false), + mSetting(-1), // Nothing requested + mLongValue(0L) +{} + + +HttpOpSetGet::~HttpOpSetGet() +{} + + +void HttpOpSetGet::setupGet(HttpRequest::EGlobalPolicy setting) +{ + mIsGlobal = true; + mSetting = setting; +} + + +void HttpOpSetGet::setupSet(HttpRequest::EGlobalPolicy setting, const std::string & value) +{ + mIsGlobal = true; + mDoSet = true; + mSetting = setting; + mStrValue = value; +} + + +void HttpOpSetGet::stageFromRequest(HttpService * service) +{ + HttpPolicyGlobal & pol_opt(service->getPolicy().getGlobalOptions()); + HttpRequest::EGlobalPolicy setting(static_cast<HttpRequest::EGlobalPolicy>(mSetting)); + + if (mDoSet) + { + mStatus = pol_opt.set(setting, mStrValue); + } + if (mStatus) + { + const std::string * value(NULL); + if ((mStatus = pol_opt.get(setting, &value))) + { + mStrValue = *value; + } + } + + addAsReply(); +} + + +} // end namespace LLCore + + diff --git a/indra/llcorehttp/_httpopsetget.h b/indra/llcorehttp/_httpopsetget.h new file mode 100644 index 0000000000..6966b9d94e --- /dev/null +++ b/indra/llcorehttp/_httpopsetget.h @@ -0,0 +1,83 @@ +/** + * @file _httpopsetget.h + * @brief Internal declarations for the HttpOpSetGet subclass + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_OPSETGET_H_ +#define _LLCORE_HTTP_OPSETGET_H_ + + +#include "linden_common.h" // Modifies curl/curl.h interfaces + +#include "httpcommon.h" + +#include <curl/curl.h> + +#include "_httpoperation.h" +#include "_refcounted.h" + + +namespace LLCore +{ + + +/// HttpOpSetGet requests dynamic changes to policy and +/// configuration settings. +/// +/// *NOTE: Expect this to change. Don't really like it yet. + +class HttpOpSetGet : public HttpOperation +{ +public: + HttpOpSetGet(); + +protected: + virtual ~HttpOpSetGet(); // Use release() + +private: + HttpOpSetGet(const HttpOpSetGet &); // Not defined + void operator=(const HttpOpSetGet &); // Not defined + +public: + /// Threading: called by application thread + void setupGet(HttpRequest::EGlobalPolicy setting); + void setupSet(HttpRequest::EGlobalPolicy setting, const std::string & value); + + virtual void stageFromRequest(HttpService *); + +public: + // Request data + bool mIsGlobal; + bool mDoSet; + int mSetting; + long mLongValue; + std::string mStrValue; + +}; // end class HttpOpSetGet + + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_OPSETGET_H_ + diff --git a/indra/llcorehttp/_httpopsetpriority.cpp b/indra/llcorehttp/_httpopsetpriority.cpp new file mode 100644 index 0000000000..d48c7a0b7d --- /dev/null +++ b/indra/llcorehttp/_httpopsetpriority.cpp @@ -0,0 +1,63 @@ +/** + * @file _httpopsetpriority.cpp + * @brief Definitions for internal classes based on HttpOpSetPriority + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httpopsetpriority.h" + +#include "httpresponse.h" +#include "httphandler.h" +#include "_httpservice.h" + + +namespace LLCore +{ + + +HttpOpSetPriority::HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority) + : HttpOperation(), + mHandle(handle), + mPriority(priority) +{} + + +HttpOpSetPriority::~HttpOpSetPriority() +{} + + +void HttpOpSetPriority::stageFromRequest(HttpService * service) +{ + // Do operations + if (! service->changePriority(mHandle, mPriority)) + { + // Request not found, fail the final status + mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND); + } + + // Move directly to response queue + addAsReply(); +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httpopsetpriority.h b/indra/llcorehttp/_httpopsetpriority.h new file mode 100644 index 0000000000..31706b737c --- /dev/null +++ b/indra/llcorehttp/_httpopsetpriority.h @@ -0,0 +1,73 @@ +/** + * @file _httpsetpriority.h + * @brief Internal declarations for HttpSetPriority + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_SETPRIORITY_H_ +#define _LLCORE_HTTP_SETPRIORITY_H_ + + +#include "httpcommon.h" +#include "httprequest.h" +#include "_httpoperation.h" +#include "_refcounted.h" + + +namespace LLCore +{ + + +/// HttpOpSetPriority is an immediate request that +/// searches the various queues looking for a given +/// request handle and changing it's priority if +/// found. +/// +/// *NOTE: This will very likely be removed in the near future +/// when priority is removed from the library. + +class HttpOpSetPriority : public HttpOperation +{ +public: + HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority); + +protected: + virtual ~HttpOpSetPriority(); + +private: + HttpOpSetPriority(const HttpOpSetPriority &); // Not defined + void operator=(const HttpOpSetPriority &); // Not defined + +public: + virtual void stageFromRequest(HttpService *); + +protected: + // Request Data + HttpHandle mHandle; + HttpRequest::priority_t mPriority; +}; // end class HttpOpSetPriority + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_SETPRIORITY_H_ + diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp new file mode 100644 index 0000000000..76c1e22431 --- /dev/null +++ b/indra/llcorehttp/_httppolicy.cpp @@ -0,0 +1,387 @@ +/** + * @file _httppolicy.cpp + * @brief Internal definitions of the Http policy thread + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "_httppolicy.h" + +#include "_httpoprequest.h" +#include "_httpservice.h" +#include "_httplibcurl.h" +#include "_httppolicyclass.h" + +#include "lltimer.h" + + +namespace LLCore +{ + + +// Per-policy-class data for a running system. +// Collection of queues, parameters, history, metrics, etc. +// for a single policy class. +// +// Threading: accessed only by worker thread +struct HttpPolicy::State +{ +public: + State() + : mConnMax(HTTP_CONNECTION_LIMIT_DEFAULT), + mConnAt(HTTP_CONNECTION_LIMIT_DEFAULT), + mConnMin(1), + mNextSample(0), + mErrorCount(0), + mErrorFactor(0) + {} + + HttpReadyQueue mReadyQueue; + HttpRetryQueue mRetryQueue; + + HttpPolicyClass mOptions; + + long mConnMax; + long mConnAt; + long mConnMin; + + HttpTime mNextSample; + unsigned long mErrorCount; + unsigned long mErrorFactor; +}; + + +HttpPolicy::HttpPolicy(HttpService * service) + : mActiveClasses(0), + mState(NULL), + mService(service) +{} + + +HttpPolicy::~HttpPolicy() +{ + shutdown(); + + mService = NULL; +} + + +void HttpPolicy::shutdown() +{ + for (int policy_class(0); policy_class < mActiveClasses; ++policy_class) + { + HttpRetryQueue & retryq(mState[policy_class].mRetryQueue); + while (! retryq.empty()) + { + HttpOpRequest * op(retryq.top()); + retryq.pop(); + + op->cancel(); + op->release(); + } + + HttpReadyQueue & readyq(mState[policy_class].mReadyQueue); + while (! readyq.empty()) + { + HttpOpRequest * op(readyq.top()); + readyq.pop(); + + op->cancel(); + op->release(); + } + } + delete [] mState; + mState = NULL; + mActiveClasses = 0; +} + + +void HttpPolicy::start(const HttpPolicyGlobal & global, + const std::vector<HttpPolicyClass> & classes) +{ + llassert_always(! mState); + + mGlobalOptions = global; + mActiveClasses = classes.size(); + mState = new State [mActiveClasses]; + for (int i(0); i < mActiveClasses; ++i) + { + mState[i].mOptions = classes[i]; + mState[i].mConnMax = classes[i].mConnectionLimit; + mState[i].mConnAt = mState[i].mConnMax; + mState[i].mConnMin = 2; + } +} + + +void HttpPolicy::addOp(HttpOpRequest * op) +{ + const int policy_class(op->mReqPolicy); + + op->mPolicyRetries = 0; + mState[policy_class].mReadyQueue.push(op); +} + + +void HttpPolicy::retryOp(HttpOpRequest * op) +{ + static const HttpTime retry_deltas[] = + { + 250000, // 1st retry in 0.25 S, etc... + 500000, + 1000000, + 2000000, + 5000000 // ... to every 5.0 S. + }; + static const int delta_max(int(LL_ARRAY_SIZE(retry_deltas)) - 1); + + const HttpTime now(totalTime()); + const int policy_class(op->mReqPolicy); + + const HttpTime delta(retry_deltas[llclamp(op->mPolicyRetries, 0, delta_max)]); + op->mPolicyRetryAt = now + delta; + ++op->mPolicyRetries; + LL_WARNS("CoreHttp") << "HTTP request " << static_cast<HttpHandle>(op) + << " retry " << op->mPolicyRetries + << " scheduled for +" << (delta / HttpTime(1000)) + << " mS. Status: " << op->mStatus.toHex() + << LL_ENDL; + if (op->mTracing > 0) + { + LL_INFOS("CoreHttp") << "TRACE, ToRetryQueue, Handle: " + << static_cast<HttpHandle>(op) + << LL_ENDL; + } + mState[policy_class].mRetryQueue.push(op); +} + + +// Attempt to deliver requests to the transport layer. +// +// Tries to find HTTP requests for each policy class with +// available capacity. Starts with the retry queue first +// looking for requests that have waited long enough then +// moves on to the ready queue. +// +// If all queues are empty, will return an indication that +// the worker thread may sleep hard otherwise will ask for +// normal polling frequency. +// +HttpService::ELoopSpeed HttpPolicy::processReadyQueue() +{ + const HttpTime now(totalTime()); + HttpService::ELoopSpeed result(HttpService::REQUEST_SLEEP); + HttpLibcurl & transport(mService->getTransport()); + + for (int policy_class(0); policy_class < mActiveClasses; ++policy_class) + { + State & state(mState[policy_class]); + int active(transport.getActiveCountInClass(policy_class)); + int needed(state.mConnAt - active); // Expect negatives here + + HttpRetryQueue & retryq(state.mRetryQueue); + HttpReadyQueue & readyq(state.mReadyQueue); + + if (needed > 0) + { + // First see if we have any retries... + while (needed > 0 && ! retryq.empty()) + { + HttpOpRequest * op(retryq.top()); + if (op->mPolicyRetryAt > now) + break; + + retryq.pop(); + + op->stageFromReady(mService); + op->release(); + + --needed; + } + + // Now go on to the new requests... + while (needed > 0 && ! readyq.empty()) + { + HttpOpRequest * op(readyq.top()); + readyq.pop(); + + op->stageFromReady(mService); + op->release(); + + --needed; + } + } + + if (! readyq.empty() || ! retryq.empty()) + { + // If anything is ready, continue looping... + result = HttpService::NORMAL; + } + } // end foreach policy_class + + return result; +} + + +bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t priority) +{ + for (int policy_class(0); policy_class < mActiveClasses; ++policy_class) + { + State & state(mState[policy_class]); + // We don't scan retry queue because a priority change there + // is meaningless. The request will be issued based on retry + // intervals not priority value, which is now moot. + + // Scan ready queue for requests that match policy + HttpReadyQueue::container_type & c(state.mReadyQueue.get_container()); + for (HttpReadyQueue::container_type::iterator iter(c.begin()); c.end() != iter;) + { + HttpReadyQueue::container_type::iterator cur(iter++); + + if (static_cast<HttpHandle>(*cur) == handle) + { + HttpOpRequest * op(*cur); + c.erase(cur); // All iterators are now invalidated + op->mReqPriority = priority; + state.mReadyQueue.push(op); // Re-insert using adapter class + return true; + } + } + } + + return false; +} + + +bool HttpPolicy::cancel(HttpHandle handle) +{ + for (int policy_class(0); policy_class < mActiveClasses; ++policy_class) + { + State & state(mState[policy_class]); + + // Scan retry queue + HttpRetryQueue::container_type & c1(state.mRetryQueue.get_container()); + for (HttpRetryQueue::container_type::iterator iter(c1.begin()); c1.end() != iter;) + { + HttpRetryQueue::container_type::iterator cur(iter++); + + if (static_cast<HttpHandle>(*cur) == handle) + { + HttpOpRequest * op(*cur); + c1.erase(cur); // All iterators are now invalidated + op->cancel(); + op->release(); + return true; + } + } + + // Scan ready queue + HttpReadyQueue::container_type & c2(state.mReadyQueue.get_container()); + for (HttpReadyQueue::container_type::iterator iter(c2.begin()); c2.end() != iter;) + { + HttpReadyQueue::container_type::iterator cur(iter++); + + if (static_cast<HttpHandle>(*cur) == handle) + { + HttpOpRequest * op(*cur); + c2.erase(cur); // All iterators are now invalidated + op->cancel(); + op->release(); + return true; + } + } + } + + return false; +} + + +bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op) +{ + static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); + static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY); + static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST); + static const HttpStatus send_error(HttpStatus::EXT_CURL_EASY, CURLE_SEND_ERROR); + static const HttpStatus recv_error(HttpStatus::EXT_CURL_EASY, CURLE_RECV_ERROR); + static const HttpStatus upload_failed(HttpStatus::EXT_CURL_EASY, CURLE_UPLOAD_FAILED); + static const HttpStatus op_timedout(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); + static const HttpStatus post_error(HttpStatus::EXT_CURL_EASY, CURLE_HTTP_POST_ERROR); + + // Retry or finalize + if (! op->mStatus) + { + // If this failed, we might want to retry. Have to inspect + // the status a little more deeply for those reasons worth retrying... + if (op->mPolicyRetries < op->mPolicyRetryLimit && + ((op->mStatus.isHttpStatus() && op->mStatus.mType >= 499 && op->mStatus.mType <= 599) || + cant_connect == op->mStatus || + cant_res_proxy == op->mStatus || + cant_res_host == op->mStatus || + send_error == op->mStatus || + recv_error == op->mStatus || + upload_failed == op->mStatus || + op_timedout == op->mStatus || + post_error == op->mStatus)) + { + // Okay, worth a retry. We include 499 in this test as + // it's the old 'who knows?' error from many grid services... + retryOp(op); + return true; // still active/ready + } + } + + // This op is done, finalize it delivering it to the reply queue... + if (! op->mStatus) + { + LL_WARNS("CoreHttp") << "HTTP request " << static_cast<HttpHandle>(op) + << " failed after " << op->mPolicyRetries + << " retries. Reason: " << op->mStatus.toString() + << " (" << op->mStatus.toHex() << ")" + << LL_ENDL; + } + else if (op->mPolicyRetries) + { + LL_WARNS("CoreHttp") << "HTTP request " << static_cast<HttpHandle>(op) + << " succeeded on retry " << op->mPolicyRetries << "." + << LL_ENDL; + } + + op->stageFromActive(mService); + op->release(); + return false; // not active +} + + +int HttpPolicy::getReadyCount(HttpRequest::policy_t policy_class) const +{ + if (policy_class < mActiveClasses) + { + return (mState[policy_class].mReadyQueue.size() + + mState[policy_class].mRetryQueue.size()); + } + return 0; +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h new file mode 100644 index 0000000000..03d92c0b8e --- /dev/null +++ b/indra/llcorehttp/_httppolicy.h @@ -0,0 +1,161 @@ +/** + * @file _httppolicy.h + * @brief Declarations for internal class enforcing policy decisions. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_POLICY_H_ +#define _LLCORE_HTTP_POLICY_H_ + + +#include "httprequest.h" +#include "_httpservice.h" +#include "_httpreadyqueue.h" +#include "_httpretryqueue.h" +#include "_httppolicyglobal.h" +#include "_httppolicyclass.h" +#include "_httpinternal.h" + + +namespace LLCore +{ + +class HttpReadyQueue; +class HttpOpRequest; + + +/// Implements class-based queuing policies for an HttpService instance. +/// +/// Threading: Single-threaded. Other than for construction/destruction, +/// all methods are expected to be invoked in a single thread, typically +/// a worker thread of some sort. +class HttpPolicy +{ +public: + HttpPolicy(HttpService *); + virtual ~HttpPolicy(); + +private: + HttpPolicy(const HttpPolicy &); // Not defined + void operator=(const HttpPolicy &); // Not defined + +public: + /// Cancel all ready and retry requests sending them to + /// their notification queues. Release state resources + /// making further request handling impossible. + /// + /// Threading: called by worker thread + void shutdown(); + + /// Deliver policy definitions and enable handling of + /// requests. One-time call invoked before starting + /// the worker thread. + /// + /// Threading: called by application thread + void start(const HttpPolicyGlobal & global, + const std::vector<HttpPolicyClass> & classes); + + /// Give the policy layer some cycles to scan the ready + /// queue promoting higher-priority requests to active + /// as permited. + /// + /// @return Indication of how soon this method + /// should be called again. + /// + /// Threading: called by worker thread + HttpService::ELoopSpeed processReadyQueue(); + + /// Add request to a ready queue. Caller is expected to have + /// provided us with a reference count to hold the request. (No + /// additional references will be added.) + /// + /// OpRequest is owned by the request queue after this call + /// and should not be modified by anyone until retrieved + /// from queue. + /// + /// Threading: called by any thread + void addOp(HttpOpRequest *); + + /// Similar to addOp, used when a caller wants to retry a + /// request that has failed. It's placed on a special retry + /// queue but ordered by retry time not priority. Otherwise, + /// handling is the same and retried operations are considered + /// before new ones but that doesn't guarantee completion + /// order. + /// + /// Threading: called by worker thread + void retryOp(HttpOpRequest *); + + /// Attempt to change the priority of an earlier request. + /// Request that Shadows HttpService's method + /// + /// Threading: called by worker thread + bool changePriority(HttpHandle handle, HttpRequest::priority_t priority); + + /// Attempt to cancel a previous request. + /// Shadows HttpService's method as well + /// + /// Threading: called by worker thread + bool cancel(HttpHandle handle); + + /// When transport is finished with an op and takes it off the + /// active queue, it is delivered here for dispatch. Policy + /// may send it back to the ready/retry queues if it needs another + /// go or we may finalize it and send it on to the reply queue. + /// + /// @return Returns true of the request is still active + /// or ready after staging, false if has been + /// sent on to the reply queue. + /// + /// Threading: called by worker thread + bool stageAfterCompletion(HttpOpRequest * op); + + // Get pointer to global policy options. Caller is expected + // to do context checks like no setting once running. + /// + /// Threading: called by any thread *but* the object may + /// only be modified by the worker thread once running. + /// + HttpPolicyGlobal & getGlobalOptions() + { + return mGlobalOptions; + } + + /// Get ready counts for a particular policy class + /// + /// Threading: called by worker thread + int getReadyCount(HttpRequest::policy_t policy_class) const; + +protected: + struct State; + + int mActiveClasses; + State * mState; + HttpService * mService; // Naked pointer, not refcounted, not owner + HttpPolicyGlobal mGlobalOptions; + +}; // end class HttpPolicy + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_POLICY_H_ diff --git a/indra/llcorehttp/_httppolicyclass.cpp b/indra/llcorehttp/_httppolicyclass.cpp new file mode 100644 index 0000000000..a23b81322c --- /dev/null +++ b/indra/llcorehttp/_httppolicyclass.cpp @@ -0,0 +1,125 @@ +/** + * @file _httppolicyclass.cpp + * @brief Definitions for internal class defining class policy option. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httppolicyclass.h" + +#include "_httpinternal.h" + + +namespace LLCore +{ + + +HttpPolicyClass::HttpPolicyClass() + : mSetMask(0UL), + mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT), + mPerHostConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT), + mPipelining(0) +{} + + +HttpPolicyClass::~HttpPolicyClass() +{} + + +HttpPolicyClass & HttpPolicyClass::operator=(const HttpPolicyClass & other) +{ + if (this != &other) + { + mSetMask = other.mSetMask; + mConnectionLimit = other.mConnectionLimit; + mPerHostConnectionLimit = other.mPerHostConnectionLimit; + mPipelining = other.mPipelining; + } + return *this; +} + + +HttpPolicyClass::HttpPolicyClass(const HttpPolicyClass & other) + : mSetMask(other.mSetMask), + mConnectionLimit(other.mConnectionLimit), + mPerHostConnectionLimit(other.mPerHostConnectionLimit), + mPipelining(other.mPipelining) +{} + + +HttpStatus HttpPolicyClass::set(HttpRequest::EClassPolicy opt, long value) +{ + switch (opt) + { + case HttpRequest::CP_CONNECTION_LIMIT: + mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX)); + break; + + case HttpRequest::CP_PER_HOST_CONNECTION_LIMIT: + mPerHostConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), mConnectionLimit); + break; + + case HttpRequest::CP_ENABLE_PIPELINING: + mPipelining = llclamp(value, 0L, 1L); + break; + + default: + return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG); + } + + mSetMask |= 1UL << int(opt); + return HttpStatus(); +} + + +HttpStatus HttpPolicyClass::get(HttpRequest::EClassPolicy opt, long * value) +{ + static const HttpStatus not_set(HttpStatus::LLCORE, HE_OPT_NOT_SET); + long * src(NULL); + + switch (opt) + { + case HttpRequest::CP_CONNECTION_LIMIT: + src = &mConnectionLimit; + break; + + case HttpRequest::CP_PER_HOST_CONNECTION_LIMIT: + src = &mPerHostConnectionLimit; + break; + + case HttpRequest::CP_ENABLE_PIPELINING: + src = &mPipelining; + break; + + default: + return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG); + } + + if (! (mSetMask & (1UL << int(opt)))) + return not_set; + + *value = *src; + return HttpStatus(); +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httppolicyclass.h b/indra/llcorehttp/_httppolicyclass.h new file mode 100644 index 0000000000..d175413cbd --- /dev/null +++ b/indra/llcorehttp/_httppolicyclass.h @@ -0,0 +1,59 @@ +/** + * @file _httppolicyclass.h + * @brief Declarations for internal class defining policy class options. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_POLICY_CLASS_H_ +#define _LLCORE_HTTP_POLICY_CLASS_H_ + + +#include "httprequest.h" + + +namespace LLCore +{ + +class HttpPolicyClass +{ +public: + HttpPolicyClass(); + ~HttpPolicyClass(); + + HttpPolicyClass & operator=(const HttpPolicyClass &); + HttpPolicyClass(const HttpPolicyClass &); // Not defined + +public: + HttpStatus set(HttpRequest::EClassPolicy opt, long value); + HttpStatus get(HttpRequest::EClassPolicy opt, long * value); + +public: + unsigned long mSetMask; + long mConnectionLimit; + long mPerHostConnectionLimit; + long mPipelining; +}; // end class HttpPolicyClass + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_POLICY_CLASS_H_ diff --git a/indra/llcorehttp/_httppolicyglobal.cpp b/indra/llcorehttp/_httppolicyglobal.cpp new file mode 100644 index 0000000000..72f409d3b1 --- /dev/null +++ b/indra/llcorehttp/_httppolicyglobal.cpp @@ -0,0 +1,175 @@ +/** + * @file _httppolicyglobal.cpp + * @brief Definitions for internal class defining global policy option. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httppolicyglobal.h" + +#include "_httpinternal.h" + + +namespace LLCore +{ + + +HttpPolicyGlobal::HttpPolicyGlobal() + : mSetMask(0UL), + mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT), + mTrace(HTTP_TRACE_OFF), + mUseLLProxy(0) +{} + + +HttpPolicyGlobal::~HttpPolicyGlobal() +{} + + +HttpPolicyGlobal & HttpPolicyGlobal::operator=(const HttpPolicyGlobal & other) +{ + if (this != &other) + { + mSetMask = other.mSetMask; + mConnectionLimit = other.mConnectionLimit; + mCAPath = other.mCAPath; + mCAFile = other.mCAFile; + mHttpProxy = other.mHttpProxy; + mTrace = other.mTrace; + mUseLLProxy = other.mUseLLProxy; + } + return *this; +} + + +HttpStatus HttpPolicyGlobal::set(HttpRequest::EGlobalPolicy opt, long value) +{ + switch (opt) + { + case HttpRequest::GP_CONNECTION_LIMIT: + mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX)); + break; + + case HttpRequest::GP_TRACE: + mTrace = llclamp(value, long(HTTP_TRACE_MIN), long(HTTP_TRACE_MAX)); + break; + + case HttpRequest::GP_LLPROXY: + mUseLLProxy = llclamp(value, 0L, 1L); + break; + + default: + return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG); + } + + mSetMask |= 1UL << int(opt); + return HttpStatus(); +} + + +HttpStatus HttpPolicyGlobal::set(HttpRequest::EGlobalPolicy opt, const std::string & value) +{ + switch (opt) + { + case HttpRequest::GP_CA_PATH: + mCAPath = value; + break; + + case HttpRequest::GP_CA_FILE: + mCAFile = value; + break; + + case HttpRequest::GP_HTTP_PROXY: + mCAFile = value; + break; + + default: + return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG); + } + + mSetMask |= 1UL << int(opt); + return HttpStatus(); +} + + +HttpStatus HttpPolicyGlobal::get(HttpRequest::EGlobalPolicy opt, long * value) +{ + static const HttpStatus not_set(HttpStatus::LLCORE, HE_OPT_NOT_SET); + long * src(NULL); + + switch (opt) + { + case HttpRequest::GP_CONNECTION_LIMIT: + src = &mConnectionLimit; + break; + + case HttpRequest::GP_TRACE: + src = &mTrace; + break; + + case HttpRequest::GP_LLPROXY: + src = &mUseLLProxy; + break; + + default: + return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG); + } + + if (! (mSetMask & (1UL << int(opt)))) + return not_set; + + *value = *src; + return HttpStatus(); +} + + +HttpStatus HttpPolicyGlobal::get(HttpRequest::EGlobalPolicy opt, const std::string ** value) +{ + static const HttpStatus not_set(HttpStatus::LLCORE, HE_OPT_NOT_SET); + const std::string * src(NULL); + + switch (opt) + { + case HttpRequest::GP_CA_PATH: + src = &mCAPath; + break; + + case HttpRequest::GP_CA_FILE: + src = &mCAFile; + break; + + case HttpRequest::GP_HTTP_PROXY: + src = &mHttpProxy; + break; + + default: + return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG); + } + + if (! (mSetMask & (1UL << int(opt)))) + return not_set; + + *value = src; + return HttpStatus(); +} + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httppolicyglobal.h b/indra/llcorehttp/_httppolicyglobal.h new file mode 100644 index 0000000000..a50d0e4188 --- /dev/null +++ b/indra/llcorehttp/_httppolicyglobal.h @@ -0,0 +1,66 @@ +/** + * @file _httppolicyglobal.h + * @brief Declarations for internal class defining global policy option. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_POLICY_GLOBAL_H_ +#define _LLCORE_HTTP_POLICY_GLOBAL_H_ + + +#include "httprequest.h" + + +namespace LLCore +{ + +class HttpPolicyGlobal +{ +public: + HttpPolicyGlobal(); + ~HttpPolicyGlobal(); + + HttpPolicyGlobal & operator=(const HttpPolicyGlobal &); + +private: + HttpPolicyGlobal(const HttpPolicyGlobal &); // Not defined + +public: + HttpStatus set(HttpRequest::EGlobalPolicy opt, long value); + HttpStatus set(HttpRequest::EGlobalPolicy opt, const std::string & value); + HttpStatus get(HttpRequest::EGlobalPolicy opt, long * value); + HttpStatus get(HttpRequest::EGlobalPolicy opt, const std::string ** value); + +public: + unsigned long mSetMask; + long mConnectionLimit; + std::string mCAPath; + std::string mCAFile; + std::string mHttpProxy; + long mTrace; + long mUseLLProxy; +}; // end class HttpPolicyGlobal + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_POLICY_GLOBAL_H_ diff --git a/indra/llcorehttp/_httpreadyqueue.h b/indra/llcorehttp/_httpreadyqueue.h new file mode 100644 index 0000000000..5f19a9c5f9 --- /dev/null +++ b/indra/llcorehttp/_httpreadyqueue.h @@ -0,0 +1,124 @@ +/** + * @file _httpreadyqueue.h + * @brief Internal declaration for the operation ready queue + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_READY_QUEUE_H_ +#define _LLCORE_HTTP_READY_QUEUE_H_ + + +#include <queue> + +#include "_httpinternal.h" +#include "_httpoprequest.h" + + +namespace LLCore +{ + +/// HttpReadyQueue provides a simple priority queue for HttpOpRequest objects. +/// +/// This uses the priority_queue adaptor class to provide the queue +/// as well as the ordering scheme while allowing us access to the +/// raw container if we follow a few simple rules. One of the more +/// important of those rules is that any iterator becomes invalid +/// on element erasure. So pay attention. +/// +/// If LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY tests true, the class +/// implements a std::priority_queue interface but on std::deque +/// behavior to eliminate sensitivity to priority. In the future, +/// this will likely become the only behavior or it may become +/// a run-time election. +/// +/// Threading: not thread-safe. Expected to be used entirely by +/// a single thread, typically a worker thread of some sort. + +#if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY + +typedef std::deque<HttpOpRequest *> HttpReadyQueueBase; + +#else + +typedef std::priority_queue<HttpOpRequest *, + std::deque<HttpOpRequest *>, + LLCore::HttpOpRequestCompare> HttpReadyQueueBase; + +#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY + +class HttpReadyQueue : public HttpReadyQueueBase +{ +public: + HttpReadyQueue() + : HttpReadyQueueBase() + {} + + ~HttpReadyQueue() + {} + +protected: + HttpReadyQueue(const HttpReadyQueue &); // Not defined + void operator=(const HttpReadyQueue &); // Not defined + +public: + +#if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY + // Types and methods needed to make a std::deque look + // more like a std::priority_queue, at least for our + // purposes. + typedef HttpReadyQueueBase container_type; + + const_reference top() const + { + return front(); + } + + void pop() + { + pop_front(); + } + + void push(const value_type & v) + { + push_back(v); + } + +#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY + + const container_type & get_container() const + { + return *this; + } + + container_type & get_container() + { + return *this; + } + +}; // end class HttpReadyQueue + + +} // end namespace LLCore + + +#endif // _LLCORE_HTTP_READY_QUEUE_H_ diff --git a/indra/llcorehttp/_httpreplyqueue.cpp b/indra/llcorehttp/_httpreplyqueue.cpp new file mode 100644 index 0000000000..558b7bdee9 --- /dev/null +++ b/indra/llcorehttp/_httpreplyqueue.cpp @@ -0,0 +1,107 @@ +/** + * @file _httpreplyqueue.cpp + * @brief Internal definitions for the operation reply queue + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httpreplyqueue.h" + + +#include "_mutex.h" +#include "_thread.h" +#include "_httpoperation.h" + +using namespace LLCoreInt; + + +namespace LLCore +{ + + +HttpReplyQueue::HttpReplyQueue() + : RefCounted(true) +{ +} + + +HttpReplyQueue::~HttpReplyQueue() +{ + while (! mQueue.empty()) + { + HttpOperation * op = mQueue.back(); + mQueue.pop_back(); + op->release(); + } +} + + +void HttpReplyQueue::addOp(HttpOperation * op) +{ + { + HttpScopedLock lock(mQueueMutex); + + mQueue.push_back(op); + } + mQueueCV.notify_all(); +} + + +HttpOperation * HttpReplyQueue::fetchOp() +{ + HttpOperation * result(NULL); + + { + HttpScopedLock lock(mQueueMutex); + + if (mQueue.empty()) + return NULL; + + result = mQueue.front(); + mQueue.erase(mQueue.begin()); + } + + // Caller also acquires the reference count + return result; +} + + +void HttpReplyQueue::fetchAll(OpContainer & ops) +{ + // Not valid putting something back on the queue... + llassert_always(ops.empty()); + + { + HttpScopedLock lock(mQueueMutex); + + if (! mQueue.empty()) + { + mQueue.swap(ops); + } + } + + // Caller also acquires the reference counts on each op. + return; +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httpreplyqueue.h b/indra/llcorehttp/_httpreplyqueue.h new file mode 100644 index 0000000000..4220a09a3b --- /dev/null +++ b/indra/llcorehttp/_httpreplyqueue.h @@ -0,0 +1,108 @@ +/** + * @file _httpreplyqueue.h + * @brief Internal declarations for the operation reply queue. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_REPLY_QUEUE_H_ +#define _LLCORE_HTTP_REPLY_QUEUE_H_ + + +#include "_refcounted.h" +#include "_mutex.h" + + +namespace LLCore +{ + + +class HttpOperation; + + +/// Almost identical to the HttpRequestQueue class but +/// whereas that class is a singleton and is known to the +/// HttpService object, this queue is 1:1 with HttpRequest +/// instances and isn't explicitly referenced by the +/// service object. Instead, HttpOperation objects that +/// want to generate replies back to their creators also +/// keep references to the corresponding HttpReplyQueue. +/// The HttpService plumbing then simply delivers replies +/// to the requested reply queue. +/// +/// One result of that is that the fetch operations do +/// not have a wait forever option. The service object +/// doesn't keep handles on everything it would need to +/// notify so it can't wake up sleepers should it need to +/// shutdown. So only non-blocking or timed-blocking modes +/// are anticipated. These are how most application consumers +/// will be coded anyway so it shouldn't be too much of a +/// burden. + +class HttpReplyQueue : public LLCoreInt::RefCounted +{ +public: + /// Caller acquires a Refcount on construction + HttpReplyQueue(); + +protected: + virtual ~HttpReplyQueue(); // Use release() + +private: + HttpReplyQueue(const HttpReplyQueue &); // Not defined + void operator=(const HttpReplyQueue &); // Not defined + +public: + typedef std::vector<HttpOperation *> OpContainer; + + /// Insert an object at the back of the reply queue. + /// + /// Library also takes possession of one reference count to pass + /// through the queue. + /// + /// Threading: callable by any thread. + void addOp(HttpOperation * op); + + /// Fetch an operation from the head of the queue. Returns + /// NULL if none exists. + /// + /// Caller acquires reference count on returned operation. + /// + /// Threading: callable by any thread. + HttpOperation * fetchOp(); + + /// Caller acquires reference count on each returned operation + /// + /// Threading: callable by any thread. + void fetchAll(OpContainer & ops); + +protected: + OpContainer mQueue; + LLCoreInt::HttpMutex mQueueMutex; + LLCoreInt::HttpConditionVariable mQueueCV; + +}; // end class HttpReplyQueue + +} // end namespace LLCore + + +#endif // _LLCORE_HTTP_REPLY_QUEUE_H_ diff --git a/indra/llcorehttp/_httprequestqueue.cpp b/indra/llcorehttp/_httprequestqueue.cpp new file mode 100644 index 0000000000..c16966d078 --- /dev/null +++ b/indra/llcorehttp/_httprequestqueue.cpp @@ -0,0 +1,161 @@ +/** + * @file _httprequestqueue.cpp + * @brief + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httprequestqueue.h" + +#include "_httpoperation.h" +#include "_mutex.h" + + +using namespace LLCoreInt; + +namespace LLCore +{ + +HttpRequestQueue * HttpRequestQueue::sInstance(NULL); + + +HttpRequestQueue::HttpRequestQueue() + : RefCounted(true), + mQueueStopped(false) +{ +} + + +HttpRequestQueue::~HttpRequestQueue() +{ + while (! mQueue.empty()) + { + HttpOperation * op = mQueue.back(); + mQueue.pop_back(); + op->release(); + } +} + + +void HttpRequestQueue::init() +{ + llassert_always(! sInstance); + sInstance = new HttpRequestQueue(); +} + + +void HttpRequestQueue::term() +{ + if (sInstance) + { + sInstance->release(); + sInstance = NULL; + } +} + + +HttpStatus HttpRequestQueue::addOp(HttpOperation * op) +{ + bool wake(false); + { + HttpScopedLock lock(mQueueMutex); + + if (mQueueStopped) + { + // Return op and error to caller + return HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN); + } + wake = mQueue.empty(); + mQueue.push_back(op); + } + if (wake) + { + mQueueCV.notify_all(); + } + return HttpStatus(); +} + + +HttpOperation * HttpRequestQueue::fetchOp(bool wait) +{ + HttpOperation * result(NULL); + + { + HttpScopedLock lock(mQueueMutex); + + while (mQueue.empty()) + { + if (! wait || mQueueStopped) + return NULL; + mQueueCV.wait(lock); + } + + result = mQueue.front(); + mQueue.erase(mQueue.begin()); + } + + // Caller also acquires the reference count + return result; +} + + +void HttpRequestQueue::fetchAll(bool wait, OpContainer & ops) +{ + // Not valid putting something back on the queue... + llassert_always(ops.empty()); + + { + HttpScopedLock lock(mQueueMutex); + + while (mQueue.empty()) + { + if (! wait || mQueueStopped) + return; + mQueueCV.wait(lock); + } + + mQueue.swap(ops); + } + + // Caller also acquires the reference counts on each op. + return; +} + + +void HttpRequestQueue::wakeAll() +{ + mQueueCV.notify_all(); +} + + +void HttpRequestQueue::stopQueue() +{ + { + HttpScopedLock lock(mQueueMutex); + + mQueueStopped = true; + wakeAll(); + } +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httprequestqueue.h b/indra/llcorehttp/_httprequestqueue.h new file mode 100644 index 0000000000..c9c52b7233 --- /dev/null +++ b/indra/llcorehttp/_httprequestqueue.h @@ -0,0 +1,141 @@ +/** + * @file _httprequestqueue.h + * @brief Internal declaration for the operation request queue + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_REQUEST_QUEUE_H_ +#define _LLCORE_HTTP_REQUEST_QUEUE_H_ + + +#include <vector> + +#include "httpcommon.h" +#include "_refcounted.h" +#include "_mutex.h" + + +namespace LLCore +{ + + +class HttpOperation; + + +/// Thread-safe queue of HttpOperation objects. Just +/// a simple queue that handles the transfer of operation +/// requests from all HttpRequest instances into the +/// singleton HttpService instance. + +class HttpRequestQueue : public LLCoreInt::RefCounted +{ +protected: + /// Caller acquires a Refcount on construction + HttpRequestQueue(); + +protected: + virtual ~HttpRequestQueue(); // Use release() + +private: + HttpRequestQueue(const HttpRequestQueue &); // Not defined + void operator=(const HttpRequestQueue &); // Not defined + +public: + static void init(); + static void term(); + + /// Threading: callable by any thread once inited. + inline static HttpRequestQueue * instanceOf() + { + return sInstance; + } + +public: + typedef std::vector<HttpOperation *> OpContainer; + + /// Insert an object at the back of the request queue. + /// + /// Caller must provide one refcount to the queue which takes + /// possession of the count on success. + /// + /// @return Standard status. On failure, caller + /// must dispose of the operation with + /// an explicit release() call. + /// + /// Threading: callable by any thread. + HttpStatus addOp(HttpOperation * op); + + /// Return the operation on the front of the queue. If + /// the queue is empty and @wait is false, call returns + /// immediately and a NULL pointer is returned. If true, + /// caller will sleep until explicitly woken. Wakeups + /// can be spurious and callers must expect NULL pointers + /// even if waiting is indicated. + /// + /// Caller acquires reference count any returned operation + /// + /// Threading: callable by any thread. + HttpOperation * fetchOp(bool wait); + + /// Return all queued requests to caller. The @ops argument + /// should be empty when called and will be swap()'d with + /// current contents. Handling of the @wait argument is + /// identical to @fetchOp. + /// + /// Caller acquires reference count on each returned operation + /// + /// Threading: callable by any thread. + void fetchAll(bool wait, OpContainer & ops); + + /// Wake any sleeping threads. Normal queuing operations + /// won't require this but it may be necessary for termination + /// requests. + /// + /// Threading: callable by any thread. + void wakeAll(); + + /// Disallow further request queuing. Callers to @addOp will + /// get a failure status (LLCORE, HE_SHUTTING_DOWN). Callers + /// to @fetchAll or @fetchOp will get requests that are on the + /// queue but the calls will no longer wait. Instead they'll + /// return immediately. Also wakes up all sleepers to send + /// them on their way. + /// + /// Threading: callable by any thread. + void stopQueue(); + +protected: + static HttpRequestQueue * sInstance; + +protected: + OpContainer mQueue; + LLCoreInt::HttpMutex mQueueMutex; + LLCoreInt::HttpConditionVariable mQueueCV; + bool mQueueStopped; + +}; // end class HttpRequestQueue + +} // end namespace LLCore + + +#endif // _LLCORE_HTTP_REQUEST_QUEUE_H_ diff --git a/indra/llcorehttp/_httpretryqueue.h b/indra/llcorehttp/_httpretryqueue.h new file mode 100644 index 0000000000..745adec09d --- /dev/null +++ b/indra/llcorehttp/_httpretryqueue.h @@ -0,0 +1,94 @@ +/** + * @file _httpretryqueue.h + * @brief Internal declaration for the operation retry queue + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_RETRY_QUEUE_H_ +#define _LLCORE_HTTP_RETRY_QUEUE_H_ + + +#include <queue> + +#include "_httpoprequest.h" + + +namespace LLCore +{ + +/// HttpRetryQueue provides a simple priority queue for HttpOpRequest objects. +/// +/// This uses the priority_queue adaptor class to provide the queue +/// as well as the ordering scheme while allowing us access to the +/// raw container if we follow a few simple rules. One of the more +/// important of those rules is that any iterator becomes invalid +/// on element erasure. So pay attention. +/// +/// Threading: not thread-safe. Expected to be used entirely by +/// a single thread, typically a worker thread of some sort. + +struct HttpOpRetryCompare +{ + bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs) + { + return lhs->mPolicyRetryAt < rhs->mPolicyRetryAt; + } +}; + + +typedef std::priority_queue<HttpOpRequest *, + std::deque<HttpOpRequest *>, + LLCore::HttpOpRetryCompare> HttpRetryQueueBase; + +class HttpRetryQueue : public HttpRetryQueueBase +{ +public: + HttpRetryQueue() + : HttpRetryQueueBase() + {} + + ~HttpRetryQueue() + {} + +protected: + HttpRetryQueue(const HttpRetryQueue &); // Not defined + void operator=(const HttpRetryQueue &); // Not defined + +public: + const container_type & get_container() const + { + return c; + } + + container_type & get_container() + { + return c; + } + +}; // end class HttpRetryQueue + + +} // end namespace LLCore + + +#endif // _LLCORE_HTTP_RETRY_QUEUE_H_ diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp new file mode 100644 index 0000000000..0825888d0f --- /dev/null +++ b/indra/llcorehttp/_httpservice.cpp @@ -0,0 +1,348 @@ +/** + * @file _httpservice.cpp + * @brief Internal definitions of the Http service thread + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_httpservice.h" + +#include <boost/bind.hpp> +#include <boost/function.hpp> + +#include "_httpoperation.h" +#include "_httprequestqueue.h" +#include "_httppolicy.h" +#include "_httplibcurl.h" +#include "_thread.h" +#include "_httpinternal.h" + +#include "lltimer.h" +#include "llthread.h" + + +namespace LLCore +{ + +HttpService * HttpService::sInstance(NULL); +volatile HttpService::EState HttpService::sState(NOT_INITIALIZED); + +HttpService::HttpService() + : mRequestQueue(NULL), + mExitRequested(0U), + mThread(NULL), + mPolicy(NULL), + mTransport(NULL) +{ + // Create the default policy class + HttpPolicyClass pol_class; + pol_class.set(HttpRequest::CP_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT); + pol_class.set(HttpRequest::CP_PER_HOST_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT); + pol_class.set(HttpRequest::CP_ENABLE_PIPELINING, 0L); + mPolicyClasses.push_back(pol_class); +} + + +HttpService::~HttpService() +{ + mExitRequested = 1U; + if (RUNNING == sState) + { + // Trying to kill the service object with a running thread + // is a bit tricky. + if (mRequestQueue) + { + mRequestQueue->stopQueue(); + } + + if (mThread) + { + if (! mThread->timedJoin(250)) + { + // Failed to join, expect problems ahead so do a hard termination. + mThread->cancel(); + + LL_WARNS("CoreHttp") << "Destroying HttpService with running thread. Expect problems." + << LL_ENDL; + } + } + } + + if (mRequestQueue) + { + mRequestQueue->release(); + mRequestQueue = NULL; + } + + delete mTransport; + mTransport = NULL; + + delete mPolicy; + mPolicy = NULL; + + if (mThread) + { + mThread->release(); + mThread = NULL; + } +} + + +void HttpService::init(HttpRequestQueue * queue) +{ + llassert_always(! sInstance); + llassert_always(NOT_INITIALIZED == sState); + sInstance = new HttpService(); + + queue->addRef(); + sInstance->mRequestQueue = queue; + sInstance->mPolicy = new HttpPolicy(sInstance); + sInstance->mTransport = new HttpLibcurl(sInstance); + sState = INITIALIZED; +} + + +void HttpService::term() +{ + if (sInstance) + { + if (RUNNING == sState && sInstance->mThread) + { + // Unclean termination. Thread appears to be running. We'll + // try to give the worker thread a chance to cancel using the + // exit flag... + sInstance->mExitRequested = 1U; + sInstance->mRequestQueue->stopQueue(); + + // And a little sleep + for (int i(0); i < 10 && RUNNING == sState; ++i) + { + ms_sleep(100); + } + } + + delete sInstance; + sInstance = NULL; + } + sState = NOT_INITIALIZED; +} + + +HttpRequest::policy_t HttpService::createPolicyClass() +{ + const HttpRequest::policy_t policy_class(mPolicyClasses.size()); + if (policy_class >= HTTP_POLICY_CLASS_LIMIT) + { + return 0; + } + mPolicyClasses.push_back(HttpPolicyClass()); + return policy_class; +} + + +bool HttpService::isStopped() +{ + // What is really wanted here is something like: + // + // HttpService * service = instanceOf(); + // return STOPPED == sState && (! service || ! service->mThread || ! service->mThread->joinable()); + // + // But boost::thread is not giving me a consistent story on joinability + // of a thread after it returns. Debug and non-debug builds are showing + // different behavior on Linux/Etch so we do a weaker test that may + // not be globally correct (i.e. thread *is* stopping, may not have + // stopped but will very soon): + + return STOPPED == sState; +} + + +/// Threading: callable by consumer thread *once*. +void HttpService::startThread() +{ + llassert_always(! mThread || STOPPED == sState); + llassert_always(INITIALIZED == sState || STOPPED == sState); + + if (mThread) + { + mThread->release(); + } + + // Push current policy definitions, enable policy & transport components + mPolicy->start(mPolicyGlobal, mPolicyClasses); + mTransport->start(mPolicyClasses.size()); + + mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1)); + sState = RUNNING; +} + + +/// Threading: callable by worker thread. +void HttpService::stopRequested() +{ + mExitRequested = 1U; +} + + +/// Threading: callable by worker thread. +bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t priority) +{ + bool found(false); + + // Skip the request queue as we currently don't leave earlier + // requests sitting there. Start with the ready queue... + found = mPolicy->changePriority(handle, priority); + + // If not there, we could try the transport/active queue but priority + // doesn't really have much effect there so we don't waste cycles. + + return found; +} + + +/// Try to find the given request handle on any of the request +/// queues and cancel the operation. +/// +/// @return True if the request was canceled. +/// +/// Threading: callable by worker thread. +bool HttpService::cancel(HttpHandle handle) +{ + bool canceled(false); + + // Request can't be on request queue so skip that. + + // Check the policy component's queues first + canceled = mPolicy->cancel(handle); + + if (! canceled) + { + // If that didn't work, check transport's. + canceled = mTransport->cancel(handle); + } + + return canceled; +} + + +/// Threading: callable by worker thread. +void HttpService::shutdown() +{ + // Disallow future enqueue of requests + mRequestQueue->stopQueue(); + + // Cancel requests already on the request queue + HttpRequestQueue::OpContainer ops; + mRequestQueue->fetchAll(false, ops); + while (! ops.empty()) + { + HttpOperation * op(ops.front()); + ops.erase(ops.begin()); + + op->cancel(); + op->release(); + } + + // Shutdown transport canceling requests, freeing resources + mTransport->shutdown(); + + // And now policy + mPolicy->shutdown(); +} + + +// Working thread loop-forever method. Gives time to +// each of the request queue, policy layer and transport +// layer pieces and then either sleeps for a small time +// or waits for a request to come in. Repeats until +// requested to stop. +void HttpService::threadRun(LLCoreInt::HttpThread * thread) +{ + boost::this_thread::disable_interruption di; + + LLThread::registerThreadID(); + + ELoopSpeed loop(REQUEST_SLEEP); + while (! mExitRequested) + { + loop = processRequestQueue(loop); + + // Process ready queue issuing new requests as needed + ELoopSpeed new_loop = mPolicy->processReadyQueue(); + loop = (std::min)(loop, new_loop); + + // Give libcurl some cycles + new_loop = mTransport->processTransport(); + loop = (std::min)(loop, new_loop); + + // Determine whether to spin, sleep briefly or sleep for next request + if (REQUEST_SLEEP != loop) + { + ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS); + } + } + + shutdown(); + sState = STOPPED; +} + + +HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop) +{ + HttpRequestQueue::OpContainer ops; + const bool wait_for_req(REQUEST_SLEEP == loop); + + mRequestQueue->fetchAll(wait_for_req, ops); + while (! ops.empty()) + { + HttpOperation * op(ops.front()); + ops.erase(ops.begin()); + + // Process operation + if (! mExitRequested) + { + // Setup for subsequent tracing + long tracing(HTTP_TRACE_OFF); + mPolicy->getGlobalOptions().get(HttpRequest::GP_TRACE, &tracing); + op->mTracing = (std::max)(op->mTracing, int(tracing)); + + if (op->mTracing > HTTP_TRACE_OFF) + { + LL_INFOS("CoreHttp") << "TRACE, FromRequestQueue, Handle: " + << static_cast<HttpHandle>(op) + << LL_ENDL; + } + + // Stage + op->stageFromRequest(this); + } + + // Done with operation + op->release(); + } + + // Queue emptied, allow polling loop to sleep + return REQUEST_SLEEP; +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h new file mode 100644 index 0000000000..ffe0349d4d --- /dev/null +++ b/indra/llcorehttp/_httpservice.h @@ -0,0 +1,224 @@ +/** + * @file _httpservice.h + * @brief Declarations for internal class providing HTTP service. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_SERVICE_H_ +#define _LLCORE_HTTP_SERVICE_H_ + + +#include <vector> + +#include "linden_common.h" +#include "llapr.h" +#include "httpcommon.h" +#include "httprequest.h" +#include "_httppolicyglobal.h" +#include "_httppolicyclass.h" + + +namespace LLCoreInt +{ + +class HttpThread; + +} + + +namespace LLCore +{ + + +class HttpRequestQueue; +class HttpPolicy; +class HttpLibcurl; + + +/// The HttpService class does the work behind the request queue. It +/// oversees the HTTP workflow carrying out a number of tasks: +/// - Pulling requests from the global request queue +/// - Executing 'immediate' requests directly +/// - Prioritizing and re-queuing on internal queues the slower requests +/// - Providing cpu cycles to the libcurl plumbing +/// - Overseeing retry operations +/// +/// Note that the service object doesn't have a pointer to any +/// reply queue. These are kept by HttpRequest and HttpOperation +/// only. +/// +/// Service, Policy and Transport +/// +/// HttpService could have been a monolithic class combining a request +/// queue servicer, request policy manager and network transport. +/// Instead, to prevent monolithic growth and allow for easier +/// replacement, it was developed as three separate classes: HttpService, +/// HttpPolicy and HttpLibcurl (transport). These always exist in a +/// 1:1:1 relationship with HttpService managing instances of the other +/// two. So, these classes do not use reference counting to refer +/// to one another, their lifecycles are always managed together. + +class HttpService +{ +protected: + HttpService(); + virtual ~HttpService(); + +private: + HttpService(const HttpService &); // Not defined + void operator=(const HttpService &); // Not defined + +public: + enum EState + { + NOT_INITIALIZED = -1, + INITIALIZED, ///< init() has been called + RUNNING, ///< thread created and running + STOPPED ///< thread has committed to exiting + }; + + // Ordered enumeration of idling strategies available to + // threadRun's loop. Ordered so that std::min on values + // produces the most conservative result of multiple + // requests. + enum ELoopSpeed + { + NORMAL, ///< continuous polling of request, ready, active queues + REQUEST_SLEEP ///< can sleep indefinitely waiting for request queue write + }; + + static void init(HttpRequestQueue *); + static void term(); + + /// Threading: callable by any thread once inited. + inline static HttpService * instanceOf() + { + return sInstance; + } + + /// Return the state of the worker thread. Note that the + /// transition from RUNNING to STOPPED is performed by the + /// worker thread itself. This has two weaknesses: + /// - race where the thread hasn't really stopped but will + /// - data ordering between threads where a non-worker thread + /// may see a stale RUNNING status. + /// + /// This transition is generally of interest only to unit tests + /// and these weaknesses shouldn't be any real burden. + /// + /// Threading: callable by any thread with above exceptions. + static EState getState() + { + return sState; + } + + /// Threading: callable by any thread but uses @see getState() and + /// acquires its weaknesses. + static bool isStopped(); + + /// Threading: callable by consumer thread *once*. + void startThread(); + + /// Threading: callable by worker thread. + void stopRequested(); + + /// Threading: callable by worker thread. + void shutdown(); + + /// Try to find the given request handle on any of the request + /// queues and reset the priority (and queue position) of the + /// request if found. + /// + /// @return True if the request was found somewhere. + /// + /// Threading: callable by worker thread. + bool changePriority(HttpHandle handle, HttpRequest::priority_t priority); + + /// Try to find the given request handle on any of the request + /// queues and cancel the operation. + /// + /// @return True if the request was found and canceled. + /// + /// Threading: callable by worker thread. + bool cancel(HttpHandle handle); + + /// Threading: callable by worker thread. + HttpPolicy & getPolicy() + { + return *mPolicy; + } + + /// Threading: callable by worker thread. + HttpLibcurl & getTransport() + { + return *mTransport; + } + + /// Threading: callable by worker thread. + HttpRequestQueue & getRequestQueue() + { + return *mRequestQueue; + } + + /// Threading: callable by consumer thread. + HttpPolicyGlobal & getGlobalOptions() + { + return mPolicyGlobal; + } + + /// Threading: callable by consumer thread. + HttpRequest::policy_t createPolicyClass(); + + /// Threading: callable by consumer thread. + HttpPolicyClass & getClassOptions(HttpRequest::policy_t policy_class) + { + llassert(policy_class >= 0 && policy_class < mPolicyClasses.size()); + return mPolicyClasses[policy_class]; + } + +protected: + void threadRun(LLCoreInt::HttpThread * thread); + + ELoopSpeed processRequestQueue(ELoopSpeed loop); + +protected: + static HttpService * sInstance; + + // === shared data === + static volatile EState sState; + HttpRequestQueue * mRequestQueue; // Refcounted + LLAtomicU32 mExitRequested; + LLCoreInt::HttpThread * mThread; + + // === consumer-thread-only data === + HttpPolicyGlobal mPolicyGlobal; + std::vector<HttpPolicyClass> mPolicyClasses; + + // === working-thread-only data === + HttpPolicy * mPolicy; // Simple pointer, has ownership + HttpLibcurl * mTransport; // Simple pointer, has ownership +}; // end class HttpService + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_SERVICE_H_ diff --git a/indra/llcorehttp/_mutex.h b/indra/llcorehttp/_mutex.h new file mode 100644 index 0000000000..4be4d016d4 --- /dev/null +++ b/indra/llcorehttp/_mutex.h @@ -0,0 +1,55 @@ +/** + * @file _mutex.hpp + * @brief mutex type abstraction + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LLCOREINT_MUTEX_H_ +#define LLCOREINT_MUTEX_H_ + + +#include <boost/thread.hpp> + + +namespace LLCoreInt +{ + +// MUTEX TYPES + +// unique mutex type +typedef boost::mutex HttpMutex; + +// CONDITION VARIABLES + +// standard condition variable +typedef boost::condition_variable HttpConditionVariable; + +// LOCKS AND FENCES + +// scoped unique lock +typedef boost::unique_lock<HttpMutex> HttpScopedLock; + +} + +#endif // LLCOREINT_MUTEX_H + diff --git a/indra/llcorehttp/_refcounted.cpp b/indra/llcorehttp/_refcounted.cpp new file mode 100644 index 0000000000..e7d0b72741 --- /dev/null +++ b/indra/llcorehttp/_refcounted.cpp @@ -0,0 +1,45 @@ +/** + * @file _refcounted.cpp + * @brief Atomic, thread-safe ref counting and destruction mixin class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "_refcounted.h" + + +namespace LLCoreInt +{ + +#if ! LL_WINDOWS + +const S32 RefCounted::NOT_REF_COUNTED; + +#endif // ! LL_WINDOWS + +RefCounted::~RefCounted() +{} + + +} // end namespace LLCoreInt + + diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h new file mode 100644 index 0000000000..a96c65fb6b --- /dev/null +++ b/indra/llcorehttp/_refcounted.h @@ -0,0 +1,125 @@ +/** + * @file _refcounted.h + * @brief Atomic, thread-safe ref counting and destruction mixin class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LLCOREINT__REFCOUNTED_H_ +#define LLCOREINT__REFCOUNTED_H_ + + +#include "linden_common.h" + +#include <boost/thread.hpp> + +#include "llapr.h" + + +namespace LLCoreInt +{ + + +class RefCounted +{ +private: + RefCounted(); // Not defined - may not be default constructed + void operator=(const RefCounted &); // Not defined + +public: + explicit RefCounted(bool const implicit) + : mRefCount(implicit) + {} + + // ref-count interface + void addRef() const; + void release() const; + bool isLastRef() const; + S32 getRefCount() const; + void noRef() const; + + static const S32 NOT_REF_COUNTED = -1; + +protected: + virtual ~RefCounted(); + virtual void destroySelf(); + +private: + mutable LLAtomicS32 mRefCount; + +}; // end class RefCounted + + +inline void RefCounted::addRef() const +{ + S32 count(mRefCount++); + llassert_always(count >= 0); +} + + +inline void RefCounted::release() const +{ + S32 count(mRefCount); + llassert_always(count != NOT_REF_COUNTED); + llassert_always(count > 0); + count = mRefCount--; + + // clean ourselves up if that was the last reference + if (0 == count) + { + const_cast<RefCounted *>(this)->destroySelf(); + } +} + + +inline bool RefCounted::isLastRef() const +{ + const S32 count(mRefCount); + llassert_always(count != NOT_REF_COUNTED); + llassert_always(count >= 1); + return (1 == count); +} + + +inline S32 RefCounted::getRefCount() const +{ + const S32 result(mRefCount); + return result; +} + + +inline void RefCounted::noRef() const +{ + llassert_always(mRefCount <= 1); + mRefCount = NOT_REF_COUNTED; +} + + +inline void RefCounted::destroySelf() +{ + delete this; +} + +} // end namespace LLCoreInt + +#endif // LLCOREINT__REFCOUNTED_H_ + diff --git a/indra/llcorehttp/_thread.h b/indra/llcorehttp/_thread.h new file mode 100644 index 0000000000..e058d660e5 --- /dev/null +++ b/indra/llcorehttp/_thread.h @@ -0,0 +1,123 @@ +/** + * @file _thread.h + * @brief thread type abstraction + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LLCOREINT_THREAD_H_ +#define LLCOREINT_THREAD_H_ + +#include "linden_common.h" + +#include <boost/thread.hpp> +#include <boost/function.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> + +#include "_refcounted.h" + +namespace LLCoreInt +{ + +class HttpThread : public RefCounted +{ +private: + HttpThread(); // Not defined + void operator=(const HttpThread &); // Not defined + + void at_exit() + { + // the thread function has exited so we need to release our reference + // to ourself so that we will be automagically cleaned up. + release(); + } + + void run() + { // THREAD CONTEXT + + // Take out additional reference for the at_exit handler + addRef(); + boost::this_thread::at_thread_exit(boost::bind(&HttpThread::at_exit, this)); + + // run the thread function + mThreadFunc(this); + + } // THREAD CONTEXT + +protected: + virtual ~HttpThread() + { + delete mThread; + } + +public: + /// Constructs a thread object for concurrent execution but does + /// not start running. Caller receives on refcount on the thread + /// instance. If the thread is started, another will be taken + /// out for the exit handler. + explicit HttpThread(boost::function<void (HttpThread *)> threadFunc) + : RefCounted(true), // implicit reference + mThreadFunc(threadFunc) + { + // this creates a boost thread that will call HttpThread::run on this instance + // and pass it the threadfunc callable... + boost::function<void()> f = boost::bind(&HttpThread::run, this); + + mThread = new boost::thread(f); + } + + inline void join() + { + mThread->join(); + } + + inline bool timedJoin(S32 millis) + { + return mThread->timed_join(boost::posix_time::milliseconds(millis)); + } + + inline bool joinable() const + { + return mThread->joinable(); + } + + // A very hostile method to force a thread to quit + inline void cancel() + { + boost::thread::native_handle_type thread(mThread->native_handle()); +#if LL_WINDOWS + TerminateThread(thread, 0); +#else + pthread_cancel(thread); +#endif + } + +private: + boost::function<void(HttpThread *)> mThreadFunc; + boost::thread * mThread; +}; // end class HttpThread + +} // end namespace LLCoreInt + +#endif // LLCOREINT_THREAD_H_ + + diff --git a/indra/llcorehttp/bufferarray.cpp b/indra/llcorehttp/bufferarray.cpp new file mode 100644 index 0000000000..8eaaeed710 --- /dev/null +++ b/indra/llcorehttp/bufferarray.cpp @@ -0,0 +1,352 @@ +/** + * @file bufferarray.cpp + * @brief Implements the BufferArray scatter/gather buffer + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "bufferarray.h" + + +// BufferArray is a list of chunks, each a BufferArray::Block, of contiguous +// data presented as a single array. Chunks are at least BufferArray::BLOCK_ALLOC_SIZE +// in length and can be larger. Any chunk may be partially filled or even +// empty. +// +// The BufferArray itself is sharable as a RefCounted entity. As shared +// reads don't work with the concept of a current position/seek value, +// none is kept with the object. Instead, the read and write operations +// all take position arguments. Single write/shared read isn't supported +// directly and any such attempts have to be serialized outside of this +// implementation. + +namespace LLCore +{ + + +// ================================== +// BufferArray::Block Declaration +// ================================== + +class BufferArray::Block +{ +public: + ~Block(); + + void operator delete(void *); + void operator delete(void *, size_t len); + +protected: + Block(size_t len); + + Block(const Block &); // Not defined + void operator=(const Block &); // Not defined + + // Allocate the block with the additional space for the + // buffered data at the end of the object. + void * operator new(size_t len, size_t addl_len); + +public: + // Only public entry to get a block. + static Block * alloc(size_t len); + +public: + size_t mUsed; + size_t mAlloced; + + // *NOTE: Must be last member of the object. We'll + // overallocate as requested via operator new and index + // into the array at will. + char mData[1]; +}; + + +// ================================== +// BufferArray Definitions +// ================================== + + +#if ! LL_WINDOWS +const size_t BufferArray::BLOCK_ALLOC_SIZE; +#endif // ! LL_WINDOWS + +BufferArray::BufferArray() + : LLCoreInt::RefCounted(true), + mLen(0) +{} + + +BufferArray::~BufferArray() +{ + for (container_t::iterator it(mBlocks.begin()); + it != mBlocks.end(); + ++it) + { + delete *it; + *it = NULL; + } + mBlocks.clear(); +} + + +size_t BufferArray::append(const void * src, size_t len) +{ + const size_t ret(len); + const char * c_src(static_cast<const char *>(src)); + + // First, try to copy into the last block + if (len && ! mBlocks.empty()) + { + Block & last(*mBlocks.back()); + if (last.mUsed < last.mAlloced) + { + // Some will fit... + const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed))); + + memcpy(&last.mData[last.mUsed], c_src, copy_len); + last.mUsed += copy_len; + llassert_always(last.mUsed <= last.mAlloced); + mLen += copy_len; + c_src += copy_len; + len -= copy_len; + } + } + + // Then get new blocks as needed + while (len) + { + const size_t copy_len((std::min)(len, BLOCK_ALLOC_SIZE)); + + if (mBlocks.size() >= mBlocks.capacity()) + { + mBlocks.reserve(mBlocks.size() + 5); + } + Block * block = Block::alloc(BLOCK_ALLOC_SIZE); + memcpy(block->mData, c_src, copy_len); + block->mUsed = copy_len; + llassert_always(block->mUsed <= block->mAlloced); + mBlocks.push_back(block); + mLen += copy_len; + c_src += copy_len; + len -= copy_len; + } + return ret; +} + + +void * BufferArray::appendBufferAlloc(size_t len) +{ + // If someone asks for zero-length, we give them a valid pointer. + if (mBlocks.size() >= mBlocks.capacity()) + { + mBlocks.reserve(mBlocks.size() + 5); + } + Block * block = Block::alloc((std::max)(BLOCK_ALLOC_SIZE, len)); + block->mUsed = len; + mBlocks.push_back(block); + mLen += len; + return block->mData; +} + + +size_t BufferArray::read(size_t pos, void * dst, size_t len) +{ + char * c_dst(static_cast<char *>(dst)); + + if (pos >= mLen) + return 0; + size_t len_limit(mLen - pos); + len = (std::min)(len, len_limit); + if (0 == len) + return 0; + + size_t result(0), offset(0); + const int block_limit(mBlocks.size()); + int block_start(findBlock(pos, &offset)); + if (block_start < 0) + return 0; + + do + { + Block & block(*mBlocks[block_start]); + size_t block_limit(block.mUsed - offset); + size_t block_len((std::min)(block_limit, len)); + + memcpy(c_dst, &block.mData[offset], block_len); + result += block_len; + len -= block_len; + c_dst += block_len; + offset = 0; + ++block_start; + } + while (len && block_start < block_limit); + + return result; +} + + +size_t BufferArray::write(size_t pos, const void * src, size_t len) +{ + const char * c_src(static_cast<const char *>(src)); + + if (pos > mLen || 0 == len) + return 0; + + size_t result(0), offset(0); + const int block_limit(mBlocks.size()); + int block_start(findBlock(pos, &offset)); + + if (block_start >= 0) + { + // Some or all of the write will be on top of + // existing data. + do + { + Block & block(*mBlocks[block_start]); + size_t block_limit(block.mUsed - offset); + size_t block_len((std::min)(block_limit, len)); + + memcpy(&block.mData[offset], c_src, block_len); + result += block_len; + c_src += block_len; + len -= block_len; + offset = 0; + ++block_start; + } + while (len && block_start < block_limit); + } + + // Something left, see if it will fit in the free + // space of the last block. + if (len && ! mBlocks.empty()) + { + Block & last(*mBlocks.back()); + if (last.mUsed < last.mAlloced) + { + // Some will fit... + const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed))); + + memcpy(&last.mData[last.mUsed], c_src, copy_len); + last.mUsed += copy_len; + result += copy_len; + llassert_always(last.mUsed <= last.mAlloced); + mLen += copy_len; + c_src += copy_len; + len -= copy_len; + } + } + + if (len) + { + // Some or all of the remaining write data will + // be an append. + result += append(c_src, len); + } + + return result; +} + + +int BufferArray::findBlock(size_t pos, size_t * ret_offset) +{ + *ret_offset = 0; + if (pos >= mLen) + return -1; // Doesn't exist + + const int block_limit(mBlocks.size()); + for (int i(0); i < block_limit; ++i) + { + if (pos < mBlocks[i]->mUsed) + { + *ret_offset = pos; + return i; + } + pos -= mBlocks[i]->mUsed; + } + + // Shouldn't get here but... + return -1; +} + + +bool BufferArray::getBlockStartEnd(int block, const char ** start, const char ** end) +{ + if (block < 0 || block >= mBlocks.size()) + { + return false; + } + + const Block & b(*mBlocks[block]); + *start = &b.mData[0]; + *end = &b.mData[b.mUsed]; + return true; +} + + +// ================================== +// BufferArray::Block Definitions +// ================================== + + +BufferArray::Block::Block(size_t len) + : mUsed(0), + mAlloced(len) +{ + memset(mData, 0, len); +} + + +BufferArray::Block::~Block() +{ + mUsed = 0; + mAlloced = 0; +} + + +void * BufferArray::Block::operator new(size_t len, size_t addl_len) +{ + void * mem = new char[len + addl_len + sizeof(void *)]; + return mem; +} + + +void BufferArray::Block::operator delete(void * mem) +{ + char * cmem = static_cast<char *>(mem); + delete [] cmem; +} + + +void BufferArray::Block::operator delete(void * mem, size_t) +{ + operator delete(mem); +} + + +BufferArray::Block * BufferArray::Block::alloc(size_t len) +{ + Block * block = new (len) Block(len); + return block; +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h new file mode 100644 index 0000000000..1094a435b4 --- /dev/null +++ b/indra/llcorehttp/bufferarray.h @@ -0,0 +1,137 @@ +/** + * @file bufferarray.h + * @brief Public-facing declaration for the BufferArray scatter/gather class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_BUFFER_ARRAY_H_ +#define _LLCORE_BUFFER_ARRAY_H_ + + +#include <cstdlib> +#include <vector> + +#include "_refcounted.h" + + +namespace LLCore +{ + +class BufferArrayStreamBuf; + +/// A very simple scatter/gather type map for bulk data. The motivation +/// for this class is the writedata callback used by libcurl. Response +/// bodies are delivered to the caller in a sequence of sequential write +/// operations and this class captures them without having to reallocate +/// and move data. +/// +/// The interface looks a little like a unix file descriptor but only +/// just. There is a notion of a current position, starting from 0, +/// which is used as the position in the data when performing read and +/// write operations. The position also moves after various operations: +/// - seek(...) +/// - read(...) +/// - write(...) +/// - append(...) +/// - appendBufferAlloc(...) +/// The object also keeps a total length value which is updated after +/// write and append operations and beyond which the current position +/// cannot be set. +/// +/// Threading: not thread-safe +/// +/// Allocation: Refcounted, heap only. Caller of the constructor +/// is given a single refcount. +/// +class BufferArray : public LLCoreInt::RefCounted +{ +public: + // BufferArrayStreamBuf has intimate knowledge of this + // implementation to implement a buffer-free adapter. + // Changes here will likely need to be reflected there. + friend class BufferArrayStreamBuf; + + BufferArray(); + +protected: + virtual ~BufferArray(); // Use release() + +private: + BufferArray(const BufferArray &); // Not defined + void operator=(const BufferArray &); // Not defined + +public: + // Internal magic number, may be used by unit tests. + static const size_t BLOCK_ALLOC_SIZE = 65540; + + /// Appends the indicated data to the BufferArray + /// modifying current position and total size. New + /// position is one beyond the final byte of the buffer. + /// + /// @return Count of bytes copied to BufferArray + size_t append(const void * src, size_t len); + + /// Similar to @see append(), this call guarantees a + /// contiguous block of memory of requested size placed + /// at the current end of the BufferArray. On return, + /// the data in the memory is considered valid whether + /// the caller writes to it or not. + /// + /// @return Pointer to contiguous region at end + /// of BufferArray of 'len' size. + void * appendBufferAlloc(size_t len); + + /// Current count of bytes in BufferArray instance. + size_t size() const + { + return mLen; + } + + /// Copies data from the given position in the instance + /// to the caller's buffer. Will return a short count of + /// bytes copied if the 'len' extends beyond the data. + size_t read(size_t pos, void * dst, size_t len); + + /// Copies data from the caller's buffer to the instance + /// at the current position. May overwrite existing data, + /// append data when current position is equal to the + /// size of the instance or do a mix of both. + size_t write(size_t pos, const void * src, size_t len); + +protected: + int findBlock(size_t pos, size_t * ret_offset); + + bool getBlockStartEnd(int block, const char ** start, const char ** end); + +protected: + class Block; + typedef std::vector<Block *> container_t; + + container_t mBlocks; + size_t mLen; +}; // end class BufferArray + + +} // end namespace LLCore + +#endif // _LLCORE_BUFFER_ARRAY_H_ diff --git a/indra/llcorehttp/bufferstream.cpp b/indra/llcorehttp/bufferstream.cpp new file mode 100644 index 0000000000..6553900eef --- /dev/null +++ b/indra/llcorehttp/bufferstream.cpp @@ -0,0 +1,285 @@ +/** + * @file bufferstream.cpp + * @brief Implements the BufferStream adapter class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "bufferstream.h" + +#include "bufferarray.h" + + +namespace LLCore +{ + +BufferArrayStreamBuf::BufferArrayStreamBuf(BufferArray * array) + : mBufferArray(array), + mReadCurPos(0), + mReadCurBlock(-1), + mReadBegin(NULL), + mReadCur(NULL), + mReadEnd(NULL), + mWriteCurPos(0) +{ + if (array) + { + array->addRef(); + mWriteCurPos = array->mLen; + } +} + + +BufferArrayStreamBuf::~BufferArrayStreamBuf() +{ + if (mBufferArray) + { + mBufferArray->release(); + mBufferArray = NULL; + } +} + + +BufferArrayStreamBuf::int_type BufferArrayStreamBuf::underflow() +{ + if (! mBufferArray) + { + return traits_type::eof(); + } + + if (mReadCur == mReadEnd) + { + // Find the next block with actual data or leave + // mCurBlock/mCur/mEnd unchanged if we're at the end + // of any block chain. + const char * new_begin(NULL), * new_end(NULL); + int new_cur_block(mReadCurBlock + 1); + + while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end)) + { + if (new_begin != new_end) + { + break; + } + ++new_cur_block; + } + if (new_begin == new_end) + { + return traits_type::eof(); + } + + mReadCurBlock = new_cur_block; + mReadBegin = mReadCur = new_begin; + mReadEnd = new_end; + } + + return traits_type::to_int_type(*mReadCur); +} + + +BufferArrayStreamBuf::int_type BufferArrayStreamBuf::uflow() +{ + const int_type ret(underflow()); + + if (traits_type::eof() != ret) + { + ++mReadCur; + ++mReadCurPos; + } + return ret; +} + + +BufferArrayStreamBuf::int_type BufferArrayStreamBuf::pbackfail(int_type ch) +{ + if (! mBufferArray) + { + return traits_type::eof(); + } + + if (mReadCur == mReadBegin) + { + // Find the previous block with actual data or leave + // mCurBlock/mBegin/mCur/mEnd unchanged if we're at the + // beginning of any block chain. + const char * new_begin(NULL), * new_end(NULL); + int new_cur_block(mReadCurBlock - 1); + + while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end)) + { + if (new_begin != new_end) + { + break; + } + --new_cur_block; + } + if (new_begin == new_end) + { + return traits_type::eof(); + } + + mReadCurBlock = new_cur_block; + mReadBegin = new_begin; + mReadEnd = mReadCur = new_end; + } + + if (traits_type::eof() != ch && mReadCur[-1] != ch) + { + return traits_type::eof(); + } + --mReadCurPos; + return traits_type::to_int_type(*--mReadCur); +} + + +std::streamsize BufferArrayStreamBuf::showmanyc() +{ + if (! mBufferArray) + { + return -1; + } + return mBufferArray->mLen - mReadCurPos; +} + + +BufferArrayStreamBuf::int_type BufferArrayStreamBuf::overflow(int c) +{ + if (! mBufferArray || mWriteCurPos > mBufferArray->mLen) + { + return traits_type::eof(); + } + const size_t wrote(mBufferArray->write(mWriteCurPos, &c, 1)); + mWriteCurPos += wrote; + return wrote ? c : traits_type::eof(); +} + + +std::streamsize BufferArrayStreamBuf::xsputn(const char * src, std::streamsize count) +{ + if (! mBufferArray || mWriteCurPos > mBufferArray->mLen) + { + return 0; + } + const size_t wrote(mBufferArray->write(mWriteCurPos, src, count)); + mWriteCurPos += wrote; + return wrote; +} + + +std::streampos BufferArrayStreamBuf::seekoff(std::streamoff off, + std::ios_base::seekdir way, + std::ios_base::openmode which) +{ + std::streampos ret(-1); + + if (! mBufferArray) + { + return ret; + } + + if (std::ios_base::in == which) + { + size_t pos(0); + + switch (way) + { + case std::ios_base::beg: + pos = off; + break; + + case std::ios_base::cur: + pos = mReadCurPos += off; + break; + + case std::ios_base::end: + pos = mBufferArray->mLen - off; + break; + + default: + return ret; + } + + if (pos >= mBufferArray->size()) + { + pos = (std::max)(size_t(0), mBufferArray->size() - 1); + } + size_t ba_offset(0); + int block(mBufferArray->findBlock(pos, &ba_offset)); + if (block < 0) + return ret; + const char * start(NULL), * end(NULL); + if (! mBufferArray->getBlockStartEnd(block, &start, &end)) + return ret; + mReadCurBlock = block; + mReadBegin = start; + mReadCur = start + ba_offset; + mReadEnd = end; + ret = mReadCurPos = pos; + } + else if (std::ios_base::out == which) + { + size_t pos(0); + + switch (way) + { + case std::ios_base::beg: + pos = off; + break; + + case std::ios_base::cur: + pos = mWriteCurPos += off; + break; + + case std::ios_base::end: + pos = mBufferArray->mLen - off; + break; + + default: + return ret; + } + + if (pos < 0) + return ret; + if (pos > mBufferArray->size()) + { + pos = mBufferArray->size(); + } + ret = mWriteCurPos = pos; + } + + return ret; +} + + +BufferArrayStream::BufferArrayStream(BufferArray * ba) + : std::iostream(&mStreamBuf), + mStreamBuf(ba) +{} + + +BufferArrayStream::~BufferArrayStream() +{} + + +} // end namespace LLCore + + diff --git a/indra/llcorehttp/bufferstream.h b/indra/llcorehttp/bufferstream.h new file mode 100644 index 0000000000..9327a798aa --- /dev/null +++ b/indra/llcorehttp/bufferstream.h @@ -0,0 +1,153 @@ +/** + * @file bufferstream.h + * @brief Public-facing declaration for the BufferStream adapter class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_BUFFER_STREAM_H_ +#define _LLCORE_BUFFER_STREAM_H_ + + +#include <sstream> +#include <cstdlib> + +#include "bufferarray.h" + + +/// @file bufferstream.h +/// +/// std::streambuf and std::iostream adapters for BufferArray +/// objects. +/// +/// BufferArrayStreamBuf inherits std::streambuf and implements +/// an unbuffered interface for streambuf. This may or may not +/// be the most time efficient implementation and it is a little +/// challenging. +/// +/// BufferArrayStream inherits std::iostream and will be the +/// adapter object most callers will be interested in (though +/// it uses BufferArrayStreamBuf internally). Instances allow +/// for the usual streaming operators ('<<', '>>') and serialization +/// methods. +/// +/// Example of LLSD serialization to a BufferArray: +/// +/// BufferArray * ba = new BufferArray; +/// BufferArrayStream bas(ba); +/// LLSDSerialize::toXML(llsd, bas); +/// operationOnBufferArray(ba); +/// ba->release(); +/// ba = NULL; +/// // operationOnBufferArray and bas are each holding +/// // references to the ba instance at this point. +/// + +namespace LLCore +{ + + +// ===================================================== +// BufferArrayStreamBuf +// ===================================================== + +/// Adapter class to put a std::streambuf interface on a BufferArray +/// +/// Application developers will rarely be interested in anything +/// other than the constructor and even that will rarely be used +/// except indirectly via the @BufferArrayStream class. The +/// choice of interfaces implemented yields a bufferless adapter +/// that doesn't used either the input or output pointer triplets +/// of the more common buffered implementations. This may or may +/// not be faster and that question could stand to be looked at +/// sometime. +/// + +class BufferArrayStreamBuf : public std::streambuf +{ +public: + /// Constructor increments the reference count on the + /// BufferArray argument and calls release() on destruction. + BufferArrayStreamBuf(BufferArray * array); + virtual ~BufferArrayStreamBuf(); + +private: + BufferArrayStreamBuf(const BufferArrayStreamBuf &); // Not defined + void operator=(const BufferArrayStreamBuf &); // Not defined + +public: + // Input interfaces from std::streambuf + int_type underflow(); + int_type uflow(); + int_type pbackfail(int_type ch); + std::streamsize showmanyc(); + + // Output interfaces from std::streambuf + int_type overflow(int c); + std::streamsize xsputn(const char * src, std::streamsize count); + + // Common/misc interfaces from std::streambuf + std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which); + +protected: + BufferArray * mBufferArray; // Ref counted + size_t mReadCurPos; + int mReadCurBlock; + const char * mReadBegin; + const char * mReadCur; + const char * mReadEnd; + size_t mWriteCurPos; + +}; // end class BufferArrayStreamBuf + + +// ===================================================== +// BufferArrayStream +// ===================================================== + +/// Adapter class that supplies streaming operators to BufferArray +/// +/// Provides a streaming adapter to an existing BufferArray +/// instance so that the convenient '<<' and '>>' conversions +/// can be applied to a BufferArray. Very convenient for LLSD +/// serialization and parsing as well. + +class BufferArrayStream : public std::iostream +{ +public: + /// Constructor increments the reference count on the + /// BufferArray argument and calls release() on destruction. + BufferArrayStream(BufferArray * ba); + ~BufferArrayStream(); + +protected: + BufferArrayStream(const BufferArrayStream &); + void operator=(const BufferArrayStream &); + +protected: + BufferArrayStreamBuf mStreamBuf; +}; // end class BufferArrayStream + + +} // end namespace LLCore + +#endif // _LLCORE_BUFFER_STREAM_H_ diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp new file mode 100644 index 0000000000..40ad4f047d --- /dev/null +++ b/indra/llcorehttp/examples/http_texture_load.cpp @@ -0,0 +1,947 @@ +/** + * @file http_texture_load.cpp + * @brief Texture download example for core-http library + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include <iostream> +#include <cstdio> +#include <cstdlib> +#include <set> +#include <map> +#if !defined(WIN32) +#include <pthread.h> +#endif + +#include "linden_common.h" + +#include "httpcommon.h" +#include "httprequest.h" +#include "httphandler.h" +#include "httpresponse.h" +#include "httpheaders.h" +#include "bufferarray.h" +#include "_mutex.h" + +#include <curl/curl.h> +#include <openssl/crypto.h> + +#include "lltimer.h" + + +void init_curl(); +void term_curl(); +unsigned long ssl_thread_id_callback(void); +void ssl_locking_callback(int mode, int type, const char * file, int line); +void usage(std::ostream & out); + +// Default command line settings +static int concurrency_limit(40); +static char url_format[1024] = "http://example.com/some/path?texture_id=%s.texture"; + +#if defined(WIN32) + +#define strncpy(_a, _b, _c) strncpy_s(_a, _b, _c) +#define strtok_r(_a, _b, _c) strtok_s(_a, _b, _c) + +int getopt(int argc, char * const argv[], const char *optstring); +char *optarg(NULL); +int optind(1); + +#endif + + +// Mostly just a container for the texture IDs and fetch +// parameters.... +class WorkingSet : public LLCore::HttpHandler +{ +public: + WorkingSet(); + ~WorkingSet(); + + bool reload(LLCore::HttpRequest *); + + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + + void loadTextureUuids(FILE * in); + +public: + struct Spec + { + std::string mUuid; + int mOffset; + int mLength; + }; + typedef std::set<LLCore::HttpHandle> handle_set_t; + typedef std::vector<Spec> texture_list_t; + +public: + bool mVerbose; + bool mRandomRange; + int mMaxConcurrency; + handle_set_t mHandles; + int mRemaining; + int mLimit; + int mAt; + std::string mUrl; + texture_list_t mTextures; + int mErrorsApi; + int mErrorsHttp; + int mErrorsHttp404; + int mErrorsHttp416; + int mErrorsHttp500; + int mErrorsHttp503; + int mSuccesses; + long mByteCount; + LLCore::HttpHeaders * mHeaders; +}; + + +// Gather process information while we run. Process +// size, cpu consumed, wallclock time. + +class Metrics +{ +public: + class MetricsImpl; + +public: + Metrics(); + ~Metrics(); + + void init(); + void sample(); + void term(); + +protected: + MetricsImpl * mImpl; + +public: + U64 mMaxVSZ; + U64 mMinVSZ; + U64 mStartWallTime; + U64 mEndWallTime; + U64 mStartUTime; + U64 mEndUTime; + U64 mStartSTime; + U64 mEndSTime; +}; + + +// +// +// +int main(int argc, char** argv) +{ + LLCore::HttpStatus status; + bool do_random(false); + bool do_verbose(false); + + int option(-1); + while (-1 != (option = getopt(argc, argv, "u:c:h?Rv"))) + { + switch (option) + { + case 'u': + strncpy(url_format, optarg, sizeof(url_format)); + url_format[sizeof(url_format) - 1] = '\0'; + break; + + case 'c': + { + unsigned long value; + char * end; + + value = strtoul(optarg, &end, 10); + if (value < 1 || value > 100 || *end != '\0') + { + usage(std::cerr); + return 1; + } + concurrency_limit = value; + } + break; + + case 'R': + do_random = true; + break; + + case 'v': + do_verbose = true; + break; + + case 'h': + case '?': + usage(std::cout); + return 0; + } + } + + if ((optind + 1) != argc) + { + usage(std::cerr); + return 1; + } + + FILE * uuids(fopen(argv[optind], "r")); + if (! uuids) + { + const char * errstr(strerror(errno)); + + std::cerr << "Couldn't open UUID file '" << argv[optind] << "'. Reason: " + << errstr << std::endl; + return 1; + } + + // Initialization + init_curl(); + LLCore::HttpRequest::createService(); + LLCore::HttpRequest::setPolicyClassOption(LLCore::HttpRequest::DEFAULT_POLICY_ID, + LLCore::HttpRequest::CP_CONNECTION_LIMIT, + concurrency_limit); + LLCore::HttpRequest::startThread(); + + // Get service point + LLCore::HttpRequest * hr = new LLCore::HttpRequest(); + + // Get a handler/working set + WorkingSet ws; + + // Fill the working set with work + ws.mUrl = url_format; + ws.loadTextureUuids(uuids); + ws.mRandomRange = do_random; + ws.mVerbose = do_verbose; + ws.mMaxConcurrency = 100; + + if (! ws.mTextures.size()) + { + std::cerr << "No UUIDs found in file '" << argv[optind] << "'." << std::endl; + return 1; + } + + // Setup metrics + Metrics metrics; + metrics.init(); + + // Run it + int passes(0); + while (! ws.reload(hr)) + { + hr->update(5000000); + ms_sleep(2); + if (0 == (++passes % 200)) + { + metrics.sample(); + } + } + metrics.sample(); + metrics.term(); + + // Report + std::cout << "HTTP errors: " << ws.mErrorsHttp << " API errors: " << ws.mErrorsApi + << " Successes: " << ws.mSuccesses << " Byte count: " << ws.mByteCount + << std::endl; + std::cout << "HTTP 404 errors: " << ws.mErrorsHttp404 << " HTTP 416 errors: " << ws.mErrorsHttp416 + << " HTTP 500 errors: " << ws.mErrorsHttp500 << " HTTP 503 errors: " << ws.mErrorsHttp503 + << std::endl; + std::cout << "User CPU: " << (metrics.mEndUTime - metrics.mStartUTime) + << " uS System CPU: " << (metrics.mEndSTime - metrics.mStartSTime) + << " uS Wall Time: " << (metrics.mEndWallTime - metrics.mStartWallTime) + << " uS Maximum VSZ: " << metrics.mMaxVSZ + << " Bytes Minimum VSZ: " << metrics.mMinVSZ << " Bytes" + << std::endl; + + // Clean up + hr->requestStopThread(NULL); + ms_sleep(1000); + delete hr; + LLCore::HttpRequest::destroyService(); + term_curl(); + + return 0; +} + + +void usage(std::ostream & out) +{ + out << "\n" + "usage:\thttp_texture_load [options] uuid_file\n" + "\n" + "This is a standalone program to drive the New Platform HTTP Library.\n" + "The program is supplied with a file of texture UUIDs, one per line\n" + "These are fetched sequentially using a pool of concurrent connection\n" + "until all are fetched. The default URL format is only useful from\n" + "within Linden Lab but this can be overriden with a printf-style\n" + "URL formatting string on the command line.\n" + "\n" + "Options:\n" + "\n" + " -u <url_format> printf-style format string for URL generation\n" + " Default: " << url_format << "\n" + " -R Issue GETs with random Range: headers\n" + " -c <limit> Maximum request concurrency. Range: [1..100]\n" + " Default: " << concurrency_limit << "\n" + " -v Verbose mode. Issue some chatter while running\n" + " -h print this help\n" + "\n" + << std::endl; +} + + +WorkingSet::WorkingSet() + : LLCore::HttpHandler(), + mVerbose(false), + mRandomRange(false), + mRemaining(200), + mLimit(200), + mAt(0), + mErrorsApi(0), + mErrorsHttp(0), + mErrorsHttp404(0), + mErrorsHttp416(0), + mErrorsHttp500(0), + mErrorsHttp503(0), + mSuccesses(0), + mByteCount(0L) +{ + mTextures.reserve(30000); + + mHeaders = new LLCore::HttpHeaders; + mHeaders->mHeaders.push_back("Accept: image/x-j2c"); +} + + +WorkingSet::~WorkingSet() +{ + if (mHeaders) + { + mHeaders->release(); + mHeaders = NULL; + } +} + + +bool WorkingSet::reload(LLCore::HttpRequest * hr) +{ + int to_do((std::min)(mRemaining, mMaxConcurrency - int(mHandles.size()))); + + for (int i(0); i < to_do; ++i) + { + char buffer[1024]; +#if defined(WIN32) + _snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, mUrl.c_str(), mTextures[mAt].mUuid.c_str()); +#else + snprintf(buffer, sizeof(buffer), mUrl.c_str(), mTextures[mAt].mUuid.c_str()); +#endif + int offset(mRandomRange ? ((unsigned long) rand()) % 1000000UL : mTextures[mAt].mOffset); + int length(mRandomRange ? ((unsigned long) rand()) % 1000000UL : mTextures[mAt].mLength); + + LLCore::HttpHandle handle; + if (offset || length) + { + handle = hr->requestGetByteRange(0, 0, buffer, offset, length, NULL, mHeaders, this); + } + else + { + handle = hr->requestGet(0, 0, buffer, NULL, mHeaders, this); + } + if (! handle) + { + // Fatal. Couldn't queue up something. + std::cerr << "Failed to queue work to HTTP Service. Reason: " + << hr->getStatus().toString() << std::endl; + exit(1); + } + else + { + mHandles.insert(handle); + } + mAt++; + mRemaining--; + + if (mVerbose) + { + static int count(0); + ++count; + if (0 == (count %5)) + std::cout << "Queued " << count << std::endl; + } + } + + // Are we done? + return (! mRemaining) && mHandles.empty(); +} + + +void WorkingSet::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) +{ + handle_set_t::iterator it(mHandles.find(handle)); + if (mHandles.end() == it) + { + // Wha? + std::cerr << "Failed to find handle in request list. Fatal." << std::endl; + exit(1); + } + else + { + LLCore::HttpStatus status(response->getStatus()); + if (status) + { + // More success + LLCore::BufferArray * data(response->getBody()); + mByteCount += data->size(); + ++mSuccesses; + } + else + { + // Something in this library or libcurl + if (status.isHttpStatus()) + { + static const LLCore::HttpStatus hs404(404); + static const LLCore::HttpStatus hs416(416); + static const LLCore::HttpStatus hs500(500); + static const LLCore::HttpStatus hs503(503); + + ++mErrorsHttp; + if (hs404 == status) + { + ++mErrorsHttp404; + } + else if (hs416 == status) + { + ++mErrorsHttp416; + } + else if (hs500 == status) + { + ++mErrorsHttp500; + } + else if (hs503 == status) + { + ++mErrorsHttp503; + } + } + else + { + ++mErrorsApi; + } + } + mHandles.erase(it); + } + + if (mVerbose) + { + static int count(0); + ++count; + if (0 == (count %5)) + std::cout << "Handled " << count << std::endl; + } +} + + +void WorkingSet::loadTextureUuids(FILE * in) +{ + char buffer[1024]; + + while (fgets(buffer, sizeof(buffer), in)) + { + WorkingSet::Spec texture; + char * state(NULL); + char * token = strtok_r(buffer, " \t\n,", &state); + if (token && 36 == strlen(token)) + { + // Close enough for this function + texture.mUuid = token; + texture.mOffset = 0; + texture.mLength = 0; + token = strtok_r(buffer, " \t\n,", &state); + if (token) + { + int offset(atoi(token)); + token = strtok_r(buffer, " \t\n,", &state); + if (token) + { + int length(atoi(token)); + texture.mOffset = offset; + texture.mLength = length; + } + } + mTextures.push_back(texture); + } + } + mRemaining = mLimit = mTextures.size(); +} + + +int ssl_mutex_count(0); +LLCoreInt::HttpMutex ** ssl_mutex_list = NULL; + +void init_curl() +{ + curl_global_init(CURL_GLOBAL_ALL); + + ssl_mutex_count = CRYPTO_num_locks(); + if (ssl_mutex_count > 0) + { + ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; + + for (int i(0); i < ssl_mutex_count; ++i) + { + ssl_mutex_list[i] = new LLCoreInt::HttpMutex; + } + + CRYPTO_set_locking_callback(ssl_locking_callback); + CRYPTO_set_id_callback(ssl_thread_id_callback); + } +} + + +void term_curl() +{ + CRYPTO_set_locking_callback(NULL); + for (int i(0); i < ssl_mutex_count; ++i) + { + delete ssl_mutex_list[i]; + } + delete [] ssl_mutex_list; +} + + +unsigned long ssl_thread_id_callback(void) +{ +#if defined(WIN32) + return (unsigned long) GetCurrentThread(); +#else + return (unsigned long) pthread_self(); +#endif +} + + +void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */) +{ + if (type >= 0 && type < ssl_mutex_count) + { + if (mode & CRYPTO_LOCK) + { + ssl_mutex_list[type]->lock(); + } + else + { + ssl_mutex_list[type]->unlock(); + } + } +} + + +#if defined(WIN32) + +// Very much a subset of posix functionality. Don't push +// it too hard... +int getopt(int argc, char * const argv[], const char *optstring) +{ + static int pos(0); + while (optind < argc) + { + if (pos == 0) + { + if (argv[optind][0] != '-') + return -1; + pos = 1; + } + if (! argv[optind][pos]) + { + ++optind; + pos = 0; + continue; + } + const char * thing(strchr(optstring, argv[optind][pos])); + if (! thing) + { + ++optind; + return -1; + } + if (thing[1] == ':') + { + optarg = argv[++optind]; + ++optind; + pos = 0; + } + else + { + optarg = NULL; + ++pos; + } + return *thing; + } + return -1; +} + +#endif + + + +#if LL_WINDOWS + +#define PSAPI_VERSION 1 +#include "windows.h" +#include "psapi.h" + +class Metrics::MetricsImpl +{ +public: + MetricsImpl() + {} + + ~MetricsImpl() + {} + + void init(Metrics * metrics) + { + HANDLE self(GetCurrentProcess()); // Does not have to be closed + FILETIME ft_dummy, ft_system, ft_user; + GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user); + ULARGE_INTEGER uli; + uli.u.LowPart = ft_system.dwLowDateTime; + uli.u.HighPart = ft_system.dwHighDateTime; + metrics->mStartSTime = uli.QuadPart / U64L(10); // Convert to uS + uli.u.LowPart = ft_user.dwLowDateTime; + uli.u.HighPart = ft_user.dwHighDateTime; + metrics->mStartUTime = uli.QuadPart / U64L(10); + metrics->mStartWallTime = totalTime(); + } + + void sample(Metrics * metrics) + { + PROCESS_MEMORY_COUNTERS_EX counters; + + GetProcessMemoryInfo(GetCurrentProcess(), + (PROCESS_MEMORY_COUNTERS *) &counters, + sizeof(counters)); + // Okay, PrivateUsage isn't truly VSZ but it will be + // a good tracker for leaks and fragmentation. Work on + // a better estimator later... + SIZE_T vsz(counters.PrivateUsage); + metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, U64(vsz)); + metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, U64(vsz)); + } + + void term(Metrics * metrics) + { + HANDLE self(GetCurrentProcess()); // Does not have to be closed + FILETIME ft_dummy, ft_system, ft_user; + GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user); + ULARGE_INTEGER uli; + uli.u.LowPart = ft_system.dwLowDateTime; + uli.u.HighPart = ft_system.dwHighDateTime; + metrics->mEndSTime = uli.QuadPart / U64L(10); + uli.u.LowPart = ft_user.dwLowDateTime; + uli.u.HighPart = ft_user.dwHighDateTime; + metrics->mEndUTime = uli.QuadPart / U64L(10); + metrics->mEndWallTime = totalTime(); + } + +protected: +}; + +#elif LL_DARWIN + +#include <sys/resource.h> +#include <mach/mach.h> + +class Metrics::MetricsImpl +{ +public: + MetricsImpl() + {} + + ~MetricsImpl() + {} + + void init(Metrics * metrics) + { + U64 utime, stime; + + if (getTimes(&utime, &stime)) + { + metrics->mStartSTime = stime; + metrics->mStartUTime = utime; + } + metrics->mStartWallTime = totalTime(); + sample(metrics); + } + + void sample(Metrics * metrics) + { + U64 vsz; + + if (getVM(&vsz)) + { + metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz); + metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz); + } + } + + void term(Metrics * metrics) + { + U64 utime, stime; + + if (getTimes(&utime, &stime)) + { + metrics->mEndSTime = stime; + metrics->mEndUTime = utime; + } + metrics->mEndWallTime = totalTime(); + } + +protected: + bool getVM(U64 * vsz) + { + task_basic_info task_info_block; + mach_msg_type_number_t task_info_count(TASK_BASIC_INFO_COUNT); + + if (KERN_SUCCESS != task_info(mach_task_self(), + TASK_BASIC_INFO, + (task_info_t) &task_info_block, + &task_info_count)) + { + return false; + } + * vsz = task_info_block.virtual_size; + return true; + } + + bool getTimes(U64 * utime, U64 * stime) + { + struct rusage usage; + + if (getrusage(RUSAGE_SELF, &usage)) + { + return false; + } + * utime = U64(usage.ru_utime.tv_sec) * U64L(1000000) + usage.ru_utime.tv_usec; + * stime = U64(usage.ru_stime.tv_sec) * U64L(1000000) + usage.ru_stime.tv_usec; + return true; + } + +}; + +#else + +class Metrics::MetricsImpl +{ +public: + MetricsImpl() + : mProcFS(NULL), + mUsecsPerTick(U64L(0)) + {} + + + ~MetricsImpl() + { + if (mProcFS) + { + fclose(mProcFS); + mProcFS = NULL; + } + } + + void init(Metrics * metrics) + { + if (! mProcFS) + { + mProcFS = fopen("/proc/self/stat", "r"); + if (! mProcFS) + { + const int errnum(errno); + LL_ERRS("Main") << "Error opening proc fs: " << strerror(errnum) << LL_ENDL; + } + } + + long ticks_per_sec(sysconf(_SC_CLK_TCK)); + mUsecsPerTick = U64L(1000000) / ticks_per_sec; + U64 usecs_per_sec(mUsecsPerTick * ticks_per_sec); + if (900000 > usecs_per_sec || 1100000 < usecs_per_sec) + { + LL_ERRS("Main") << "Resolution problems using uSecs for ticks" << LL_ENDL; + } + + U64 utime, stime; + if (scanProcFS(&utime, &stime, NULL)) + { + metrics->mStartSTime = stime; + metrics->mStartUTime = utime; + } + metrics->mStartWallTime = totalTime(); + + sample(metrics); + } + + + void sample(Metrics * metrics) + { + U64 vsz; + if (scanProcFS(NULL, NULL, &vsz)) + { + metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz); + metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz); + } + } + + + void term(Metrics * metrics) + { + U64 utime, stime; + if (scanProcFS(&utime, &stime, NULL)) + { + metrics->mEndSTime = stime; + metrics->mEndUTime = utime; + } + metrics->mEndWallTime = totalTime(); + + sample(metrics); + + if (mProcFS) + { + fclose(mProcFS); + mProcFS = NULL; + } + } + +protected: + bool scanProcFS(U64 * utime, U64 * stime, U64 * vsz) + { + if (mProcFS) + { + int i_dummy; + unsigned int ui_dummy; + unsigned long ul_dummy, user_ticks, sys_ticks, vsize; + long l_dummy, rss; + unsigned long long ull_dummy; + char c_dummy; + + char buffer[256]; + + static const char * format("%d %*s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld"); + + fseek(mProcFS, 0L, SEEK_SET); + size_t len = fread(buffer, 1, sizeof(buffer) - 1, mProcFS); + if (! len) + { + return false; + } + buffer[len] = '\0'; + if (23 == sscanf(buffer, format, + &i_dummy, // pid + // &s_dummy, // command name + &c_dummy, // state + &i_dummy, // ppid + &i_dummy, // pgrp + &i_dummy, // session + &i_dummy, // terminal + &i_dummy, // terminal group id + &ui_dummy, // flags + &ul_dummy, // minor faults + &ul_dummy, // minor faults in children + &ul_dummy, // major faults + &ul_dummy, // major faults in children + &user_ticks, + &sys_ticks, + &l_dummy, // cutime + &l_dummy, // cstime + &l_dummy, // process priority + &l_dummy, // nice value + &l_dummy, // thread count + &l_dummy, // time to SIGALRM + &ull_dummy, // start time + &vsize, + &rss)) + { + // Looks like we understand the line + if (utime) + { + *utime = user_ticks * mUsecsPerTick; + } + + if (stime) + { + *stime = sys_ticks * mUsecsPerTick; + } + + if (vsz) + { + *vsz = vsize; + } + return true; + } + } + return false; + } + +protected: + FILE * mProcFS; + U64 mUsecsPerTick; + +}; + + +#endif // LL_WINDOWS + +Metrics::Metrics() + : mMaxVSZ(U64(0)), + mMinVSZ(U64L(0xffffffffffffffff)), + mStartWallTime(U64(0)), + mEndWallTime(U64(0)), + mStartUTime(U64(0)), + mEndUTime(U64(0)), + mStartSTime(U64(0)), + mEndSTime(U64(0)) +{ + mImpl = new MetricsImpl(); +} + + +Metrics::~Metrics() +{ + delete mImpl; + mImpl = NULL; +} + + +void Metrics::init() +{ + mImpl->init(this); +} + + +void Metrics::sample() +{ + mImpl->sample(this); +} + + +void Metrics::term() +{ + mImpl->term(this); +} + + diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp new file mode 100644 index 0000000000..f2fcbf77a3 --- /dev/null +++ b/indra/llcorehttp/httpcommon.cpp @@ -0,0 +1,179 @@ +/** + * @file httpcommon.cpp + * @brief + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "httpcommon.h" + +#include <curl/curl.h> +#include <string> +#include <sstream> + + +namespace LLCore +{ + +HttpStatus::type_enum_t EXT_CURL_EASY; +HttpStatus::type_enum_t EXT_CURL_MULTI; +HttpStatus::type_enum_t LLCORE; + +HttpStatus::operator unsigned long() const +{ + static const int shift(sizeof(unsigned long) * 4); + + unsigned long result(((unsigned long) mType) << shift | (unsigned long) (int) mStatus); + return result; +} + + +std::string HttpStatus::toHex() const +{ + std::ostringstream result; + result.width(8); + result.fill('0'); + result << std::hex << operator unsigned long(); + return result.str(); +} + + +std::string HttpStatus::toString() const +{ + static const char * llcore_errors[] = + { + "", + "HTTP error reply status", + "Services shutting down", + "Operation canceled", + "Invalid Content-Range header encountered", + "Request handle not found", + "Invalid datatype for argument or option", + "Option has not been explicitly set", + "Option is not dynamic and must be set early", + "Invalid HTTP status code received from server" + }; + static const int llcore_errors_count(sizeof(llcore_errors) / sizeof(llcore_errors[0])); + + static const struct + { + type_enum_t mCode; + const char * mText; + } + http_errors[] = + { + // Keep sorted by mCode, we binary search this list. + { 100, "Continue" }, + { 101, "Switching Protocols" }, + { 200, "OK" }, + { 201, "Created" }, + { 202, "Accepted" }, + { 203, "Non-Authoritative Information" }, + { 204, "No Content" }, + { 205, "Reset Content" }, + { 206, "Partial Content" }, + { 300, "Multiple Choices" }, + { 301, "Moved Permanently" }, + { 302, "Found" }, + { 303, "See Other" }, + { 304, "Not Modified" }, + { 305, "Use Proxy" }, + { 307, "Temporary Redirect" }, + { 400, "Bad Request" }, + { 401, "Unauthorized" }, + { 402, "Payment Required" }, + { 403, "Forbidden" }, + { 404, "Not Found" }, + { 405, "Method Not Allowed" }, + { 406, "Not Acceptable" }, + { 407, "Proxy Authentication Required" }, + { 408, "Request Time-out" }, + { 409, "Conflict" }, + { 410, "Gone" }, + { 411, "Length Required" }, + { 412, "Precondition Failed" }, + { 413, "Request Entity Too Large" }, + { 414, "Request-URI Too Large" }, + { 415, "Unsupported Media Type" }, + { 416, "Requested range not satisfiable" }, + { 417, "Expectation Failed" }, + { 500, "Internal Server Error" }, + { 501, "Not Implemented" }, + { 502, "Bad Gateway" }, + { 503, "Service Unavailable" }, + { 504, "Gateway Time-out" }, + { 505, "HTTP Version not supported" } + }; + static const int http_errors_count(sizeof(http_errors) / sizeof(http_errors[0])); + + if (*this) + { + return std::string(""); + } + switch (mType) + { + case EXT_CURL_EASY: + return std::string(curl_easy_strerror(CURLcode(mStatus))); + + case EXT_CURL_MULTI: + return std::string(curl_multi_strerror(CURLMcode(mStatus))); + + case LLCORE: + if (mStatus >= 0 && mStatus < llcore_errors_count) + { + return std::string(llcore_errors[mStatus]); + } + break; + + default: + if (isHttpStatus()) + { + // Binary search for the error code and string + int bottom(0), top(http_errors_count); + while (true) + { + int at((bottom + top) / 2); + if (mType == http_errors[at].mCode) + { + return std::string(http_errors[at].mText); + } + if (at == bottom) + { + break; + } + else if (mType < http_errors[at].mCode) + { + top = at; + } + else + { + bottom = at; + } + } + } + break; + } + return std::string("Unknown error"); +} + +} // end namespace LLCore + diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h new file mode 100644 index 0000000000..c0d4ec5aad --- /dev/null +++ b/indra/llcorehttp/httpcommon.h @@ -0,0 +1,311 @@ +/** + * @file httpcommon.h + * @brief Public-facing declarations and definitions of common types + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_COMMON_H_ +#define _LLCORE_HTTP_COMMON_H_ + +/// @package LLCore::HTTP +/// +/// This library implements a high-level, Indra-code-free client interface to +/// HTTP services based on actual patterns found in the viewer and simulator. +/// Interfaces are similar to those supplied by the legacy classes +/// LLCurlRequest and LLHTTPClient. To that is added a policy scheme that +/// allows an application to specify connection behaviors: limits on +/// connections, HTTP keepalive, HTTP pipelining, retry-on-error limits, etc. +/// +/// Features of the library include: +/// - Single, private working thread where all transport and processing occurs. +/// - Support for multiple consumers running in multiple threads. +/// - Scatter/gather (a.k.a. buffer array) model for bulk data movement. +/// - Reference counting used for many object instance lifetimes. +/// - Minimal data sharing across threads for correctness and low latency. +/// +/// The public interface is declared in a few key header files: +/// - "llcorehttp/bufferarray.h" +/// - "llcorehttp/httpcommon.h" +/// - "llcorehttp/httphandler.h" +/// - "llcorehttp/httpheaders.h" +/// - "llcorehttp/httpoptions.h" +/// - "llcorehttp/httprequest.h" +/// - "llcorehttp/httpresponse.h" +/// +/// The library is still under early development and particular users +/// may need access to internal implementation details that are found +/// in the _*.h header files. But this is a crutch to be avoided if at +/// all possible and probably indicates some interface work is neeeded. +/// +/// Using the library is fairly easy. Global setup needs a few +/// steps: +/// +/// - libcurl initialization including thread-safely callbacks for SSL: +/// . curl_global_init(...) +/// . CRYPTO_set_locking_callback(...) +/// . CRYPTO_set_id_callback(...) +/// - HttpRequest::createService() called to instantiate singletons +/// and support objects. +/// +/// An HTTP consumer in an application, and an application may have many +/// consumers, does a few things: +/// +/// - Instantiate and retain an object based on HttpRequest. This +/// object becomes the portal into runtime services for the consumer. +/// - Derive or mixin the HttpHandler class if you want notification +/// when requests succeed or fail. This object's onCompleted() +/// method is invoked and an instance can be shared across +/// requests. +/// +/// Issuing a request is straightforward: +/// - Construct a suitable URL. +/// - Configure HTTP options for the request. (optional) +/// - Build a list of additional headers. (optional) +/// - Invoke one of the requestXXXX() methods (requestGetByteRange, +/// requestPost, etc.) on the HttpRequest instance supplying the +/// above along with a policy class, a priority and an optional +/// pointer to an HttpHandler instance. Work is then queued to +/// the worker thread and occurs asynchronously. +/// - Periodically invoke the update() method on the HttpRequest +/// instance which performs completion notification to HttpHandler +/// objects. +/// - Do completion processing in your onCompletion() method. +/// +/// Code fragments: +/// Rather than a poorly-maintained example in comments, look in the +/// example subdirectory which is a minimal yet functional tool to do +/// GET request performance testing. With four calls: +/// +/// init_curl(); +/// LLCore::HttpRequest::createService(); +/// LLCore::HttpRequest::startThread(); +/// LLCore::HttpRequest * hr = new LLCore::HttpRequest(); +/// +/// the program is basically ready to issue requests. +/// + + +#include "linden_common.h" // Modifies curl/curl.h interfaces + +#include <string> + + +namespace LLCore +{ + + +/// All queued requests are represented by an HttpHandle value. +/// The invalid value is returned when a request failed to queue. +/// The actual status for these failures is then fetched with +/// HttpRequest::getStatus(). +/// +/// The handle is valid only for the life of a request. On +/// return from any HttpHandler notification, the handle immediately +/// becomes invalid and may be recycled for other queued requests. + +typedef void * HttpHandle; +#define LLCORE_HTTP_HANDLE_INVALID (NULL) + +/// For internal scheduling and metrics, we use a microsecond +/// timebase compatible with the environment. +typedef U64 HttpTime; + +/// Error codes defined by the library itself as distinct from +/// libcurl (or any other transport provider). +enum HttpError +{ + // Successful value compatible with the libcurl codes. + HE_SUCCESS = 0, + + // Intended for HTTP reply codes 100-999, indicates that + // the reply should be considered an error by the application. + HE_REPLY_ERROR = 1, + + // Service is shutting down and requested operation will + // not be queued or performed. + HE_SHUTTING_DOWN = 2, + + // Operation was canceled by request. + HE_OP_CANCELED = 3, + + // Invalid content range header received. + HE_INV_CONTENT_RANGE_HDR = 4, + + // Request handle not found + HE_HANDLE_NOT_FOUND = 5, + + // Invalid datatype for option/setting + HE_INVALID_ARG = 6, + + // Option hasn't been explicitly set + HE_OPT_NOT_SET = 7, + + // Option not dynamic, must be set during init phase + HE_OPT_NOT_DYNAMIC = 8, + + // Invalid HTTP status code returned by server + HE_INVALID_HTTP_STATUS = 9 + +}; // end enum HttpError + + +/// HttpStatus encapsulates errors from libcurl (easy, multi), HTTP +/// reply status codes and internal errors as well. The encapsulation +/// isn't expected to completely isolate the caller from libcurl but +/// basic operational tests (success or failure) are provided. +/// +/// Non-HTTP status are encoded as (type, status) with type being +/// one of: EXT_CURL_EASY, EXT_CURL_MULTI or LLCORE and status +/// being the success/error code from that domain. HTTP status +/// is encoded as (status, error_flag). Status should be in the +/// range [100, 999] and error_flag is either HE_SUCCESS or +/// HE_REPLY_ERROR to indicate whether this should be treated as +/// a successful status or an error. The application is responsible +/// for making that determination and a range like [200, 299] isn't +/// automatically assumed to be definitive. +/// +/// Examples: +/// +/// 1. Construct a default, successful status code: +/// HttpStatus(); +/// +/// 2. Construct a successful, HTTP 200 status code: +/// HttpStatus(200); +/// +/// 3. Construct a failed, HTTP 404 not-found status code: +/// HttpStatus(404); +/// +/// 4. Construct a failed libcurl couldn't connect status code: +/// HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); +/// +/// 5. Construct an HTTP 301 status code to be treated as success: +/// HttpStatus(301, HE_SUCCESS); +/// + +struct HttpStatus +{ + typedef unsigned short type_enum_t; + + HttpStatus() + : mType(LLCORE), + mStatus(HE_SUCCESS) + {} + + HttpStatus(type_enum_t type, short status) + : mType(type), + mStatus(status) + {} + + HttpStatus(int http_status) + : mType(http_status), + mStatus(http_status >= 200 && http_status <= 299 + ? HE_SUCCESS + : HE_REPLY_ERROR) + { + llassert(http_status >= 100 && http_status <= 999); + } + + HttpStatus(const HttpStatus & rhs) + : mType(rhs.mType), + mStatus(rhs.mStatus) + {} + + HttpStatus & operator=(const HttpStatus & rhs) + { + // Don't care if lhs & rhs are the same object + + mType = rhs.mType; + mStatus = rhs.mStatus; + return *this; + } + + static const type_enum_t EXT_CURL_EASY = 0; + static const type_enum_t EXT_CURL_MULTI = 1; + static const type_enum_t LLCORE = 2; + + type_enum_t mType; + short mStatus; + + /// Test for successful status in the code regardless + /// of error source (internal, libcurl). + /// + /// @return 'true' when status is successful. + /// + operator bool() const + { + return 0 == mStatus; + } + + /// Inverse of previous operator. + /// + /// @return 'true' on any error condition + bool operator !() const + { + return 0 != mStatus; + } + + /// Equality and inequality tests to bypass bool conversion + /// which will do the wrong thing in conditional expressions. + bool operator==(const HttpStatus & rhs) const + { + return mType == rhs.mType && mStatus == rhs.mStatus; + } + + bool operator!=(const HttpStatus & rhs) const + { + return ! operator==(rhs); + } + + /// Convert to single numeric representation. Mainly + /// for logging or other informal purposes. Also + /// creates an ambiguous second path to integer conversion + /// which tends to find programming errors such as formatting + /// the status to a stream (operator<<). + operator unsigned long() const; + unsigned long toULong() const + { + return operator unsigned long(); + } + + /// And to convert to a hex string. + std::string toHex() const; + + /// Convert status to a string representation. For + /// success, returns an empty string. For failure + /// statuses, a string as appropriate for the source of + /// the error code (libcurl easy, libcurl multi, or + /// LLCore itself). + std::string toString() const; + + /// Returns true if the status value represents an + /// HTTP response status (100 - 999). + bool isHttpStatus() const + { + return mType >= type_enum_t(100) && mType <= type_enum_t(999); + } + +}; // end struct HttpStatus + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_COMMON_H_ diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h new file mode 100644 index 0000000000..9171e4e7b9 --- /dev/null +++ b/indra/llcorehttp/httphandler.h @@ -0,0 +1,88 @@ +/** + * @file httphandler.h + * @brief Public-facing declarations for the HttpHandler class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_HANDLER_H_ +#define _LLCORE_HTTP_HANDLER_H_ + + +#include "httpcommon.h" + + +namespace LLCore +{ + +class HttpResponse; + + +/// HttpHandler defines an interface used by the library to +/// notify library callers of significant events, currently +/// request completion. Callers must derive or mixin this class +/// then provide an implementation of the @see onCompleted +/// method to receive such notifications. An instance may +/// be shared by any number of requests and across instances +/// of HttpRequest running in the same thread. +/// +/// Threading: HttpHandler itself is pure interface and is +/// tread-compatible. Most derivations, however, will have +/// different constraints. +/// +/// Allocation: Not refcounted, may be stack allocated though +/// that is rarely a good idea. Queued requests and replies keep +/// a naked pointer to the handler and this can result in a +/// dangling pointer if lifetimes aren't managed correctly. + +class HttpHandler +{ +public: + virtual ~HttpHandler() + {} + + /// Method invoked during calls to @see update(). Each invocation + /// represents the completion of some requested operation. Caller + /// can identify the request from the handle and interrogate the + /// response argument for success/failure, data and other information. + /// + /// @param handle Identifier of the request generating + /// the notification. + /// @param response Supplies detailed information about + /// the request including status codes + /// (both programming and HTTP), HTTP body + /// data and encodings, headers, etc. + /// The response object is refcounted and + /// the called code may retain the object + /// by invoking @see addRef() on it. The + /// library itself drops all references to + /// to object on return and never touches + /// it again. + /// + virtual void onCompleted(HttpHandle handle, HttpResponse * response) = 0; + +}; // end class HttpHandler + + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_HANDLER_H_ diff --git a/indra/llcorehttp/httpheaders.cpp b/indra/llcorehttp/httpheaders.cpp new file mode 100644 index 0000000000..2832696271 --- /dev/null +++ b/indra/llcorehttp/httpheaders.cpp @@ -0,0 +1,44 @@ +/** + * @file httpheaders.cpp + * @brief Implementation of the HTTPHeaders class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "httpheaders.h" + + +namespace LLCore +{ + + +HttpHeaders::HttpHeaders() + : RefCounted(true) +{} + + +HttpHeaders::~HttpHeaders() +{} + + +} // end namespace LLCore + diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h new file mode 100644 index 0000000000..3449daa3a1 --- /dev/null +++ b/indra/llcorehttp/httpheaders.h @@ -0,0 +1,87 @@ +/** + * @file httpheaders.h + * @brief Public-facing declarations for the HttpHeaders class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_HEADERS_H_ +#define _LLCORE_HTTP_HEADERS_H_ + + +#include <string> + +#include "_refcounted.h" + + +namespace LLCore +{ + +/// +/// Maintains an ordered list of name/value pairs representing +/// HTTP header lines. This is used both to provide additional +/// headers when making HTTP requests and in responses when the +/// caller has asked that headers be returned (not the default +/// option). +/// +/// @note +/// This is a minimally-functional placeholder at the moment +/// to fill out the class hierarchy. The final class will be +/// something else, probably more pair-oriented. It's also +/// an area where shared values are desirable so refcounting is +/// already specced and a copy-on-write scheme imagined. +/// Expect changes here. +/// +/// Threading: Not intrinsically thread-safe. It *is* expected +/// that callers will build these objects and then share them +/// via reference counting with the worker thread. The implication +/// is that once an HttpHeader instance is handed to a request, +/// the object must be treated as read-only. +/// +/// Allocation: Refcounted, heap only. Caller of the +/// constructor is given a refcount. +/// + +class HttpHeaders : public LLCoreInt::RefCounted +{ +public: + /// @post In addition to the instance, caller has a refcount + /// to the instance. A call to @see release() will destroy + /// the instance. + HttpHeaders(); + +protected: + virtual ~HttpHeaders(); // Use release() + + HttpHeaders(const HttpHeaders &); // Not defined + void operator=(const HttpHeaders &); // Not defined + +public: + typedef std::vector<std::string> container_t; + container_t mHeaders; + +}; // end class HttpHeaders + +} // end namespace LLCore + + +#endif // _LLCORE_HTTP_HEADERS_H_ diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp new file mode 100644 index 0000000000..1699d19f8d --- /dev/null +++ b/indra/llcorehttp/httpoptions.cpp @@ -0,0 +1,73 @@ +/** + * @file httpoptions.cpp + * @brief Implementation of the HTTPOptions class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "httpoptions.h" + +#include "_httpinternal.h" + + +namespace LLCore +{ + + +HttpOptions::HttpOptions() + : RefCounted(true), + mWantHeaders(false), + mTracing(HTTP_TRACE_OFF), + mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT), + mRetries(HTTP_RETRY_COUNT_DEFAULT) +{} + + +HttpOptions::~HttpOptions() +{} + + +void HttpOptions::setWantHeaders(bool wanted) +{ + mWantHeaders = wanted; +} + + +void HttpOptions::setTrace(long level) +{ + mTracing = int(level); +} + + +void HttpOptions::setTimeout(unsigned int timeout) +{ + mTimeout = timeout; +} + + +void HttpOptions::setRetries(unsigned int retries) +{ + mRetries = retries; +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h new file mode 100644 index 0000000000..97e46a8cd3 --- /dev/null +++ b/indra/llcorehttp/httpoptions.h @@ -0,0 +1,106 @@ +/** + * @file httpoptions.h + * @brief Public-facing declarations for the HTTPOptions class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_OPTIONS_H_ +#define _LLCORE_HTTP_OPTIONS_H_ + + +#include "httpcommon.h" + +#include "_refcounted.h" + + +namespace LLCore +{ + + +/// Really a struct in spirit, it provides options that +/// modify HTTP requests. +/// +/// Sharing instances across requests. It's intended that +/// these be shared across requests: caller can create one +/// of these, set it up as needed and then reference it +/// repeatedly in HTTP operations. But see the Threading +/// note about references. +/// +/// Threading: While this class does nothing to ensure thread +/// safety, it *is* intended to be shared between the application +/// thread and the worker thread. This means that once an instance +/// is delivered to the library in request operations, the +/// option data must not be written until all such requests +/// complete and relinquish their references. +/// +/// Allocation: Refcounted, heap only. Caller of the constructor +/// is given a refcount. +/// +class HttpOptions : public LLCoreInt::RefCounted +{ +public: + HttpOptions(); + +protected: + virtual ~HttpOptions(); // Use release() + + HttpOptions(const HttpOptions &); // Not defined + void operator=(const HttpOptions &); // Not defined + +public: + void setWantHeaders(bool wanted); + bool getWantHeaders() const + { + return mWantHeaders; + } + + void setTrace(int long); + int getTrace() const + { + return mTracing; + } + + void setTimeout(unsigned int timeout); + unsigned int getTimeout() const + { + return mTimeout; + } + + void setRetries(unsigned int retries); + unsigned int getRetries() const + { + return mRetries; + } + +protected: + bool mWantHeaders; + int mTracing; + unsigned int mTimeout; + unsigned int mRetries; + +}; // end class HttpOptions + + +} // end namespace HttpOptions + +#endif // _LLCORE_HTTP_OPTIONS_H_ diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp new file mode 100644 index 0000000000..9b739a8825 --- /dev/null +++ b/indra/llcorehttp/httprequest.cpp @@ -0,0 +1,504 @@ +/** + * @file httprequest.cpp + * @brief Implementation of the HTTPRequest class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "httprequest.h" + +#include "_httprequestqueue.h" +#include "_httpreplyqueue.h" +#include "_httpservice.h" +#include "_httppolicy.h" +#include "_httpoperation.h" +#include "_httpoprequest.h" +#include "_httpopsetpriority.h" +#include "_httpopcancel.h" +#include "_httpopsetget.h" + +#include "lltimer.h" + + +namespace +{ + +bool has_inited(false); + +} + +namespace LLCore +{ + +// ==================================== +// HttpRequest Implementation +// ==================================== + + +HttpRequest::policy_t HttpRequest::sNextPolicyID(1); + + +HttpRequest::HttpRequest() + : //HttpHandler(), + mReplyQueue(NULL), + mRequestQueue(NULL) +{ + mRequestQueue = HttpRequestQueue::instanceOf(); + mRequestQueue->addRef(); + + mReplyQueue = new HttpReplyQueue(); +} + + +HttpRequest::~HttpRequest() +{ + if (mRequestQueue) + { + mRequestQueue->release(); + mRequestQueue = NULL; + } + + if (mReplyQueue) + { + mReplyQueue->release(); + mReplyQueue = NULL; + } +} + + +// ==================================== +// Policy Methods +// ==================================== + + +HttpStatus HttpRequest::setPolicyGlobalOption(EGlobalPolicy opt, long value) +{ + if (HttpService::RUNNING == HttpService::instanceOf()->getState()) + { + return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC); + } + return HttpService::instanceOf()->getGlobalOptions().set(opt, value); +} + + +HttpStatus HttpRequest::setPolicyGlobalOption(EGlobalPolicy opt, const std::string & value) +{ + if (HttpService::RUNNING == HttpService::instanceOf()->getState()) + { + return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC); + } + return HttpService::instanceOf()->getGlobalOptions().set(opt, value); +} + + +HttpRequest::policy_t HttpRequest::createPolicyClass() +{ + if (HttpService::RUNNING == HttpService::instanceOf()->getState()) + { + return 0; + } + return HttpService::instanceOf()->createPolicyClass(); +} + + +HttpStatus HttpRequest::setPolicyClassOption(policy_t policy_id, + EClassPolicy opt, + long value) +{ + if (HttpService::RUNNING == HttpService::instanceOf()->getState()) + { + return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC); + } + return HttpService::instanceOf()->getClassOptions(policy_id).set(opt, value); +} + + +// ==================================== +// Request Methods +// ==================================== + + +HttpStatus HttpRequest::getStatus() const +{ + return mLastReqStatus; +} + + +HttpHandle HttpRequest::requestGet(policy_t policy_id, + priority_t priority, + const std::string & url, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * user_handler) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpRequest * op = new HttpOpRequest(); + if (! (status = op->setupGet(policy_id, priority, url, options, headers))) + { + op->release(); + mLastReqStatus = status; + return handle; + } + op->setReplyPath(mReplyQueue, user_handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + + +HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id, + priority_t priority, + const std::string & url, + size_t offset, + size_t len, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * user_handler) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpRequest * op = new HttpOpRequest(); + if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers))) + { + op->release(); + mLastReqStatus = status; + return handle; + } + op->setReplyPath(mReplyQueue, user_handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + + +HttpHandle HttpRequest::requestPost(policy_t policy_id, + priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * user_handler) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpRequest * op = new HttpOpRequest(); + if (! (status = op->setupPost(policy_id, priority, url, body, options, headers))) + { + op->release(); + mLastReqStatus = status; + return handle; + } + op->setReplyPath(mReplyQueue, user_handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + + +HttpHandle HttpRequest::requestPut(policy_t policy_id, + priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * user_handler) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpRequest * op = new HttpOpRequest(); + if (! (status = op->setupPut(policy_id, priority, url, body, options, headers))) + { + op->release(); + mLastReqStatus = status; + return handle; + } + op->setReplyPath(mReplyQueue, user_handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + + +HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpNull * op = new HttpOpNull(); + op->setReplyPath(mReplyQueue, user_handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + + +HttpStatus HttpRequest::update(long usecs) +{ + HttpOperation * op(NULL); + + if (usecs) + { + const HttpTime limit(totalTime() + HttpTime(usecs)); + while (limit >= totalTime() && (op = mReplyQueue->fetchOp())) + { + // Process operation + op->visitNotifier(this); + + // We're done with the operation + op->release(); + } + } + else + { + // Same as above, just no time limit + HttpReplyQueue::OpContainer replies; + mReplyQueue->fetchAll(replies); + if (! replies.empty()) + { + for (HttpReplyQueue::OpContainer::iterator iter(replies.begin()); + replies.end() != iter; + ++iter) + { + // Swap op pointer for NULL; + op = *iter; *iter = NULL; + + // Process operation + op->visitNotifier(this); + + // We're done with the operation + op->release(); + } + } + } + + return HttpStatus(); +} + + + + +// ==================================== +// Request Management Methods +// ==================================== + +HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler * user_handler) +{ + HttpStatus status; + HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpCancel * op = new HttpOpCancel(request); + op->setReplyPath(mReplyQueue, user_handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return ret_handle; + } + + mLastReqStatus = status; + ret_handle = static_cast<HttpHandle>(op); + + return ret_handle; +} + + +HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority, + HttpHandler * handler) +{ + HttpStatus status; + HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpSetPriority * op = new HttpOpSetPriority(request, priority); + op->setReplyPath(mReplyQueue, handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return ret_handle; + } + + mLastReqStatus = status; + ret_handle = static_cast<HttpHandle>(op); + + return ret_handle; +} + + +// ==================================== +// Utility Methods +// ==================================== + +HttpStatus HttpRequest::createService() +{ + HttpStatus status; + + if (! has_inited) + { + HttpRequestQueue::init(); + HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); + HttpService::init(rq); + has_inited = true; + } + + return status; +} + + +HttpStatus HttpRequest::destroyService() +{ + HttpStatus status; + + if (has_inited) + { + HttpService::term(); + HttpRequestQueue::term(); + has_inited = false; + } + + return status; +} + + +HttpStatus HttpRequest::startThread() +{ + HttpStatus status; + + HttpService::instanceOf()->startThread(); + + return status; +} + + +HttpHandle HttpRequest::requestStopThread(HttpHandler * user_handler) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpStop * op = new HttpOpStop(); + op->setReplyPath(mReplyQueue, user_handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + + +HttpHandle HttpRequest::requestSpin(int mode) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpSpin * op = new HttpOpSpin(mode); + op->setReplyPath(mReplyQueue, NULL); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + +// ==================================== +// Dynamic Policy Methods +// ==================================== + +HttpHandle HttpRequest::requestSetHttpProxy(const std::string & proxy, HttpHandler * handler) +{ + HttpStatus status; + HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + + HttpOpSetGet * op = new HttpOpSetGet(); + op->setupSet(GP_HTTP_PROXY, proxy); + op->setReplyPath(mReplyQueue, handler); + if (! (status = mRequestQueue->addOp(op))) // transfers refcount + { + op->release(); + mLastReqStatus = status; + return handle; + } + + mLastReqStatus = status; + handle = static_cast<HttpHandle>(op); + + return handle; +} + + +} // end namespace LLCore + diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h new file mode 100644 index 0000000000..ab2f302d34 --- /dev/null +++ b/indra/llcorehttp/httprequest.h @@ -0,0 +1,535 @@ +/** + * @file httprequest.h + * @brief Public-facing declarations for HttpRequest class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_REQUEST_H_ +#define _LLCORE_HTTP_REQUEST_H_ + + +#include "httpcommon.h" +#include "httphandler.h" + + +namespace LLCore +{ + +class HttpRequestQueue; +class HttpReplyQueue; +class HttpService; +class HttpOptions; +class HttpHeaders; +class HttpOperation; +class BufferArray; + +/// HttpRequest supplies the entry into the HTTP transport +/// services in the LLCore libraries. Services provided include: +/// +/// - Some, but not all, global initialization of libcurl. +/// - Starting asynchronous, threaded HTTP requests. +/// - Definition of policy classes affect request handling. +/// - Utilities to control request options and headers +/// +/// Requests +/// +/// The class supports the current HTTP request operations: +/// +/// - requestGetByteRange: GET with Range header for a single range of bytes +/// +/// Policy Classes +/// +/// <TBD> +/// +/// Usage +/// +/// <TBD> +/// +/// Threading: An instance may only be used by one application/ +/// consumer thread. But a thread may have as many instances of +/// this as it likes. +/// +/// Allocation: Not refcounted, may be stack allocated though that +/// hasn't been tested. Queued requests can still run and any +/// queued replies will keep refcounts to the reply queue leading +/// to memory leaks. +/// +/// @pre Before using this class (static or instances), some global +/// initialization is required. See @see httpcommon.h for more information. +/// +/// @nosubgrouping +/// + +class HttpRequest +{ +public: + HttpRequest(); + virtual ~HttpRequest(); + +private: + HttpRequest(const HttpRequest &); // Disallowed + void operator=(const HttpRequest &); // Disallowed + +public: + typedef unsigned int policy_t; + typedef unsigned int priority_t; + +public: + /// @name PolicyMethods + /// @{ + + /// Represents a default, catch-all policy class that guarantees + /// eventual service for any HTTP request. + static const int DEFAULT_POLICY_ID = 0; + + enum EGlobalPolicy + { + /// Maximum number of connections the library will use to + /// perform operations. This is somewhat soft as the underlying + /// transport will cache some connections (up to 5). + + /// A long value setting the maximum number of connections + /// allowed over all policy classes. Note that this will be + /// a somewhat soft value. There may be an additional five + /// connections per policy class depending upon runtime + /// behavior. + GP_CONNECTION_LIMIT, + + /// String containing a system-appropriate directory name + /// where SSL certs are stored. + GP_CA_PATH, + + /// String giving a full path to a file containing SSL certs. + GP_CA_FILE, + + /// String of host/port to use as simple HTTP proxy. This is + /// going to change in the future into something more elaborate + /// that may support richer schemes. + GP_HTTP_PROXY, + + /// Long value that if non-zero enables the use of the + /// traditional LLProxy code for http/socks5 support. If + /// enabled, has priority over GP_HTTP_PROXY. + GP_LLPROXY, + + /// Long value setting the logging trace level for the + /// library. Possible values are: + /// 0 - No tracing (default) + /// 1 - Basic tracing of request start, stop and major events. + /// 2 - Connection, header and payload size information from + /// HTTP transactions. + /// 3 - Partial logging of payload itself. + /// + /// These values are also used in the trace modes for + /// individual requests in HttpOptions. Also be aware that + /// tracing tends to impact performance of the viewer. + GP_TRACE + }; + + /// Set a parameter on a global policy option. Calls + /// made after the start of the servicing thread are + /// not honored and return an error status. + /// + /// @param opt Enum of option to be set. + /// @param value Desired value of option. + /// @return Standard status code. + static HttpStatus setPolicyGlobalOption(EGlobalPolicy opt, long value); + static HttpStatus setPolicyGlobalOption(EGlobalPolicy opt, const std::string & value); + + /// Create a new policy class into which requests can be made. + /// + /// @return If positive, the policy_id used to reference + /// the class in other methods. If 0, an error + /// occurred and @see getStatus() may provide more + /// detail on the reason. + static policy_t createPolicyClass(); + + enum EClassPolicy + { + /// Limits the number of connections used for the class. + CP_CONNECTION_LIMIT, + + /// Limits the number of connections used for a single + /// literal address/port pair within the class. + CP_PER_HOST_CONNECTION_LIMIT, + + /// Suitable requests are allowed to pipeline on their + /// connections when they ask for it. + CP_ENABLE_PIPELINING + }; + + /// Set a parameter on a class-based policy option. Calls + /// made after the start of the servicing thread are + /// not honored and return an error status. + /// + /// @param policy_id ID of class as returned by @see createPolicyClass(). + /// @param opt Enum of option to be set. + /// @param value Desired value of option. + /// @return Standard status code. + static HttpStatus setPolicyClassOption(policy_t policy_id, EClassPolicy opt, long value); + + /// @} + + /// @name RequestMethods + /// + /// @{ + + /// Some calls expect to succeed as the normal part of operation and so + /// return a useful value rather than a status. When they do fail, the + /// status is saved and can be fetched with this method. + /// + /// @return Status of the failing method invocation. If the + /// preceding call succeeded or other HttpStatus + /// returning calls immediately preceded this method, + /// the returned value may not be reliable. + /// + HttpStatus getStatus() const; + + /// Queue a full HTTP GET request to be issued for entire entity. + /// The request is queued and serviced by the working thread and + /// notification of completion delivered to the optional HttpHandler + /// argument during @see update() calls. + /// + /// With a valid handle returned, it can be used to reference the + /// request in other requests (like cancellation) and will be an + /// argument when any HttpHandler object is invoked. + /// + /// Headers supplied by default: + /// - Connection: keep-alive + /// - Accept: */* + /// - Accept-Encoding: deflate, gzip + /// - Keep-alive: 300 + /// - Host: <stuff> + /// + /// Some headers excluded by default: + /// - Pragma: + /// - Cache-control: + /// - Range: + /// - Transfer-Encoding: + /// - Referer: + /// + /// @param policy_id Default or user-defined policy class under + /// which this request is to be serviced. + /// @param priority Standard priority scheme inherited from + /// Indra code base (U32-type scheme). + /// @param url URL with any encoded query parameters to + /// be accessed. + /// @param options Optional instance of an HttpOptions object + /// to provide additional controls over the request + /// function for this request only. Any such + /// object then becomes shared-read across threads + /// and no code should modify the HttpOptions + /// instance. + /// @param headers Optional instance of an HttpHeaders object + /// to provide additional and/or overridden + /// headers for the request. As with options, + /// the instance becomes shared-read across threads + /// and no code should modify the HttpHeaders + /// instance. + /// @param handler Optional pointer to an HttpHandler instance + /// whose onCompleted() method will be invoked + /// during calls to update(). This is a non- + /// reference-counted object which would be a + /// problem for shutdown and other edge cases but + /// the pointer is only dereferenced during + /// calls to update(). + /// + /// @return The handle of the request if successfully + /// queued or LLCORE_HTTP_HANDLE_INVALID if the + /// request could not be queued. In the latter + /// case, @see getStatus() will return more info. + /// + HttpHandle requestGet(policy_t policy_id, + priority_t priority, + const std::string & url, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * handler); + + + /// Queue a full HTTP GET request to be issued with a 'Range' header. + /// The request is queued and serviced by the working thread and + /// notification of completion delivered to the optional HttpHandler + /// argument during @see update() calls. + /// + /// With a valid handle returned, it can be used to reference the + /// request in other requests (like cancellation) and will be an + /// argument when any HttpHandler object is invoked. + /// + /// Headers supplied by default: + /// - Connection: keep-alive + /// - Accept: */* + /// - Accept-Encoding: deflate, gzip + /// - Keep-alive: 300 + /// - Host: <stuff> + /// - Range: <stuff> (will be omitted if offset == 0 and len == 0) + /// + /// Some headers excluded by default: + /// - Pragma: + /// - Cache-control: + /// - Transfer-Encoding: + /// - Referer: + /// + /// @param policy_id @see requestGet() + /// @param priority " + /// @param url " + /// @param offset Offset of first byte into resource to be returned. + /// @param len Count of bytes to be returned + /// @param options @see requestGet() + /// @param headers " + /// @param handler " + /// @return " + /// + HttpHandle requestGetByteRange(policy_t policy_id, + priority_t priority, + const std::string & url, + size_t offset, + size_t len, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * handler); + + + /// Queue a full HTTP POST. Query arguments and body may + /// be provided. Caller is responsible for escaping and + /// encoding and communicating the content types. + /// + /// Headers supplied by default: + /// - Connection: keep-alive + /// - Accept: */* + /// - Accept-Encoding: deflate, gzip + /// - Keep-Alive: 300 + /// - Host: <stuff> + /// - Content-Length: <digits> + /// - Content-Type: application/x-www-form-urlencoded + /// + /// Some headers excluded by default: + /// - Pragma: + /// - Cache-Control: + /// - Transfer-Encoding: ... chunked ... + /// - Referer: + /// - Content-Encoding: + /// - Expect: + /// + /// @param policy_id @see requestGet() + /// @param priority " + /// @param url " + /// @param body Byte stream to be sent as the body. No + /// further encoding or escaping will be done + /// to the content. + /// @param options @see requestGet()K(optional) + /// @param headers " + /// @param handler " + /// @return " + /// + HttpHandle requestPost(policy_t policy_id, + priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * handler); + + + /// Queue a full HTTP PUT. Query arguments and body may + /// be provided. Caller is responsible for escaping and + /// encoding and communicating the content types. + /// + /// Headers supplied by default: + /// - Connection: keep-alive + /// - Accept: */* + /// - Accept-Encoding: deflate, gzip + /// - Keep-Alive: 300 + /// - Host: <stuff> + /// - Content-Length: <digits> + /// + /// Some headers excluded by default: + /// - Pragma: + /// - Cache-Control: + /// - Transfer-Encoding: ... chunked ... + /// - Referer: + /// - Content-Encoding: + /// - Expect: + /// - Content-Type: + /// + /// @param policy_id @see requestGet() + /// @param priority " + /// @param url " + /// @param body Byte stream to be sent as the body. No + /// further encoding or escaping will be done + /// to the content. + /// @param options @see requestGet()K(optional) + /// @param headers " + /// @param handler " + /// @return " + /// + HttpHandle requestPut(policy_t policy_id, + priority_t priority, + const std::string & url, + BufferArray * body, + HttpOptions * options, + HttpHeaders * headers, + HttpHandler * handler); + + + /// Queue a NoOp request. + /// The request is queued and serviced by the working thread which + /// immediately processes it and returns the request to the reply + /// queue. + /// + /// @param handler @see requestGet() + /// @return " + /// + HttpHandle requestNoOp(HttpHandler * handler); + + /// While all the heavy work is done by the worker thread, notifications + /// must be performed in the context of the application thread. These + /// are done synchronously during calls to this method which gives the + /// library control so notification can be performed. Application handlers + /// are expected to return 'quickly' and do any significant processing + /// outside of the notification callback to onCompleted(). + /// + /// @param usecs Maximum number of wallclock microseconds to + /// spend in the call. As hinted at above, this + /// is partly a function of application code so it's + /// a soft limit. A '0' value will run without + /// time limit until everything queued has been + /// delivered. + /// + /// @return Standard status code. + HttpStatus update(long usecs); + + /// @} + + /// @name RequestMgmtMethods + /// + /// @{ + + HttpHandle requestCancel(HttpHandle request, HttpHandler *); + + /// Request that a previously-issued request be reprioritized. + /// The status of whether the change itself succeeded arrives + /// via notification. + /// + /// @param request Handle of previously-issued request to + /// be changed. + /// @param priority New priority value. + /// @param handler @see requestGet() + /// @return " + /// + HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler * handler); + + /// @} + + /// @name UtilityMethods + /// + /// @{ + + /// Initialization method that needs to be called before queueing any + /// requests. Doesn't start the worker thread and may be called befoer + /// or after policy setup. + static HttpStatus createService(); + + /// Mostly clean shutdown of services prior to exit. Caller is expected + /// to have stopped a running worker thread before calling this. + static HttpStatus destroyService(); + + /// Called once after @see createService() to start the worker thread. + /// Stopping the thread is achieved by requesting it via @see requestStopThread(). + /// May be called before or after requests are issued. + static HttpStatus startThread(); + + /// Queues a request to the worker thread to have it stop processing + /// and exit (without exiting the program). When the operation is + /// picked up by the worker thread, it immediately processes it and + /// begins detaching from refcounted resources like request and + /// reply queues and then returns to the host OS. It *does* queue a + /// reply to give the calling application thread a notification that + /// the operation has been performed. + /// + /// @param handler (optional) + /// @return The handle of the request if successfully + /// queued or LLCORE_HTTP_HANDLE_INVALID if the + /// request could not be queued. In the latter + /// case, @see getStatus() will return more info. + /// As the request cannot be cancelled, the handle + /// is generally not useful. + /// + HttpHandle requestStopThread(HttpHandler * handler); + + /// Queue a Spin request. + /// DEBUG/TESTING ONLY. This puts the worker into a CPU spin for + /// test purposes. + /// + /// @param mode 0 for hard spin, 1 for soft spin + /// @return Standard handle return cases. + /// + HttpHandle requestSpin(int mode); + + /// @} + + /// @name DynamicPolicyMethods + /// + /// @{ + + /// Request that a running transport pick up a new proxy setting. + /// An empty string will indicate no proxy is to be used. + HttpHandle requestSetHttpProxy(const std::string & proxy, HttpHandler * handler); + + /// @} + +protected: + void generateNotification(HttpOperation * op); + +private: + /// @name InstanceData + /// + /// @{ + HttpStatus mLastReqStatus; + HttpReplyQueue * mReplyQueue; + HttpRequestQueue * mRequestQueue; + + /// @} + + // ==================================== + /// @name GlobalState + /// + /// @{ + /// + /// Must be established before any threading is allowed to + /// start. + /// + static policy_t sNextPolicyID; + + /// @} + // End Global State + // ==================================== + +}; // end class HttpRequest + + +} // end namespace LLCore + + + +#endif // _LLCORE_HTTP_REQUEST_H_ diff --git a/indra/llcorehttp/httpresponse.cpp b/indra/llcorehttp/httpresponse.cpp new file mode 100644 index 0000000000..a552e48a1b --- /dev/null +++ b/indra/llcorehttp/httpresponse.cpp @@ -0,0 +1,91 @@ +/** + * @file httpresponse.cpp + * @brief + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "httpresponse.h" +#include "bufferarray.h" +#include "httpheaders.h" + + +namespace LLCore +{ + + +HttpResponse::HttpResponse() + : LLCoreInt::RefCounted(true), + mReplyOffset(0U), + mReplyLength(0U), + mReplyFullLength(0U), + mBufferArray(NULL), + mHeaders(NULL) +{} + + +HttpResponse::~HttpResponse() +{ + setBody(NULL); + setHeaders(NULL); +} + + +void HttpResponse::setBody(BufferArray * ba) +{ + if (mBufferArray == ba) + return; + + if (mBufferArray) + { + mBufferArray->release(); + } + + if (ba) + { + ba->addRef(); + } + + mBufferArray = ba; +} + + +void HttpResponse::setHeaders(HttpHeaders * headers) +{ + if (mHeaders == headers) + return; + + if (mHeaders) + { + mHeaders->release(); + } + + if (headers) + { + headers->addRef(); + } + + mHeaders = headers; +} + + +} // end namespace LLCore diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h new file mode 100644 index 0000000000..4a481db6ac --- /dev/null +++ b/indra/llcorehttp/httpresponse.h @@ -0,0 +1,161 @@ +/** + * @file httpresponse.h + * @brief Public-facing declarations for the HttpResponse class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LLCORE_HTTP_RESPONSE_H_ +#define _LLCORE_HTTP_RESPONSE_H_ + + +#include <string> + +#include "httpcommon.h" + +#include "_refcounted.h" + + +namespace LLCore +{ + +class BufferArray; +class HttpHeaders; + +/// HttpResponse is instantiated by the library and handed to +/// the caller during callbacks to the handler. It supplies +/// all the status, header and HTTP body data the caller is +/// interested in. Methods provide simple getters to return +/// individual pieces of the response. +/// +/// Typical usage will have the caller interrogate the object +/// and return from the handler callback. Instances are refcounted +/// and callers can bump the count and retain the object as needed. +/// +/// Threading: Not intrinsically thread-safe. +/// +/// Allocation: Refcounted, heap only. Caller of the constructor +/// is given a refcount. +/// +class HttpResponse : public LLCoreInt::RefCounted +{ +public: + HttpResponse(); + +protected: + virtual ~HttpResponse(); // Use release() + + HttpResponse(const HttpResponse &); // Not defined + void operator=(const HttpResponse &); // Not defined + +public: + /// Returns the final status of the requested operation. + /// + HttpStatus getStatus() const + { + return mStatus; + } + + void setStatus(const HttpStatus & status) + { + mStatus = status; + } + + /// Simple getter for the response body returned as a scatter/gather + /// buffer. If the operation doesn't produce data (such as the Null + /// or StopThread operations), this may be NULL. + /// + /// Caller can hold onto the response by incrementing the reference + /// count of the returned object. + BufferArray * getBody() const + { + return mBufferArray; + } + + /// Set the response data in the instance. Will drop the reference + /// count to any existing data and increment the count of that passed + /// in. It is legal to set the data to NULL. + void setBody(BufferArray * ba); + + /// And a getter for the headers. And as with @see getResponse(), + /// if headers aren't available because the operation doesn't produce + /// any or delivery of headers wasn't requested in the options, this + /// will be NULL. + /// + /// Caller can hold onto the headers by incrementing the reference + /// count of the returned object. + HttpHeaders * getHeaders() const + { + return mHeaders; + } + + /// Behaves like @see setResponse() but for header data. + void setHeaders(HttpHeaders * headers); + + /// If a 'Range:' header was used, these methods are involved + /// in setting and returning data about the actual response. + /// If both @offset and @length are returned as 0, we probably + /// didn't get a Content-Range header in the response. This + /// occurs with various Capabilities-based services and the + /// caller is going to have to make assumptions on receipt of + /// a 206 status. The @full value may also be zero in cases of + /// parsing problems or a wild-carded length response. + void getRange(unsigned int * offset, unsigned int * length, unsigned int * full) const + { + *offset = mReplyOffset; + *length = mReplyLength; + *full = mReplyFullLength; + } + + void setRange(unsigned int offset, unsigned int length, unsigned int full_length) + { + mReplyOffset = offset; + mReplyLength = length; + mReplyFullLength = full_length; + } + + /// + const std::string & getContentType() const + { + return mContentType; + } + + void setContentType(const std::string & con_type) + { + mContentType = con_type; + } + +protected: + // Response data here + HttpStatus mStatus; + unsigned int mReplyOffset; + unsigned int mReplyLength; + unsigned int mReplyFullLength; + BufferArray * mBufferArray; + HttpHeaders * mHeaders; + std::string mContentType; +}; + + +} // end namespace LLCore + +#endif // _LLCORE_HTTP_RESPONSE_H_ diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp new file mode 100644 index 0000000000..e863ddd13f --- /dev/null +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -0,0 +1,175 @@ +/** + * @file llcorehttp_test + * @brief Main test runner + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llcorehttp_test.h" + +#include <iostream> +#include <sstream> + +// These are not the right way in viewer for some reason: +// #include <tut/tut.hpp> +// #include <tut/tut_reporter.hpp> +// This works: +#include "../test/lltut.h" + +// Pull in each of the test sets +#include "test_bufferarray.hpp" +#include "test_bufferstream.hpp" +#include "test_httpstatus.hpp" +#include "test_refcounted.hpp" +#include "test_httpoperation.hpp" +#include "test_httprequest.hpp" +#include "test_httpheaders.hpp" +#include "test_httprequestqueue.hpp" + +#include "llproxy.h" + +unsigned long ssl_thread_id_callback(void); +void ssl_locking_callback(int mode, int type, const char * file, int line); + +#if 0 // lltut provides main and runner + +namespace tut +{ + test_runner_singleton runner; +} + +int main() +{ + curl_global_init(CURL_GLOBAL_ALL); + + // *FIXME: Need threaded/SSL curl setup here. + + tut::reporter reporter; + + tut::runner.get().set_callback(&reporter); + tut::runner.get().run_tests(); + return !reporter.all_ok(); + + curl_global_cleanup(); +} + +#endif // 0 + +int ssl_mutex_count(0); +LLCoreInt::HttpMutex ** ssl_mutex_list = NULL; + +void init_curl() +{ + curl_global_init(CURL_GLOBAL_ALL); + + ssl_mutex_count = CRYPTO_num_locks(); + if (ssl_mutex_count > 0) + { + ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; + + for (int i(0); i < ssl_mutex_count; ++i) + { + ssl_mutex_list[i] = new LLCoreInt::HttpMutex; + } + + CRYPTO_set_locking_callback(ssl_locking_callback); + CRYPTO_set_id_callback(ssl_thread_id_callback); + } + + LLProxy::getInstance(); +} + + +void term_curl() +{ + LLProxy::cleanupClass(); + + CRYPTO_set_locking_callback(NULL); + for (int i(0); i < ssl_mutex_count; ++i) + { + delete ssl_mutex_list[i]; + } + delete [] ssl_mutex_list; +} + + +unsigned long ssl_thread_id_callback(void) +{ +#if defined(WIN32) + return (unsigned long) GetCurrentThread(); +#else + return (unsigned long) pthread_self(); +#endif +} + + +void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */) +{ + if (type >= 0 && type < ssl_mutex_count) + { + if (mode & CRYPTO_LOCK) + { + ssl_mutex_list[type]->lock(); + } + else + { + ssl_mutex_list[type]->unlock(); + } + } +} + + +std::string get_base_url() +{ + const char * env(getenv("LL_TEST_PORT")); + + if (! env) + { + std::cerr << "LL_TEST_PORT environment variable missing." << std::endl; + std::cerr << "Test expects to run in test_llcorehttp_peer.py script." << std::endl; + tut::ensure("LL_TEST_PORT set in environment", NULL != env); + } + + int port(atoi(env)); + std::ostringstream out; + out << "http://localhost:" << port << "/"; + return out.str(); +} + + +void stop_thread(LLCore::HttpRequest * req) +{ + if (req) + { + req->requestStopThread(NULL); + + int count = 0; + int limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + req->update(1000); + usleep(100000); + } + } +} + + diff --git a/indra/llcorehttp/tests/llcorehttp_test.h b/indra/llcorehttp/tests/llcorehttp_test.h new file mode 100644 index 0000000000..a9567435ce --- /dev/null +++ b/indra/llcorehttp/tests/llcorehttp_test.h @@ -0,0 +1,64 @@ +/** + * @file llcorehttp_test.h + * @brief Main test runner + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#ifndef _LLCOREHTTP_TEST_H_ +#define _LLCOREHTTP_TEST_H_ + +#include "linden_common.h" // Modifies curl interfaces + +#include <curl/curl.h> +#include <openssl/crypto.h> +#include <string> + +#include "httprequest.h" + +// Initialization and cleanup for libcurl. Mainly provides +// a mutex callback for SSL and a thread ID hash for libcurl. +// If you don't use these (or equivalent) and do use libcurl, +// you'll see stalls and other anomalies when performing curl +// operations. +extern void init_curl(); +extern void term_curl(); +extern std::string get_base_url(); +extern void stop_thread(LLCore::HttpRequest * req); + +class ScopedCurlInit +{ +public: + ScopedCurlInit() + { + init_curl(); + } + + ~ScopedCurlInit() + { + term_curl(); + } +}; + + +#endif // _LLCOREHTTP_TEST_H_ diff --git a/indra/llcorehttp/tests/test_allocator.cpp b/indra/llcorehttp/tests/test_allocator.cpp new file mode 100644 index 0000000000..ea12dc58eb --- /dev/null +++ b/indra/llcorehttp/tests/test_allocator.cpp @@ -0,0 +1,184 @@ +/** + * @file test_allocator.cpp + * @brief quick and dirty allocator for tracking memory allocations + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "test_allocator.h" + +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 +#include <libkern/OSAtomic.h> +#elif defined(_MSC_VER) +#include <Windows.h> +#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ ) > 40100 +// atomic extensions are built into GCC on posix platforms +#endif + +#include <cassert> +#include <cstdlib> +#include <cstring> +#include <vector> +#include <iostream> +#include <new> + +#include <boost/thread.hpp> + + +#if defined(WIN32) +#define THROW_BAD_ALLOC() _THROW1(std::bad_alloc) +#define THROW_NOTHING() _THROW0() +#else +#define THROW_BAD_ALLOC() throw(std::bad_alloc) +#define THROW_NOTHING() throw() +#endif + + +struct BlockHeader +{ + struct Block * next; + std::size_t size; + bool in_use; +}; + +struct Block +{ + BlockHeader hdr; + unsigned char data[1]; +}; + +#define TRACE_MSG(val) std::cout << __FUNCTION__ << "(" << val << ") [" << __FILE__ << ":" << __LINE__ << "]" << std::endl; + +static unsigned char MemBuf[ 4096 * 1024 ]; +Block * pNext = static_cast<Block *>(static_cast<void *>(MemBuf)); +volatile std::size_t MemTotal = 0; + +// cross-platform compare and swap operation +static bool CAS(void * volatile * ptr, void * expected, void * new_value) +{ +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 + return OSAtomicCompareAndSwapPtr( expected, new_value, ptr ); +#elif defined(_MSC_VER) + return expected == InterlockedCompareExchangePointer( ptr, new_value, expected ); +#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ ) > 40100 + return __sync_bool_compare_and_swap( ptr, expected, new_value ); +#endif +} + +static void * GetMem(std::size_t size) +{ + // TRACE_MSG(size); + volatile Block * pBlock = NULL; + volatile Block * pNewNext = NULL; + + // do a lock-free update of the global next pointer + do + { + pBlock = pNext; + pNewNext = (volatile Block *)(pBlock->data + size); + + } while(! CAS((void * volatile *) &pNext, (void *) pBlock, (void *) pNewNext)); + + // if we get here, we safely carved out a block of memory in the + // memory pool... + + // initialize our block + pBlock->hdr.next = (Block *)(pBlock->data + size); + pBlock->hdr.size = size; + pBlock->hdr.in_use = true; + memset((void *) pBlock->data, 0, pBlock->hdr.size); + + // do a lock-free update of the global memory total + volatile size_t total = 0; + volatile size_t new_total = 0; + do + { + total = MemTotal; + new_total = total + size; + + } while (! CAS((void * volatile *) &MemTotal, (void *) total, (void *) new_total)); + + return (void *) pBlock->data; +} + + +static void FreeMem(void * p) +{ + // get the pointer to the block record + Block * pBlock = (Block *)((unsigned char *) p - sizeof(BlockHeader)); + + // TRACE_MSG(pBlock->hdr.size); + bool * cur_in_use = &(pBlock->hdr.in_use); + volatile bool in_use = false; + bool new_in_use = false; + do + { + in_use = pBlock->hdr.in_use; + } while (! CAS((void * volatile *) cur_in_use, (void *) in_use, (void *) new_in_use)); + + // do a lock-free update of the global memory total + volatile size_t total = 0; + volatile size_t new_total = 0; + do + { + total = MemTotal; + new_total = total - pBlock->hdr.size; + } while (! CAS((void * volatile *)&MemTotal, (void *) total, (void *) new_total)); +} + + +std::size_t GetMemTotal() +{ + return MemTotal; +} + + +void * operator new(std::size_t size) THROW_BAD_ALLOC() +{ + return GetMem( size ); +} + + +void * operator new[](std::size_t size) THROW_BAD_ALLOC() +{ + return GetMem( size ); +} + + +void operator delete(void * p) THROW_NOTHING() +{ + if (p) + { + FreeMem( p ); + } +} + + +void operator delete[](void * p) THROW_NOTHING() +{ + if (p) + { + FreeMem( p ); + } +} + + diff --git a/indra/llcorehttp/tests/test_allocator.h b/indra/llcorehttp/tests/test_allocator.h new file mode 100644 index 0000000000..3572bbc5c5 --- /dev/null +++ b/indra/llcorehttp/tests/test_allocator.h @@ -0,0 +1,47 @@ +/** + * @file test_allocator.h + * @brief quick and dirty allocator for tracking memory allocations + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef TEST_ALLOCATOR_H +#define TEST_ALLOCATOR_H + +#include <cstdlib> +#include <new> + +size_t GetMemTotal(); +#if defined(WIN32) +void * operator new(std::size_t size) _THROW1(std::bad_alloc); +void * operator new[](std::size_t size) _THROW1(std::bad_alloc); +void operator delete(void * p) _THROW0(); +void operator delete[](void * p) _THROW0(); +#else +void * operator new(std::size_t size) throw (std::bad_alloc); +void * operator new[](std::size_t size) throw (std::bad_alloc); +void operator delete(void * p) throw (); +void operator delete[](void * p) throw (); +#endif + +#endif // TEST_ALLOCATOR_H + diff --git a/indra/llcorehttp/tests/test_bufferarray.hpp b/indra/llcorehttp/tests/test_bufferarray.hpp new file mode 100644 index 0000000000..8a2a64d970 --- /dev/null +++ b/indra/llcorehttp/tests/test_bufferarray.hpp @@ -0,0 +1,432 @@ +/** + * @file test_bufferarray.hpp + * @brief unit tests for the LLCore::BufferArray class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#ifndef TEST_LLCORE_BUFFER_ARRAY_H_ +#define TEST_LLCORE_BUFFER_ARRAY_H_ + +#include "bufferarray.h" + +#include <iostream> + +#include "test_allocator.h" + + +using namespace LLCore; + + + +namespace tut +{ + +struct BufferArrayTestData +{ + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + size_t mMemTotal; +}; + +typedef test_group<BufferArrayTestData> BufferArrayTestGroupType; +typedef BufferArrayTestGroupType::object BufferArrayTestObjectType; +BufferArrayTestGroupType BufferArrayTestGroup("BufferArray Tests"); + +template <> template <> +void BufferArrayTestObjectType::test<1>() +{ + set_test_name("BufferArray construction"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + ensure("One ref on construction of BufferArray", ba->getRefCount() == 1); + ensure("Memory being used", mMemTotal < GetMemTotal()); + ensure("Nothing in BA", 0 == ba->size()); + + // Try to read + char buffer[20]; + size_t read_len(ba->read(0, buffer, sizeof(buffer))); + ensure("Read returns empty", 0 == read_len); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void BufferArrayTestObjectType::test<2>() +{ + set_test_name("BufferArray single write"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + char buffer[256]; + + size_t len = ba->write(0, str1, strlen(str1)); + ensure("Wrote length correct", strlen(str1) == len); + ensure("Recorded size correct", strlen(str1) == ba->size()); + + // read some data back + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(2, buffer, 2); + ensure("Read length correct", 2 == len); + ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]); + ensure("Read didn't overwrite", 'X' == buffer[2]); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + + +template <> template <> +void BufferArrayTestObjectType::test<3>() +{ + set_test_name("BufferArray multiple writes"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, strlen(str1)); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", (2 * str1_len) == ba->size()); + + // read some data back + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(8, buffer, 4); + ensure("Read length correct", 4 == len); + ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]); + ensure("Read content correct", 'a' == buffer[2] && 'b' == buffer[3]); + ensure("Read didn't overwrite", 'X' == buffer[4]); + + // Read whole thing + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(0, buffer, sizeof(buffer)); + ensure("Read length correct", (2 * str1_len) == len); + ensure("Read content correct (3)", 0 == strncmp(buffer, str1, str1_len)); + ensure("Read content correct (4)", 0 == strncmp(&buffer[str1_len], str1, str1_len)); + ensure("Read didn't overwrite (5)", 'X' == buffer[2 * str1_len]); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void BufferArrayTestObjectType::test<4>() +{ + set_test_name("BufferArray overwriting"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJ"; + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, strlen(str1)); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", (2 * str1_len) == ba->size()); + + // reposition and overwrite + len = ba->write(8, str2, 4); + ensure("Overwrite length correct", 4 == len); + + // Leave position and read verifying content (stale really from seek() days) + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(12, buffer, 4); + ensure("Read length correct", 4 == len); + ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]); + ensure("Read content correct.2", 'e' == buffer[2] && 'f' == buffer[3]); + ensure("Read didn't overwrite", 'X' == buffer[4]); + + // reposition and check + len = ba->read(6, buffer, 8); + ensure("Read length correct.2", 8 == len); + ensure("Read content correct.3", 'g' == buffer[0] && 'h' == buffer[1]); + ensure("Read content correct.4", 'A' == buffer[2] && 'B' == buffer[3]); + ensure("Read content correct.5", 'C' == buffer[4] && 'D' == buffer[5]); + ensure("Read content correct.6", 'c' == buffer[6] && 'd' == buffer[7]); + ensure("Read didn't overwrite.7", 'X' == buffer[8]); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void BufferArrayTestObjectType::test<5>() +{ + set_test_name("BufferArray multiple writes - sequential reads"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, str1_len); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", (2 * str1_len) == ba->size()); + + // read some data back + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(8, buffer, 4); + ensure("Read length correct", 4 == len); + ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]); + ensure("Read content correct.2", 'a' == buffer[2] && 'b' == buffer[3]); + ensure("Read didn't overwrite", 'X' == buffer[4]); + + // Read some more without repositioning + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(12, buffer, sizeof(buffer)); + ensure("Read length correct", (str1_len - 2) == len); + ensure("Read content correct.3", 0 == strncmp(buffer, str1+2, str1_len-2)); + ensure("Read didn't overwrite.2", 'X' == buffer[str1_len-1]); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void BufferArrayTestObjectType::test<6>() +{ + set_test_name("BufferArray overwrite spanning blocks and appending"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJKLMNOPQRST"; + size_t str2_len(strlen(str2)); + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, strlen(str1)); + ensure("Wrote length correct", str1_len == len); + ensure("Recorded size correct", (2 * str1_len) == ba->size()); + + // reposition and overwrite + len = ba->write(8, str2, str2_len); + ensure("Overwrite length correct", str2_len == len); + + // Leave position and read verifying content + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(8 + str2_len, buffer, 0); + ensure("Read length correct", 0 == len); + ensure("Read didn't overwrite", 'X' == buffer[0]); + + // reposition and check + len = ba->read(0, buffer, sizeof(buffer)); + ensure("Read length correct.2", (str1_len + str2_len - 2) == len); + ensure("Read content correct", 0 == strncmp(buffer, str1, str1_len-2)); + ensure("Read content correct.2", 0 == strncmp(buffer+str1_len-2, str2, str2_len)); + ensure("Read didn't overwrite.2", 'X' == buffer[str1_len + str2_len - 2]); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure("All memory released", mMemTotal == GetMemTotal()); +} + +template <> template <> +void BufferArrayTestObjectType::test<7>() +{ + set_test_name("BufferArray overwrite spanning blocks and sequential writes"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJKLMNOPQRST"; + size_t str2_len(strlen(str2)); + char buffer[256]; + + // 2x str1 + size_t len = ba->write(0, str1, str1_len); + len = ba->write(str1_len, str1, str1_len); + + // reposition and overwrite + len = ba->write(6, str2, 2); + ensure("Overwrite length correct", 2 == len); + + len = ba->write(8, str2, 2); + ensure("Overwrite length correct.2", 2 == len); + + len = ba->write(10, str2, 2); + ensure("Overwrite length correct.3", 2 == len); + + // append some data + len = ba->append(str2, str2_len); + ensure("Append length correct", str2_len == len); + + // append some more + void * out_buf(ba->appendBufferAlloc(str1_len)); + memcpy(out_buf, str1, str1_len); + + // And some final writes + len = ba->write(3 * str1_len + str2_len, str2, 2); + ensure("Write length correct.2", 2 == len); + + // Check contents + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(0, buffer, sizeof(buffer)); + ensure("Final buffer length correct", (3 * str1_len + str2_len + 2) == len); + ensure("Read content correct", 0 == strncmp(buffer, str1, 6)); + ensure("Read content correct.2", 0 == strncmp(buffer + 6, str2, 2)); + ensure("Read content correct.3", 0 == strncmp(buffer + 8, str2, 2)); + ensure("Read content correct.4", 0 == strncmp(buffer + 10, str2, 2)); + ensure("Read content correct.5", 0 == strncmp(buffer + str1_len + 2, str1 + 2, str1_len - 2)); + ensure("Read content correct.6", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len)); + ensure("Read content correct.7", 0 == strncmp(buffer + str1_len + str1_len + str2_len, str1, str1_len)); + ensure("Read content correct.8", 0 == strncmp(buffer + str1_len + str1_len + str2_len + str1_len, str2, 2)); + ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len + str1_len + 2]); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure("All memory released", mMemTotal == GetMemTotal()); +} + +template <> template <> +void BufferArrayTestObjectType::test<8>() +{ + set_test_name("BufferArray zero-length appendBufferAlloc"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJKLMNOPQRST"; + size_t str2_len(strlen(str2)); + char buffer[256]; + + // 2x str1 + size_t len = ba->write(0, str1, str1_len); + len = ba->write(str1_len, str1, str1_len); + + // zero-length allocate (we allow this with a valid pointer returned) + void * out_buf(ba->appendBufferAlloc(0)); + ensure("Buffer from zero-length appendBufferAlloc non-NULL", NULL != out_buf); + + // Do it again + void * out_buf2(ba->appendBufferAlloc(0)); + ensure("Buffer from zero-length appendBufferAlloc non-NULL.2", NULL != out_buf2); + ensure("Two zero-length appendBufferAlloc buffers distinct", out_buf != out_buf2); + + // And some final writes + len = ba->write(2 * str1_len, str2, str2_len); + + // Check contents + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(0, buffer, sizeof(buffer)); + ensure("Final buffer length correct", (2 * str1_len + str2_len) == len); + ensure("Read content correct.1", 0 == strncmp(buffer, str1, str1_len)); + ensure("Read content correct.2", 0 == strncmp(buffer + str1_len, str1, str1_len)); + ensure("Read content correct.3", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len)); + ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len]); + + // release the implicit reference, causing the object to be released + ba->release(); + + // make sure we didn't leak any memory + ensure("All memory released", mMemTotal == GetMemTotal()); +} + +} // end namespace tut + + +#endif // TEST_LLCORE_BUFFER_ARRAY_H_ diff --git a/indra/llcorehttp/tests/test_bufferstream.hpp b/indra/llcorehttp/tests/test_bufferstream.hpp new file mode 100644 index 0000000000..831c901b9d --- /dev/null +++ b/indra/llcorehttp/tests/test_bufferstream.hpp @@ -0,0 +1,304 @@ +/** + * @file test_bufferstream.hpp + * @brief unit tests for the LLCore::BufferArrayStreamBuf/BufferArrayStream classes + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#ifndef TEST_LLCORE_BUFFER_STREAM_H_ +#define TEST_LLCORE_BUFFER_STREAM_H_ + +#include "bufferstream.h" + +#include <iostream> + +#include "test_allocator.h" +#include "llsd.h" +#include "llsdserialize.h" + + +using namespace LLCore; + + +namespace tut +{ + +struct BufferStreamTestData +{ + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + size_t mMemTotal; +}; + +typedef test_group<BufferStreamTestData> BufferStreamTestGroupType; +typedef BufferStreamTestGroupType::object BufferStreamTestObjectType; +BufferStreamTestGroupType BufferStreamTestGroup("BufferStream Tests"); +typedef BufferArrayStreamBuf::traits_type tst_traits_t; + + +template <> template <> +void BufferStreamTestObjectType::test<1>() +{ + set_test_name("BufferArrayStreamBuf construction with NULL BufferArray"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(NULL); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // Not much will work with a NULL + ensure("underflow() on NULL fails", tst_traits_t::eof() == bsb->underflow()); + ensure("uflow() on NULL fails", tst_traits_t::eof() == bsb->uflow()); + ensure("pbackfail() on NULL fails", tst_traits_t::eof() == bsb->pbackfail('c')); + ensure("showmanyc() on NULL fails", bsb->showmanyc() == -1); + ensure("overflow() on NULL fails", tst_traits_t::eof() == bsb->overflow('c')); + ensure("xsputn() on NULL fails", bsb->xsputn("blah", 4) == 0); + ensure("seekoff() on NULL fails", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(-1)); + + // release the implicit reference, causing the object to be released + delete bsb; + bsb = NULL; + + // make sure we didn't leak any memory + ensure("Allocated memory returned", mMemTotal == GetMemTotal()); +} + + +template <> template <> +void BufferStreamTestObjectType::test<2>() +{ + set_test_name("BufferArrayStream construction with NULL BufferArray"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + BufferArrayStream * bas = new BufferArrayStream(NULL); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // Not much will work with a NULL here + ensure("eof() is false on NULL", ! bas->eof()); + ensure("fail() is false on NULL", ! bas->fail()); + ensure("good() on NULL", bas->good()); + + // release the implicit reference, causing the object to be released + delete bas; + bas = NULL; + + // make sure we didn't leak any memory + ensure("Allocated memory returned", mMemTotal == GetMemTotal()); +} + + +template <> template <> +void BufferStreamTestObjectType::test<3>() +{ + set_test_name("BufferArrayStreamBuf construction with empty BufferArray"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted BufferArray with implicit reference + BufferArray * ba = new BufferArray; + BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // I can release my ref on the BA + ba->release(); + ba = NULL; + + // release the implicit reference, causing the object to be released + delete bsb; + bsb = NULL; + + // make sure we didn't leak any memory + ensure("Allocated memory returned", mMemTotal == GetMemTotal()); +} + + +template <> template <> +void BufferStreamTestObjectType::test<4>() +{ + set_test_name("BufferArrayStream construction with empty BufferArray"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted BufferArray with implicit reference + BufferArray * ba = new BufferArray; + + { + // create a new ref counted object with an implicit reference + BufferArrayStream bas(ba); + ensure("Memory being used", mMemTotal < GetMemTotal()); + } + + // release the implicit reference, causing the object to be released + ba->release(); + ba = NULL; + + // make sure we didn't leak any memory + ensure("Allocated memory returned", mMemTotal == GetMemTotal()); +} + + +template <> template <> +void BufferStreamTestObjectType::test<5>() +{ + set_test_name("BufferArrayStreamBuf construction with real BufferArray"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted BufferArray with implicit reference + BufferArray * ba = new BufferArray; + const char * content("This is a string. A fragment."); + const size_t c_len(strlen(content)); + ba->append(content, c_len); + + // Creat an adapter for the BufferArray + BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // I can release my ref on the BA + ba->release(); + ba = NULL; + + // Various static state + ensure("underflow() returns 'T'", bsb->underflow() == 'T'); + ensure("underflow() returns 'T' again", bsb->underflow() == 'T'); + ensure("uflow() returns 'T'", bsb->uflow() == 'T'); + ensure("uflow() returns 'h'", bsb->uflow() == 'h'); + ensure("pbackfail('i') fails", tst_traits_t::eof() == bsb->pbackfail('i')); + ensure("pbackfail('T') fails", tst_traits_t::eof() == bsb->pbackfail('T')); + ensure("pbackfail('h') succeeds", bsb->pbackfail('h') == 'h'); + ensure("showmanyc() is everything but the 'T'", bsb->showmanyc() == (c_len - 1)); + ensure("overflow() appends", bsb->overflow('c') == 'c'); + ensure("showmanyc() reflects append", bsb->showmanyc() == (c_len - 1 + 1)); + ensure("xsputn() appends some more", bsb->xsputn("bla!", 4) == 4); + ensure("showmanyc() reflects 2nd append", bsb->showmanyc() == (c_len - 1 + 5)); + ensure("seekoff() succeeds", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(0)); + ensure("seekoff() succeeds 2", bsb->seekoff(4, std::ios_base::cur, std::ios_base::in) == std::streampos(4)); + ensure("showmanyc() picks up seekoff", bsb->showmanyc() == (c_len + 5 - 4)); + ensure("seekoff() succeeds 3", bsb->seekoff(0, std::ios_base::end, std::ios_base::in) == std::streampos(c_len + 4)); + ensure("pbackfail('!') succeeds", tst_traits_t::eof() == bsb->pbackfail('!')); + + // release the implicit reference, causing the object to be released + delete bsb; + bsb = NULL; + + // make sure we didn't leak any memory + ensure("Allocated memory returned", mMemTotal == GetMemTotal()); +} + + +template <> template <> +void BufferStreamTestObjectType::test<6>() +{ + set_test_name("BufferArrayStream construction with real BufferArray"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted BufferArray with implicit reference + BufferArray * ba = new BufferArray; + //const char * content("This is a string. A fragment."); + //const size_t c_len(strlen(content)); + //ba->append(content, strlen(content)); + + { + // Creat an adapter for the BufferArray + BufferArrayStream bas(ba); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // Basic operations + bas << "Hello" << 27 << "."; + ensure("BA length 8", ba->size() == 8); + + std::string str; + bas >> str; + ensure("reads correctly", str == "Hello27."); + } + + // release the implicit reference, causing the object to be released + ba->release(); + ba = NULL; + + // make sure we didn't leak any memory + // ensure("Allocated memory returned", mMemTotal == GetMemTotal()); + // static U64 mem = GetMemTotal(); +} + + +template <> template <> +void BufferStreamTestObjectType::test<7>() +{ + set_test_name("BufferArrayStream with LLSD serialization"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted BufferArray with implicit reference + BufferArray * ba = new BufferArray; + + { + // Creat an adapter for the BufferArray + BufferArrayStream bas(ba); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // LLSD + LLSD llsd = LLSD::emptyMap(); + + llsd["int"] = LLSD::Integer(3); + llsd["float"] = LLSD::Real(923289.28992); + llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj"); + + LLSD llsd_map = LLSD::emptyMap(); + llsd_map["int"] = LLSD::Integer(-2889); + llsd_map["float"] = LLSD::Real(2.37829e32); + llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP"); + + llsd["map"] = llsd_map; + + // Serialize it + LLSDSerialize::toXML(llsd, bas); + + std::string str; + bas >> str; + // std::cout << "SERIALIZED LLSD: " << str << std::endl; + ensure("Extracted string has reasonable length", str.size() > 60); + } + + // release the implicit reference, causing the object to be released + ba->release(); + ba = NULL; + + // make sure we didn't leak any memory + // ensure("Allocated memory returned", mMemTotal == GetMemTotal()); +} + + +} // end namespace tut + + +#endif // TEST_LLCORE_BUFFER_STREAM_H_ diff --git a/indra/llcorehttp/tests/test_httpheaders.hpp b/indra/llcorehttp/tests/test_httpheaders.hpp new file mode 100644 index 0000000000..ce0d19b058 --- /dev/null +++ b/indra/llcorehttp/tests/test_httpheaders.hpp @@ -0,0 +1,108 @@ +/** + * @file test_httpheaders.hpp + * @brief unit tests for the LLCore::HttpHeaders class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#ifndef TEST_LLCORE_HTTP_HEADERS_H_ +#define TEST_LLCORE_HTTP_HEADERS_H_ + +#include "httpheaders.h" + +#include <iostream> + +#include "test_allocator.h" + + +using namespace LLCoreInt; + + + +namespace tut +{ + +struct HttpHeadersTestData +{ + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + size_t mMemTotal; +}; + +typedef test_group<HttpHeadersTestData> HttpHeadersTestGroupType; +typedef HttpHeadersTestGroupType::object HttpHeadersTestObjectType; +HttpHeadersTestGroupType HttpHeadersTestGroup("HttpHeaders Tests"); + +template <> template <> +void HttpHeadersTestObjectType::test<1>() +{ + set_test_name("HttpHeaders construction"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + HttpHeaders * headers = new HttpHeaders(); + ensure("One ref on construction of HttpHeaders", headers->getRefCount() == 1); + ensure("Memory being used", mMemTotal < GetMemTotal()); + ensure("Nothing in headers", 0 == headers->mHeaders.size()); + + // release the implicit reference, causing the object to be released + headers->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void HttpHeadersTestObjectType::test<2>() +{ + set_test_name("HttpHeaders construction"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + HttpHeaders * headers = new HttpHeaders(); + + { + // Append a few strings + std::string str1("Pragma:"); + headers->mHeaders.push_back(str1); + std::string str2("Accept: application/json"); + headers->mHeaders.push_back(str2); + + ensure("Headers retained", 2 == headers->mHeaders.size()); + ensure("First is first", headers->mHeaders[0] == str1); + ensure("Second is second", headers->mHeaders[1] == str2); + } + + // release the implicit reference, causing the object to be released + headers->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +} // end namespace tut + + +#endif // TEST_LLCORE_HTTP_HEADERS_H_ diff --git a/indra/llcorehttp/tests/test_httpoperation.hpp b/indra/llcorehttp/tests/test_httpoperation.hpp new file mode 100644 index 0000000000..17b1a96878 --- /dev/null +++ b/indra/llcorehttp/tests/test_httpoperation.hpp @@ -0,0 +1,125 @@ +/** + * @file test_httpoperation.hpp + * @brief unit tests for the LLCore::HttpOperation-derived classes + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#ifndef TEST_LLCORE_HTTP_OPERATION_H_ +#define TEST_LLCORE_HTTP_OPERATION_H_ + +#include "_httpoperation.h" +#include "httphandler.h" + +#include <iostream> + +#include "test_allocator.h" + + +using namespace LLCoreInt; + + +namespace +{ + +class TestHandler : public LLCore::HttpHandler +{ +public: + virtual void onCompleted(HttpHandle, HttpResponse *) + { + std::cout << "TestHandler::onCompleted() invoked" << std::endl; + } + +}; + + +} // end namespace anonymous + + +namespace tut +{ + struct HttpOperationTestData + { + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + size_t mMemTotal; + }; + + typedef test_group<HttpOperationTestData> HttpOperationTestGroupType; + typedef HttpOperationTestGroupType::object HttpOperationTestObjectType; + HttpOperationTestGroupType HttpOperationTestGroup("HttpOperation Tests"); + + template <> template <> + void HttpOperationTestObjectType::test<1>() + { + set_test_name("HttpOpNull construction"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + HttpOpNull * op = new HttpOpNull(); + ensure(op->getRefCount() == 1); + ensure(mMemTotal < GetMemTotal()); + + // release the implicit reference, causing the object to be released + op->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); + } + + template <> template <> + void HttpOperationTestObjectType::test<2>() + { + set_test_name("HttpOpNull construction with handlers"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // Get some handlers + TestHandler * h1 = new TestHandler(); + + // create a new ref counted object with an implicit reference + HttpOpNull * op = new HttpOpNull(); + + // Add the handlers + op->setReplyPath(NULL, h1); + + // Check ref count + ensure(op->getRefCount() == 1); + + // release the reference, releasing the operation but + // not the handlers. + op->release(); + op = NULL; + ensure(mMemTotal != GetMemTotal()); + + // release the handlers + delete h1; + h1 = NULL; + + ensure(mMemTotal == GetMemTotal()); + } + +} + +#endif // TEST_LLCORE_HTTP_OPERATION_H_ diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp new file mode 100644 index 0000000000..e5488cf941 --- /dev/null +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -0,0 +1,2670 @@ +/** + * @file test_httprequest.hpp + * @brief unit tests for the LLCore::HttpRequest class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#ifndef TEST_LLCORE_HTTP_REQUEST_H_ +#define TEST_LLCORE_HTTP_REQUEST_H_ + +#include "httprequest.h" +#include "bufferarray.h" +#include "httphandler.h" +#include "httpheaders.h" +#include "httpresponse.h" +#include "httpoptions.h" +#include "_httpservice.h" +#include "_httprequestqueue.h" + +#include <curl/curl.h> +#include <boost/regex.hpp> +#include <sstream> + +#include "test_allocator.h" +#include "llcorehttp_test.h" + + +using namespace LLCoreInt; + + +namespace +{ + +#if defined(WIN32) + +void usleep(unsigned long usec); + +#endif + +} + +namespace tut +{ + +struct HttpRequestTestData +{ + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + size_t mMemTotal; + int mHandlerCalls; + HttpStatus mStatus; +}; + +class TestHandler2 : public LLCore::HttpHandler +{ +public: + TestHandler2(HttpRequestTestData * state, + const std::string & name) + : mState(state), + mName(name), + mExpectHandle(LLCORE_HTTP_HANDLE_INVALID) + {} + + virtual void onCompleted(HttpHandle handle, HttpResponse * response) + { + if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle) + { + ensure("Expected handle received in handler", mExpectHandle == handle); + } + ensure("Handler got a response", NULL != response); + if (response && mState) + { + const HttpStatus actual_status(response->getStatus()); + std::ostringstream test; + test << "Expected HttpStatus received in response. Wanted: " + << mState->mStatus.toHex() << " Received: " << actual_status.toHex(); + ensure(test.str().c_str(), actual_status == mState->mStatus); + } + if (mState) + { + mState->mHandlerCalls++; + } + if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty()) + { + ensure("Response required with header check", response != NULL); + HttpHeaders * header(response->getHeaders()); // Will not hold onto this + ensure("Some quantity of headers returned", header != NULL); + + if (! mHeadersRequired.empty()) + { + for (int i(0); i < mHeadersRequired.size(); ++i) + { + bool found = false; + for (HttpHeaders::container_t::const_iterator iter(header->mHeaders.begin()); + header->mHeaders.end() != iter; + ++iter) + { + if (boost::regex_match(*iter, mHeadersRequired[i])) + { + found = true; + break; + } + } + std::ostringstream str; + str << "Required header # " << i << " found in response"; + ensure(str.str(), found); + } + } + + if (! mHeadersDisallowed.empty()) + { + for (int i(0); i < mHeadersDisallowed.size(); ++i) + { + for (HttpHeaders::container_t::const_iterator iter(header->mHeaders.begin()); + header->mHeaders.end() != iter; + ++iter) + { + if (boost::regex_match(*iter, mHeadersDisallowed[i])) + { + std::ostringstream str; + str << "Disallowed header # " << i << " not found in response"; + ensure(str.str(), false); + } + } + } + } + } + + if (! mCheckContentType.empty()) + { + ensure("Response required with content type check", response != NULL); + std::string con_type(response->getContentType()); + ensure("Content-Type as expected (" + mCheckContentType + ")", + mCheckContentType == con_type); + } + + // std::cout << "TestHandler2::onCompleted() invoked" << std::endl; + } + + HttpRequestTestData * mState; + std::string mName; + HttpHandle mExpectHandle; + std::string mCheckContentType; + std::vector<boost::regex> mHeadersRequired; + std::vector<boost::regex> mHeadersDisallowed; +}; + +typedef test_group<HttpRequestTestData> HttpRequestTestGroupType; +typedef HttpRequestTestGroupType::object HttpRequestTestObjectType; +HttpRequestTestGroupType HttpRequestTestGroup("HttpRequest Tests"); + +template <> template <> +void HttpRequestTestObjectType::test<1>() +{ + ScopedCurlInit ready; + + set_test_name("HttpRequest construction"); + + HttpRequest * req = NULL; + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + try + { + // Get singletons created + HttpRequest::createService(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // release the request object + delete req; + req = NULL; + + HttpRequest::destroyService(); + + // make sure we didn't leak any memory + ensure("Memory returned", mMemTotal == GetMemTotal()); + } + catch (...) + { + delete req; + HttpRequest::destroyService(); + throw; + } +} + +template <> template <> +void HttpRequestTestObjectType::test<2>() +{ + ScopedCurlInit ready; + + set_test_name("HttpRequest and Null Op queued"); + + HttpRequest * req = NULL; + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + try + { + // Get singletons created + HttpRequest::createService(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // Issue a NoOp + HttpHandle handle = req->requestNoOp(NULL); + ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID); + + // release the request object + delete req; + req = NULL; + + // We're still holding onto the operation which is + // sitting, unserviced, on the request queue so... + ensure("Memory being used 2", mMemTotal < GetMemTotal()); + + // Request queue should have two references: global singleton & service object + ensure("Two references to request queue", 2 == HttpRequestQueue::instanceOf()->getRefCount()); + + // Okay, tear it down + HttpRequest::destroyService(); + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory returned", mMemTotal == GetMemTotal()); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<3>() +{ + ScopedCurlInit ready; + + set_test_name("HttpRequest NoOp + Stop execution"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a NoOp + HttpHandle handle = req->requestNoOp(&handler); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(20); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 100; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + +template <> template <> +void HttpRequestTestObjectType::test<4>() +{ + ScopedCurlInit ready; + + set_test_name("2 HttpRequest instances, one thread"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + TestHandler2 handler1(this, "handler1"); + TestHandler2 handler2(this, "handler2"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req1 = NULL; + HttpRequest * req2 = NULL; + + try + { + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req1 = new HttpRequest(); + req2 = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue some NoOps + HttpHandle handle = req1->requestNoOp(&handler1); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler1.mExpectHandle = handle; + + handle = req2->requestNoOp(&handler2); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler2.mExpectHandle = handle; + + // Run the notification pump. + int count(0); + int limit(20); + while (count++ < limit && mHandlerCalls < 2) + { + req1->update(1000000); + req2->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 2); + + // Okay, request a shutdown of the servicing thread + handle = req2->requestStopThread(&handler2); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler2.mExpectHandle = handle; + + // Run the notification pump again + count = 0; + limit = 100; + while (count++ < limit && mHandlerCalls < 3) + { + req1->update(1000000); + req2->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 3); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req1; + req1 = NULL; + delete req2; + req2 = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 3 == mHandlerCalls); + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); + } + catch (...) + { + stop_thread(req1); + delete req1; + delete req2; + HttpRequest::destroyService(); + throw; + } +} + +template <> template <> +void HttpRequestTestObjectType::test<5>() +{ + ScopedCurlInit ready; + + set_test_name("HttpRequest Spin (soft) + NoOp + hard termination"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a Spin + HttpHandle handle = req->requestSpin(1); + ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Issue a NoOp + handle = req->requestNoOp(&handler); + ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("NoOp notification received", mHandlerCalls == 1); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + // Check memory usage + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); + // This memory test should work but could give problems as it + // relies on the worker thread picking up a friendly request + // to shutdown. Doing so, it drops references to things and + // we should go back to where we started. If it gives you + // problems, look into the code before commenting things out. + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<6>() +{ + ScopedCurlInit ready; + + set_test_name("HttpRequest Spin + NoOp + hard termination"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a Spin + HttpHandle handle = req->requestSpin(0); // Hard spin + ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Issue a NoOp + handle = req->requestNoOp(&handler); + ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("No notifications received", mHandlerCalls == 0); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + // Check memory usage + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + // ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); + // This memory test won't work because we're killing the thread + // hard with the hard spinner. There's no opportunity to join + // nicely so many things leak or get destroyed unilaterally. + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<7>() +{ + ScopedCurlInit ready; + + set_test_name("HttpRequest GET to dead port + Stop execution"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * opts = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + opts = new HttpOptions(); + opts->setRetries(1); // Don't try for too long - default retries take about 18S + + // Issue a GET that can't connect + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + 0U, + "http://127.0.0.1:2/nothing/here", + 0, + 0, + opts, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(50); // With one retry, should fail quickish + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 100; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options + opts->release(); + opts = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + stop_thread(req); + if (opts) + { + opts->release(); + opts = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<8>() +{ + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest GET to real service"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + NULL, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if defined(WIN32) + // Can only do this memory test on Windows. On other platforms, + // the LL logging system holds on to memory and produces what looks + // like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<9>() +{ + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest GET with Range: header to real service"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + 0, + 0, + NULL, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if defined(WIN32) + // Can only do this memory test on Windows. On other platforms, + // the LL logging system holds on to memory and produces what looks + // like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<10>() +{ + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest PUT to real service"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + BufferArray * body = new BufferArray; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a GET that *can* connect + static const char * body_text("Now is the time for all good men..."); + body->append(body_text, strlen(body_text)); + mStatus = HttpStatus(200); + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + body, + NULL, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // Lose the request body + body->release(); + body = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + if (body) + { + body->release(); + } + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + +template <> template <> +void HttpRequestTestObjectType::test<11>() +{ + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest POST to real service"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + BufferArray * body = new BufferArray; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a GET that *can* connect + static const char * body_text("Now is the time for all good men..."); + body->append(body_text, strlen(body_text)); + mStatus = HttpStatus(200); + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + body, + NULL, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // Lose the request body + body->release(); + body = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if defined(WIN32) + // Can only do this memory test on Windows. On other platforms, + // the LL logging system holds on to memory and produces what looks + // like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + if (body) + { + body->release(); + } + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + +template <> template <> +void HttpRequestTestObjectType::test<12>() +{ + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest GET with some tracing"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Enable tracing + HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_TRACE, 2); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + 0, + 0, + NULL, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if 0 // defined(WIN32) + // Can't do this on any platform anymore, the LL logging system holds + // on to memory and produces what looks like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<13>() +{ + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest GET with returned headers"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * opts = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Enable tracing + HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_TRACE, 2); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + opts = new HttpOptions(); + opts->setWantHeaders(true); + + // Issue a GET that succeeds + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back(boost::regex("\\W*X-LL-Special:.*", boost::regex::icase)); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + 0, + 0, + opts, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // release options + opts->release(); + opts = NULL; + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if defined(WIN32) + // Can only do this memory test on Windows. On other platforms, + // the LL logging system holds on to memory and produces what looks + // like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + stop_thread(req); + if (opts) + { + opts->release(); + opts = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +template <> template <> +void HttpRequestTestObjectType::test<14>() +{ + ScopedCurlInit ready; + + set_test_name("HttpRequest GET timeout"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * opts = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + opts = new HttpOptions(); + opts->setRetries(0); // Don't retry + opts->setTimeout(2); + + // Issue a GET that sleeps + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + 0, + 0, + opts, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(50); // With one retry, should fail quickish + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 100; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options + opts->release(); + opts = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if defined(WIN32) + // Can only do this memory test on Windows. On other platforms, + // the LL logging system holds on to memory and produces what looks + // like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + stop_thread(req); + if (opts) + { + opts->release(); + opts = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + +// Test retrieval of Content-Type/Content-Encoding headers +template <> template <> +void HttpRequestTestObjectType::test<15>() +{ + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; + + set_test_name("HttpRequest GET with Content-Type"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // Load and clear the string setting to preload std::string object + // for memory return tests. + handler.mCheckContentType = "application/llsd+xml"; + handler.mCheckContentType.clear(); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + handler.mCheckContentType = "application/llsd+xml"; + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base, + NULL, + NULL, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mCheckContentType.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + +#if defined(WIN32) + // Can only do this memory test on Windows. On other platforms, + // the LL logging system holds on to memory and produces what looks + // like memory leaks... + + // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal()); + ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal()); +#endif + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +// Test header generation on GET requests +template <> template <> +void HttpRequestTestObjectType::test<16>() +{ + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest GET"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * options = NULL; + HttpHeaders * headers = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = new HttpOptions(); + options->setWantHeaders(true); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase)); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base + "reflect/", + options, + NULL, + &handler); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Do a texture-style fetch + headers = new HttpHeaders; + headers->mHeaders.push_back("Accept: image/x-j2c"); + + mStatus = HttpStatus(200); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*image/x-j2c", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("\\W*X-Reflect-range:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase)); + handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base + "reflect/", + 0, + 47, + options, + headers, + &handler); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 2); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 3) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 3); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers + if (options) + { + options->release(); + } + options = NULL; + + if (headers) + { + headers->release(); + } + headers = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (options) + { + options->release(); + options = NULL; + } + if (headers) + { + headers->release(); + headers = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +// Test header generation on POST requests +template <> template <> +void HttpRequestTestObjectType::test<17>() +{ + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest POST"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * options = NULL; + HttpHeaders * headers = NULL; + BufferArray * ba = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = new HttpOptions(); + options->setWantHeaders(true); + + // And a buffer array + const char * msg("It was the best of times, it was the worst of times."); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default POST + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/x-www-form-urlencoded", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase)); + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base + "reflect/", + ba, + options, + NULL, + &handler); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers + if (options) + { + options->release(); + } + options = NULL; + + if (headers) + { + headers->release(); + } + headers = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } + if (options) + { + options->release(); + options = NULL; + } + if (headers) + { + headers->release(); + headers = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +// Test header generation on PUT requests +template <> template <> +void HttpRequestTestObjectType::test<18>() +{ + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest PUT"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * options = NULL; + HttpHeaders * headers = NULL; + BufferArray * ba = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = new HttpOptions(); + options->setWantHeaders(true); + + // And a buffer array + const char * msg("It was the best of times, it was the worst of times."); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default PUT + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:.*", boost::regex::icase)); + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base + "reflect/", + ba, + options, + NULL, + &handler); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers + if (options) + { + options->release(); + } + options = NULL; + + if (headers) + { + headers->release(); + } + headers = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } + if (options) + { + options->release(); + options = NULL; + } + if (headers) + { + headers->release(); + headers = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +// Test header generation on GET requests with overrides +template <> template <> +void HttpRequestTestObjectType::test<19>() +{ + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest GET with header overrides"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * options = NULL; + HttpHeaders * headers = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = new HttpOptions(); + options->setWantHeaders(true); + + // headers + headers = new HttpHeaders; + headers->mHeaders.push_back("Keep-Alive: 120"); + headers->mHeaders.push_back("Accept-encoding: deflate"); + headers->mHeaders.push_back("Accept: text/plain"); + + // Issue a GET with modified headers + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*text/plain", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*deflate", boost::regex::icase)); // close enough + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*120", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-keep-alive:\\s*300", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase)); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base + "reflect/", + options, + headers, + &handler); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers + if (options) + { + options->release(); + } + options = NULL; + + if (headers) + { + headers->release(); + } + headers = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (options) + { + options->release(); + options = NULL; + } + if (headers) + { + headers->release(); + headers = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +// Test header generation on POST requests with overrides +template <> template <> +void HttpRequestTestObjectType::test<20>() +{ + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest POST with header overrides"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * options = NULL; + HttpHeaders * headers = NULL; + BufferArray * ba = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = new HttpOptions(); + options->setWantHeaders(true); + + // headers + headers = new HttpHeaders(); + headers->mHeaders.push_back("keep-Alive: 120"); + headers->mHeaders.push_back("Accept: text/html"); + headers->mHeaders.push_back("content-type: application/llsd+xml"); + headers->mHeaders.push_back("cache-control: no-store"); + + // And a buffer array + const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default POST + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*text/html", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*120", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/llsd\\+xml", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("\\s*X-Reflect-cache-control:\\s*no-store", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*application/x-www-form-urlencoded", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-keep-alive:\\s*300", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase)); + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base + "reflect/", + ba, + options, + headers, + &handler); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers + if (options) + { + options->release(); + } + options = NULL; + + if (headers) + { + headers->release(); + } + headers = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } + if (options) + { + options->release(); + options = NULL; + } + if (headers) + { + headers->release(); + headers = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +// Test header generation on PUT requests with overrides +template <> template <> +void HttpRequestTestObjectType::test<21>() +{ + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + std::string url_base(get_base_url()); + + set_test_name("Header generation for HttpRequest PUT with header overrides"); + + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + // Create before memory record as the string copy will bump numbers. + TestHandler2 handler(this, "handler"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions * options = NULL; + HttpHeaders * headers = NULL; + BufferArray * ba = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = new HttpOptions(); + options->setWantHeaders(true); + + // headers + headers = new HttpHeaders; + headers->mHeaders.push_back("content-type: text/plain"); + headers->mHeaders.push_back("content-type: text/html"); + headers->mHeaders.push_back("content-type: application/llsd+xml"); + + // And a buffer array + const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default PUT + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase)); + handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/llsd\\+xml", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*text/plain", boost::regex::icase)); + handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*text/html", boost::regex::icase)); + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + 0U, + url_base + "reflect/", + ba, + options, + headers, + &handler); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(10); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(100000); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + + // Okay, request a shutdown of the servicing thread + mStatus = HttpStatus(); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handle = req->requestStopThread(&handler); + ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump again + count = 0; + limit = 10; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(100000); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(100000); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers + if (options) + { + options->release(); + } + options = NULL; + + if (headers) + { + headers->release(); + } + headers = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } + if (options) + { + options->release(); + options = NULL; + } + if (headers) + { + headers->release(); + headers = NULL; + } + delete req; + HttpRequest::destroyService(); + throw; + } +} + + +} // end namespace tut + +namespace +{ + +#if defined(WIN32) + +void usleep(unsigned long usec) +{ + Sleep((DWORD) (usec / 1000UL)); +} + +#endif + +} + +#endif // TEST_LLCORE_HTTP_REQUEST_H_ diff --git a/indra/llcorehttp/tests/test_httprequestqueue.hpp b/indra/llcorehttp/tests/test_httprequestqueue.hpp new file mode 100644 index 0000000000..1de2d8f9ab --- /dev/null +++ b/indra/llcorehttp/tests/test_httprequestqueue.hpp @@ -0,0 +1,186 @@ +/** + * @file test_httprequestqueue.hpp + * @brief unit tests for the LLCore::HttpRequestQueue class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#ifndef TEST_LLCORE_HTTP_REQUESTQUEUE_H_ +#define TEST_LLCORE_HTTP_REQUESTQUEUE_H_ + +#include "_httprequestqueue.h" + +#include <iostream> + +#include "test_allocator.h" +#include "_httpoperation.h" + + +using namespace LLCoreInt; + + + +namespace tut +{ + +struct HttpRequestqueueTestData +{ + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + size_t mMemTotal; +}; + +typedef test_group<HttpRequestqueueTestData> HttpRequestqueueTestGroupType; +typedef HttpRequestqueueTestGroupType::object HttpRequestqueueTestObjectType; +HttpRequestqueueTestGroupType HttpRequestqueueTestGroup("HttpRequestqueue Tests"); + +template <> template <> +void HttpRequestqueueTestObjectType::test<1>() +{ + set_test_name("HttpRequestQueue construction"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); + + ensure("One ref on construction of HttpRequestQueue", HttpRequestQueue::instanceOf()->getRefCount() == 1); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // release the implicit reference, causing the object to be released + HttpRequestQueue::term(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void HttpRequestqueueTestObjectType::test<2>() +{ + set_test_name("HttpRequestQueue refcount works"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); + + HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); + rq->addRef(); + + // release the singleton, hold on to the object + HttpRequestQueue::term(); + + ensure("One ref after term() called", rq->getRefCount() == 1); + ensure("Memory being used", mMemTotal < GetMemTotal()); + + // Drop ref + rq->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void HttpRequestqueueTestObjectType::test<3>() +{ + set_test_name("HttpRequestQueue addOp/fetchOp work"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); + + HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); + + HttpOperation * op = new HttpOpNull(); + + rq->addOp(op); // transfer my refcount + + op = rq->fetchOp(true); // Potentially hangs the test on failure + ensure("One goes in, one comes out", NULL != op); + op->release(); + + op = rq->fetchOp(false); + ensure("Better not be two of them", NULL == op); + + // release the singleton, hold on to the object + HttpRequestQueue::term(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); +} + +template <> template <> +void HttpRequestqueueTestObjectType::test<4>() +{ + set_test_name("HttpRequestQueue addOp/fetchAll work"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); + + HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); + + HttpOperation * op = new HttpOpNull(); + rq->addOp(op); // transfer my refcount + + op = new HttpOpNull(); + rq->addOp(op); // transfer my refcount + + op = new HttpOpNull(); + rq->addOp(op); // transfer my refcount + + { + HttpRequestQueue::OpContainer ops; + rq->fetchAll(true, ops); // Potentially hangs the test on failure + ensure("Three go in, three come out", 3 == ops.size()); + + op = rq->fetchOp(false); + ensure("Better not be any more of them", NULL == op); + + // release the singleton, hold on to the object + HttpRequestQueue::term(); + + // We're still holding onto the ops. + ensure(mMemTotal < GetMemTotal()); + + // Release them + while (! ops.empty()) + { + HttpOperation * op = ops.front(); + ops.erase(ops.begin()); + op->release(); + } + } + + // Should be clean + ensure("All memory returned", mMemTotal == GetMemTotal()); +} + +} // end namespace tut + + +#endif // TEST_LLCORE_HTTP_REQUESTQUEUE_H_ diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp new file mode 100644 index 0000000000..f7b542d3b5 --- /dev/null +++ b/indra/llcorehttp/tests/test_httpstatus.hpp @@ -0,0 +1,265 @@ +/** + * @file test_llrefcounted + * @brief unit tests for HttpStatus struct + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef TEST_HTTP_STATUS_H_ +#define TEST_HTTP_STATUS_H_ + +#include "httpcommon.h" + +#include <curl/curl.h> +#include <curl/multi.h> + +using namespace LLCore; + +namespace tut +{ + +struct HttpStatusTestData +{ + HttpStatusTestData() + {} +}; + +typedef test_group<HttpStatusTestData> HttpStatusTestGroupType; +typedef HttpStatusTestGroupType::object HttpStatusTestObjectType; + +HttpStatusTestGroupType HttpStatusTestGroup("HttpStatus Tests"); + +template <> template <> +void HttpStatusTestObjectType::test<1>() +{ + set_test_name("HttpStatus construction"); + + // auto allocation fine for this + HttpStatus status; + status.mType = HttpStatus::EXT_CURL_EASY; + status.mStatus = 0; + + ensure(bool(status)); + ensure(false == !(status)); + + status.mType = HttpStatus::EXT_CURL_MULTI; + status.mStatus = 0; + + ensure(bool(status)); + ensure(false == !(status)); + + status.mType = HttpStatus::LLCORE; + status.mStatus = HE_SUCCESS; + + ensure(bool(status)); + ensure(false == !(status)); + + status.mType = HttpStatus::EXT_CURL_MULTI; + status.mStatus = -1; + + ensure(false == bool(status)); + ensure(!(status)); + + status.mType = HttpStatus::EXT_CURL_EASY; + status.mStatus = CURLE_BAD_DOWNLOAD_RESUME; + + ensure(false == bool(status)); + ensure(!(status)); +} + + +template <> template <> +void HttpStatusTestObjectType::test<2>() +{ + set_test_name("HttpStatus memory structure"); + + // Require that an HttpStatus object can be trivially + // returned as a function return value in registers. + // One should fit in an int on all platforms. + + ensure(sizeof(HttpStatus) <= sizeof(int)); +} + + +template <> template <> +void HttpStatusTestObjectType::test<3>() +{ + set_test_name("HttpStatus valid error string conversion"); + + HttpStatus status; + status.mType = HttpStatus::EXT_CURL_EASY; + status.mStatus = 0; + std::string msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(msg.empty()); + + status.mType = HttpStatus::EXT_CURL_EASY; + status.mStatus = CURLE_BAD_FUNCTION_ARGUMENT; + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); + + status.mType = HttpStatus::EXT_CURL_MULTI; + status.mStatus = CURLM_OUT_OF_MEMORY; + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); + + status.mType = HttpStatus::LLCORE; + status.mStatus = HE_SHUTTING_DOWN; + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); +} + + +template <> template <> +void HttpStatusTestObjectType::test<4>() +{ + set_test_name("HttpStatus invalid error string conversion"); + + HttpStatus status; + status.mType = HttpStatus::EXT_CURL_EASY; + status.mStatus = 32726; + std::string msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); + + status.mType = HttpStatus::EXT_CURL_MULTI; + status.mStatus = -470; + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); + + status.mType = HttpStatus::LLCORE; + status.mStatus = 923; + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); +} + +template <> template <> +void HttpStatusTestObjectType::test<5>() +{ + set_test_name("HttpStatus equality/inequality testing"); + + // Make certain equality/inequality tests do not pass + // through the bool conversion. Distinct successful + // and error statuses should compare unequal. + + HttpStatus status1(HttpStatus::LLCORE, HE_SUCCESS); + HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS); + ensure(status1 != status2); + + status1.mType = HttpStatus::LLCORE; + status1.mStatus = HE_REPLY_ERROR; + status2.mType = HttpStatus::LLCORE; + status2.mStatus= HE_SHUTTING_DOWN; + ensure(status1 != status2); +} + +template <> template <> +void HttpStatusTestObjectType::test<6>() +{ + set_test_name("HttpStatus basic HTTP status encoding"); + + HttpStatus status; + status.mType = 200; + status.mStatus = HE_SUCCESS; + std::string msg = status.toString(); + ensure(msg.empty()); + ensure(bool(status)); + + // Normally a success but application says error + status.mStatus = HE_REPLY_ERROR; + msg = status.toString(); + ensure(! msg.empty()); + ensure(! bool(status)); + ensure(status.toULong() > 1UL); // Biggish number, not a bool-to-ulong + + // Same statuses with distinct success/fail are distinct + status.mType = 200; + status.mStatus = HE_SUCCESS; + HttpStatus status2(200, HE_REPLY_ERROR); + ensure(status != status2); + + // Normally an error but application says okay + status.mType = 406; + status.mStatus = HE_SUCCESS; + msg = status.toString(); + ensure(msg.empty()); + ensure(bool(status)); + + // Different statuses but both successful are distinct + status.mType = 200; + status.mStatus = HE_SUCCESS; + status2.mType = 201; + status2.mStatus = HE_SUCCESS; + ensure(status != status2); + + // Different statuses but both failed are distinct + status.mType = 200; + status.mStatus = HE_REPLY_ERROR; + status2.mType = 201; + status2.mStatus = HE_REPLY_ERROR; + ensure(status != status2); +} + +template <> template <> +void HttpStatusTestObjectType::test<7>() +{ + set_test_name("HttpStatus HTTP error text strings"); + + HttpStatus status(100, HE_REPLY_ERROR); + std::string msg(status.toString()); + ensure(! msg.empty()); // Should be something + ensure(msg == "Continue"); + + status.mStatus = HE_SUCCESS; + msg = status.toString(); + ensure(msg.empty()); // Success is empty + + status.mType = 199; + status.mStatus = HE_REPLY_ERROR; + msg = status.toString(); + ensure(msg == "Unknown error"); + + status.mType = 505; // Last defined string + status.mStatus = HE_REPLY_ERROR; + msg = status.toString(); + ensure(msg == "HTTP Version not supported"); + + status.mType = 506; // One beyond + status.mStatus = HE_REPLY_ERROR; + msg = status.toString(); + ensure(msg == "Unknown error"); + + status.mType = 999; // Last HTTP status + status.mStatus = HE_REPLY_ERROR; + msg = status.toString(); + ensure(msg == "Unknown error"); +} + +} // end namespace tut + +#endif // TEST_HTTP_STATUS_H + diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py new file mode 100644 index 0000000000..75a3c39ef2 --- /dev/null +++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python +"""\ +@file test_llsdmessage_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=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2012, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +import os +import sys +import time +import select +import getopt +from threading import Thread +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +from SocketServer import ThreadingMixIn + +mydir = os.path.dirname(__file__) # expected to be .../indra/llcorehttp/tests/ +sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) +from indra.util.fastest_elementtree import parse as xml_parse +from indra.base import llsd +from testrunner import freeport, run, debug, VERBOSE + +class TestHTTPRequestHandler(BaseHTTPRequestHandler): + """This subclass of BaseHTTPRequestHandler is to receive and echo + LLSD-flavored messages sent by the C++ LLHTTPClient. + """ + def read(self): + # The following logic is adapted from the library module + # SimpleXMLRPCServer.py. + # Get arguments by reading body of request. + # We read this in chunks to avoid straining + # socket.read(); around the 10 or 15Mb mark, some platforms + # begin to have problems (bug #792570). + try: + size_remaining = int(self.headers["content-length"]) + except (KeyError, ValueError): + return "" + max_chunk_size = 10*1024*1024 + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + chunk = self.rfile.read(chunk_size) + L.append(chunk) + size_remaining -= len(chunk) + return ''.join(L) + # end of swiped read() logic + + def read_xml(self): + # This approach reads the entire POST data into memory first + return llsd.parse(self.read()) +## # This approach attempts to stream in the LLSD XML from self.rfile, +## # assuming that the underlying XML parser reads its input file +## # incrementally. Unfortunately I haven't been able to make it work. +## tree = xml_parse(self.rfile) +## debug("Finished raw parse") +## debug("parsed XML tree %s", tree) +## debug("parsed root node %s", tree.getroot()) +## debug("root node tag %s", tree.getroot().tag) +## return llsd.to_python(tree.getroot()) + + def do_HEAD(self): + self.do_GET(withdata=False) + + def do_GET(self, withdata=True): + # Of course, don't attempt to read data. + self.answer(dict(reply="success", status=200, + reason="Your GET operation worked")) + + def do_POST(self): + # Read the provided POST data. + # self.answer(self.read()) + self.answer(dict(reply="success", status=200, + reason=self.read())) + + def do_PUT(self): + # Read the provided PUT data. + # self.answer(self.read()) + self.answer(dict(reply="success", status=200, + reason=self.read())) + + def answer(self, data, withdata=True): + debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path) + if "/sleep/" in self.path: + time.sleep(30) + + if "fail" not in self.path: + data = data.copy() # we're going to modify + # Ensure there's a "reply" key in data, even if there wasn't before + data["reply"] = data.get("reply", llsd.LLSD("success")) + response = llsd.format_xml(data) + debug("success: %s", response) + self.send_response(200) + if "/reflect/" in self.path: + self.reflect_headers() + self.send_header("Content-type", "application/llsd+xml") + self.send_header("Content-Length", str(len(response))) + self.send_header("X-LL-Special", "Mememememe"); + self.end_headers() + if withdata: + self.wfile.write(response) + else: # fail requested + status = data.get("status", 500) + # self.responses maps an int status to a (short, long) pair of + # strings. We want the longer string. That's why we pass a string + # pair to get(): the [1] will select the second string, whether it + # came from self.responses or from our default pair. + reason = data.get("reason", + self.responses.get(status, + ("fail requested", + "Your request specified failure status %s " + "without providing a reason" % status))[1]) + debug("fail requested: %s: %r", status, reason) + self.send_error(status, reason) + if "/reflect/" in self.path: + self.reflect_headers() + self.end_headers() + + def reflect_headers(self): + for name in self.headers.keys(): + # print "Header: %s: %s" % (name, self.headers[name]) + self.send_header("X-Reflect-" + name, self.headers[name]) + + if not VERBOSE: + # When VERBOSE is set, skip both these overrides because they exist to + # suppress output. + + 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 Server(ThreadingMixIn, HTTPServer): + # This pernicious flag is on by default in HTTPServer. But proper + # operation of freeport() absolutely depends on it being off. + allow_reuse_address = False + +if __name__ == "__main__": + do_valgrind = False + path_search = False + options, args = getopt.getopt(sys.argv[1:], "V", ["valgrind"]) + for option, value in options: + if option == "-V" or option == "--valgrind": + do_valgrind = True + + # Instantiate a Server(TestHTTPRequestHandler) on the first free port + # in the specified port range. Doing this inline is better than in a + # daemon thread: if it blows up here, we'll get a traceback. If it blew up + # in some other thread, the traceback would get eaten and we'd run the + # subject test program anyway. + httpd, port = freeport(xrange(8000, 8020), + lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) + + # Pass the selected port number to the subject test program via the + # environment. We don't want to impose requirements on the test program's + # command-line parsing -- and anyway, for C++ integration tests, that's + # performed in TUT code rather than our own. + os.environ["LL_TEST_PORT"] = str(port) + debug("$LL_TEST_PORT = %s", port) + if do_valgrind: + args = ["valgrind", "--log-file=./valgrind.log"] + args + path_search = True + sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), use_path=path_search, *args)) diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp new file mode 100644 index 0000000000..cb4b50287a --- /dev/null +++ b/indra/llcorehttp/tests/test_refcounted.hpp @@ -0,0 +1,156 @@ +/** + * @file test_refcounted.hpp + * @brief unit tests for the LLCoreInt::RefCounted class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#ifndef TEST_LLCOREINT_REF_COUNTED_H_ +#define TEST_LLCOREINT_REF_COUNTED_H_ + +#include "_refcounted.h" + +#include "test_allocator.h" + +using namespace LLCoreInt; + +namespace tut +{ + struct RefCountedTestData + { + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + size_t mMemTotal; + }; + + typedef test_group<RefCountedTestData> RefCountedTestGroupType; + typedef RefCountedTestGroupType::object RefCountedTestObjectType; + RefCountedTestGroupType RefCountedTestGroup("RefCounted Tests"); + + template <> template <> + void RefCountedTestObjectType::test<1>() + { + set_test_name("RefCounted construction with implicit count"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + RefCounted * rc = new RefCounted(true); + ensure(rc->getRefCount() == 1); + + // release the implicit reference, causing the object to be released + rc->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); + } + + template <> template <> + void RefCountedTestObjectType::test<2>() + { + set_test_name("RefCounted construction without implicit count"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + // create a new ref counted object with an implicit reference + RefCounted * rc = new RefCounted(false); + ensure(rc->getRefCount() == 0); + + // add a reference + rc->addRef(); + ensure(rc->getRefCount() == 1); + + // release the implicit reference, causing the object to be released + rc->release(); + + ensure(mMemTotal == GetMemTotal()); + } + + template <> template <> + void RefCountedTestObjectType::test<3>() + { + set_test_name("RefCounted addRef and release"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + RefCounted * rc = new RefCounted(false); + + for (int i = 0; i < 1024; ++i) + { + rc->addRef(); + } + + ensure(rc->getRefCount() == 1024); + + for (int i = 0; i < 1024; ++i) + { + rc->release(); + } + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); + } + + template <> template <> + void RefCountedTestObjectType::test<4>() + { + set_test_name("RefCounted isLastRef check"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + RefCounted * rc = new RefCounted(true); + + // with only one reference, isLastRef should be true + ensure(rc->isLastRef()); + + // release it to clean up memory + rc->release(); + + // make sure we didn't leak any memory + ensure(mMemTotal == GetMemTotal()); + } + + template <> template <> + void RefCountedTestObjectType::test<5>() + { + set_test_name("RefCounted noRef check"); + + // record the total amount of dynamically allocated memory + mMemTotal = GetMemTotal(); + + RefCounted * rc = new RefCounted(false); + + // set the noRef + rc->noRef(); + + // with only one reference, isLastRef should be true + ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED); + + // allow this memory leak, but check that we're leaking a known amount + ensure(mMemTotal == (GetMemTotal() - sizeof(RefCounted))); + } +} + +#endif // TEST_LLCOREINT_REF_COUNTED_H_ diff --git a/indra/llcorehttp/tests/testrunner.py b/indra/llcorehttp/tests/testrunner.py new file mode 100644 index 0000000000..9a2de71142 --- /dev/null +++ b/indra/llcorehttp/tests/testrunner.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python +"""\ +@file testrunner.py +@author Nat Goodspeed +@date 2009-03-20 +@brief Utilities for writing wrapper scripts for ADD_COMM_BUILD_TEST unit tests + +$LicenseInfo:firstyear=2009&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2010, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +from __future__ import with_statement + +import os +import sys +import re +import errno +import socket + +VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet +# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if +# that construct actually turns on verbosity... +VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE) + +if VERBOSE: + def debug(fmt, *args): + print fmt % args + sys.stdout.flush() +else: + debug = lambda *args: None + +def freeport(portlist, expr): + """ + Find a free server port to use. Specifically, evaluate 'expr' (a + callable(port)) until it stops raising EADDRINUSE exception. + + Pass: + + portlist: an iterable (e.g. xrange()) of ports to try. If you exhaust the + range, freeport() lets the socket.error exception propagate. If you want + unbounded, you could pass itertools.count(baseport), though of course in + practice the ceiling is 2^16-1 anyway. But it seems prudent to constrain + the range much more sharply: if we're iterating an absurd number of times, + probably something else is wrong. + + expr: a callable accepting a port number, specifically one of the items + from portlist. If calling that callable raises socket.error with + EADDRINUSE, freeport() retrieves the next item from portlist and retries. + + Returns: (expr(port), port) + + port: the value from portlist for which expr(port) succeeded + + Raises: + + Any exception raised by expr(port) other than EADDRINUSE. + + socket.error if, for every item from portlist, expr(port) raises + socket.error. The exception you see is the one from the last item in + portlist. + + StopIteration if portlist is completely empty. + + Example: + + class Server(HTTPServer): + # If you use BaseHTTPServer.HTTPServer, turning off this flag is + # essential for proper operation of freeport()! + allow_reuse_address = False + # ... + server, port = freeport(xrange(8000, 8010), + lambda port: Server(("localhost", port), + MyRequestHandler)) + # pass 'port' to client code + # call server.serve_forever() + """ + try: + # If portlist is completely empty, let StopIteration propagate: that's an + # error because we can't return meaningful values. We have no 'port', + # therefore no 'expr(port)'. + portiter = iter(portlist) + port = portiter.next() + + while True: + try: + # If this value of port works, return as promised. + value = expr(port) + + except socket.error, err: + # Anything other than 'Address already in use', propagate + if err.args[0] != errno.EADDRINUSE: + raise + + # Here we want the next port from portiter. But on StopIteration, + # we want to raise the original exception rather than + # StopIteration. So save the original exc_info(). + type, value, tb = sys.exc_info() + try: + try: + port = portiter.next() + except StopIteration: + raise type, value, tb + finally: + # Clean up local traceback, see docs for sys.exc_info() + del tb + + else: + debug("freeport() returning %s on port %s", value, port) + return value, port + + # Recap of the control flow above: + # If expr(port) doesn't raise, return as promised. + # If expr(port) raises anything but EADDRINUSE, propagate that + # exception. + # If portiter.next() raises StopIteration -- that is, if the port + # value we just passed to expr(port) was the last available -- reraise + # the EADDRINUSE exception. + # If we've actually arrived at this point, portiter.next() delivered a + # new port value. Loop back to pass that to expr(port). + + except Exception, err: + debug("*** freeport() raising %s: %s", err.__class__.__name__, err) + raise + +def run(*args, **kwds): + """All positional arguments collectively form a command line, executed as + a synchronous child process. + In addition, pass server=new_thread_instance as an explicit keyword (to + differentiate it from an additional command-line argument). + new_thread_instance should be an instantiated but not yet started Thread + subclass instance, e.g.: + run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd")) + """ + # If there's no server= keyword arg, don't start a server thread: simply + # run a child process. + try: + thread = kwds.pop("server") + except KeyError: + pass + else: + # Start server thread. Note that this and all other comm server + # threads should be daemon threads: we'll let them run "forever," + # confident that the whole process will terminate when the main thread + # terminates, which will be when the child process terminates. + thread.setDaemon(True) + thread.start() + # choice of os.spawnv(): + # - [v vs. l] pass a list of args vs. individual arguments, + # - [no p] don't use the PATH because we specifically want to invoke the + # executable passed as our first arg, + # - [no e] child should inherit this process's environment. + debug("Running %s...", " ".join(args)) + if kwds.get("use_path", False): + rc = os.spawnvp(os.P_WAIT, args[0], args) + else: + rc = os.spawnv(os.P_WAIT, args[0], args) + debug("%s returned %s", args[0], rc) + return rc + +# **************************************************************************** +# test code -- manual at this point, see SWAT-564 +# **************************************************************************** +def test_freeport(): + # ------------------------------- Helpers -------------------------------- + from contextlib import contextmanager + # helper Context Manager for expecting an exception + # with exc(SomeError): + # raise SomeError() + # raises AssertionError otherwise. + @contextmanager + def exc(exception_class, *args): + try: + yield + except exception_class, err: + for i, expected_arg in enumerate(args): + assert expected_arg == err.args[i], \ + "Raised %s, but args[%s] is %r instead of %r" % \ + (err.__class__.__name__, i, err.args[i], expected_arg) + print "Caught expected exception %s(%s)" % \ + (err.__class__.__name__, ', '.join(repr(arg) for arg in err.args)) + else: + assert False, "Failed to raise " + exception_class.__class__.__name__ + + # helper to raise specified exception + def raiser(exception): + raise exception + + # the usual + def assert_equals(a, b): + assert a == b, "%r != %r" % (a, b) + + # ------------------------ Sanity check the above ------------------------ + class SomeError(Exception): pass + # Without extra args, accept any err.args value + with exc(SomeError): + raiser(SomeError("abc")) + # With extra args, accept only the specified value + with exc(SomeError, "abc"): + raiser(SomeError("abc")) + with exc(AssertionError): + with exc(SomeError, "abc"): + raiser(SomeError("def")) + with exc(AssertionError): + with exc(socket.error, errno.EADDRINUSE): + raiser(socket.error(errno.ECONNREFUSED, 'Connection refused')) + + # ----------- freeport() without engaging socket functionality ----------- + # If portlist is empty, freeport() raises StopIteration. + with exc(StopIteration): + freeport([], None) + + assert_equals(freeport([17], str), ("17", 17)) + + # This is the magic exception that should prompt us to retry + inuse = socket.error(errno.EADDRINUSE, 'Address already in use') + # Get the iterator to our ports list so we can check later if we've used all + ports = iter(xrange(5)) + with exc(socket.error, errno.EADDRINUSE): + freeport(ports, lambda port: raiser(inuse)) + # did we entirely exhaust 'ports'? + with exc(StopIteration): + ports.next() + + ports = iter(xrange(2)) + # Any exception but EADDRINUSE should quit immediately + with exc(SomeError): + freeport(ports, lambda port: raiser(SomeError())) + assert_equals(ports.next(), 1) + + # ----------- freeport() with platform-dependent socket stuff ------------ + # This is what we should've had unit tests to begin with (see CHOP-661). + def newbind(port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.bind(('127.0.0.1', port)) + return sock + + bound0, port0 = freeport(xrange(7777, 7780), newbind) + assert_equals(port0, 7777) + bound1, port1 = freeport(xrange(7777, 7780), newbind) + assert_equals(port1, 7778) + bound2, port2 = freeport(xrange(7777, 7780), newbind) + assert_equals(port2, 7779) + with exc(socket.error, errno.EADDRINUSE): + bound3, port3 = freeport(xrange(7777, 7780), newbind) + +if __name__ == "__main__": + test_freeport() diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 825878c5ef..916c346b7a 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -292,11 +292,16 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components) ++sRawImageCount; } -LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components) +LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy) : LLImageBase() { mMemType = LLMemType::MTYPE_IMAGERAW; - if(allocateDataSize(width, height, components)) + + if(no_copy) + { + setDataAndSize(data, width, height, components); + } + else if(allocateDataSize(width, height, components)) { memcpy(getData(), data, width*height*components); } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 9ce77a0d01..5f54585005 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -189,7 +189,7 @@ protected: public: LLImageRaw(); LLImageRaw(U16 width, U16 height, S8 components); - LLImageRaw(U8 *data, U16 width, U16 height, S8 components); + LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false); // Construct using createFromFile (used by tools) //LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false); diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 452aad25cb..452aad25cb 100644..100755 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 433076c7a9..a871bcbb25 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -193,8 +193,6 @@ void LLParcel::init(const LLUUID &owner_id, mMediaWidth = 0; mMediaHeight = 0; setMediaCurrentURL(LLStringUtil::null); - mMediaURLFilterEnable = FALSE; - mMediaURLFilterList = LLSD::emptyArray(); mMediaAllowNavigate = TRUE; mMediaURLTimeout = 0.0f; mMediaPreventCameraZoom = FALSE; @@ -336,38 +334,6 @@ void LLParcel::setMediaURLResetTimer(F32 time) mMediaResetTimer.setTimerExpirySec(time); } -void LLParcel::setMediaURLFilterList(LLSD list) -{ - // sanity check LLSD - // must be array of strings - if (!list.isArray()) - { - return; - } - - for (S32 i = 0; i < list.size(); i++) - { - if (!list[i].isString()) - return; - } - - // can't be too big - const S32 MAX_SIZE = 50; - if (list.size() > MAX_SIZE) - { - LLSD new_list = LLSD::emptyArray(); - - for (S32 i = 0; i < llmin(list.size(), MAX_SIZE); i++) - { - new_list.append(list[i]); - } - - list = new_list; - } - - mMediaURLFilterList = list; -} - // virtual void LLParcel::setLocalID(S32 local_id) { @@ -622,34 +588,6 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr return input_stream.good(); } -BOOL LLParcel::importMediaURLFilter(std::istream& input_stream, std::string& url) -{ - skip_to_end_of_next_keyword("{", input_stream); - - while(input_stream.good()) - { - skip_comments_and_emptyspace(input_stream); - std::string line, keyword, value; - get_line(line, input_stream, MAX_STRING); - get_keyword_and_value(keyword, value, line); - - if ("}" == keyword) - { - break; - } - else if ("url" == keyword) - { - url = value; - } - else - { - llwarns << "Unknown keyword in parcel media url filter section: <" - << keyword << ">" << llendl; - } - } - return input_stream.good(); -} - // Assumes we are in a block "ParcelData" void LLParcel::packMessage(LLMessageSystem* msg) { @@ -696,8 +634,6 @@ void LLParcel::packMessage(LLSD& msg) msg["media_allow_navigate"] = getMediaAllowNavigate(); msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom(); msg["media_url_timeout"] = getMediaURLTimeout(); - msg["media_url_filter_enable"] = getMediaURLFilterEnable(); - msg["media_url_filter_list"] = getMediaURLFilterList(); msg["group_id"] = getGroupID(); msg["pass_price"] = mPassPrice; msg["pass_hours"] = mPassHours; @@ -789,7 +725,6 @@ void LLParcel::unpackMessage(LLMessageSystem* msg) msg->getString("MediaLinkSharing", "MediaCurrentURL", buffer); setMediaCurrentURL(buffer); msg->getU8 ( "MediaLinkSharing", "MediaAllowNavigate", mMediaAllowNavigate ); - msg->getU8 ( "MediaLinkSharing", "MediaURLFilterEnable", mMediaURLFilterEnable ); msg->getU8 ( "MediaLinkSharing", "MediaPreventCameraZoom", mMediaPreventCameraZoom ); msg->getF32( "MediaLinkSharing", "MediaURLTimeout", mMediaURLTimeout); } @@ -1250,8 +1185,6 @@ void LLParcel::clearParcel() mMediaWidth = 0; mMediaHeight = 0; setMediaCurrentURL(LLStringUtil::null); - setMediaURLFilterList(LLSD::emptyArray()); - setMediaURLFilterEnable(FALSE); setMediaAllowNavigate(TRUE); setMediaPreventCameraZoom(FALSE); setMediaURLTimeout(0.0f); diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index f0b2caca3d..499f690e76 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -247,8 +247,6 @@ public: void setMediaWidth(S32 width); void setMediaHeight(S32 height); void setMediaCurrentURL(const std::string& url); - void setMediaURLFilterEnable(U8 enable) { mMediaURLFilterEnable = enable; } - void setMediaURLFilterList(LLSD list); void setMediaAllowNavigate(U8 enable) { mMediaAllowNavigate = enable; } void setMediaURLTimeout(F32 timeout) { mMediaURLTimeout = timeout; } void setMediaPreventCameraZoom(U8 enable) { mMediaPreventCameraZoom = enable; } @@ -310,7 +308,6 @@ public: // BOOL importStream(std::istream& input_stream); BOOL importAccessEntry(std::istream& input_stream, LLAccessEntry* entry); - BOOL importMediaURLFilter(std::istream& input_stream, std::string& url); // BOOL exportStream(std::ostream& output_stream); void packMessage(LLMessageSystem* msg); @@ -354,8 +351,6 @@ public: U8 getMediaAutoScale() const { return mMediaAutoScale; } U8 getMediaLoop() const { return mMediaLoop; } const std::string& getMediaCurrentURL() const { return mMediaCurrentURL; } - U8 getMediaURLFilterEnable() const { return mMediaURLFilterEnable; } - LLSD getMediaURLFilterList() const { return mMediaURLFilterList; } U8 getMediaAllowNavigate() const { return mMediaAllowNavigate; } F32 getMediaURLTimeout() const { return mMediaURLTimeout; } U8 getMediaPreventCameraZoom() const { return mMediaPreventCameraZoom; } @@ -651,8 +646,6 @@ protected: U8 mMediaLoop; std::string mMediaCurrentURL; LLUUID mMediaID; - U8 mMediaURLFilterEnable; - LLSD mMediaURLFilterList; U8 mMediaAllowNavigate; U8 mMediaPreventCameraZoom; F32 mMediaURLTimeout; diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index cf88de12b4..0c0a844b73 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1179,7 +1179,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap) llassert(mDims == comp_dims); // Safety check; the caller has ensured this } bool use_shorts = (mComps[c].get_bit_depth(true) <= 16); - mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts); + mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts,0,0); if (res.which() == 0) // No DWT levels used { mEngines[c] = kdu_decoder(res.access_subband(LL_BAND),&mAllocator,use_shorts); @@ -1223,7 +1223,7 @@ separation between consecutive rows in the real buffer. */ { for (c = 0; c < mNumComponents; c++) { - mEngines[c].pull(mLines[c],true); + mEngines[c].pull(mLines[c]); } if ((mNumComponents >= 3) && mUseYCC) { diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 9ab0b9e4a7..fb1f6535ba 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -32,6 +32,7 @@ // // KDU core header files // +#define KDU_NO_THREADS #include "kdu_elementary.h" #include "kdu_messaging.h" #include "kdu_params.h" diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index 9d923fc367..dbdf88b2d9 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -28,6 +28,7 @@ #define LL_LLKDUMEM_H // Support classes for reading and writing from memory buffers in KDU +#define KDU_NO_THREADS #include "kdu_image.h" #include "kdu_elementary.h" #include "kdu_messaging.h" diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index beee99a522..b675153b2e 100644..100755 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -127,7 +127,6 @@ kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; } void kdu_resolution::get_dims(kdu_dims& ) { } int kdu_resolution::which() { return 0; } int kdu_resolution::get_valid_band_indices(int &) { return 1; } -kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { } kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { } kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { } kdu_params::~kdu_params() { } @@ -153,7 +152,6 @@ void kdu_codestream::destroy() { } void kdu_codestream::collect_timing_stats(int ) { } void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { } void kdu_codestream::get_valid_tiles(kdu_dims& ) { } -void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { } void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { } void kdu_codestream::apply_input_restrictions( int, int, int, int, kdu_dims*, kdu_component_access_mode ) { } void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { } @@ -175,7 +173,7 @@ kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return N bool kdu_codestream_comment::put_text(const char*) { return false; } void kdu_customize_warnings(kdu_message*) { } void kdu_customize_errors(kdu_message*) { } -void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { } + kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, bool, kdu_roi_image*, bool, int, kdu_thread_env*, kdu_thread_queue*, bool ) { kdu_long a = 0; return a; } siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { } void siz_params::finalize(bool ) { } @@ -184,6 +182,21 @@ int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0; bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; } bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; } +#ifdef LL_LINUX +// Linux use the old pre KDU v7.0.0 +// *TODO: Supress this legacy stubbs once Linux migrates to v7.0.0 +kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { } +void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { } +void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { } +#else +kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*, int) { } +void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long, kdu_thread_env* ) { } +void (*kdu_convert_ycc_to_rgb_rev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); +void (*kdu_convert_ycc_to_rgb_irrev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); +void (*kdu_convert_ycc_to_rgb_rev32)(kdu_int32*,kdu_int32*,kdu_int32*,int); +void (*kdu_convert_ycc_to_rgb_irrev32)(float*,float*,float*,int); +#endif + // ------------------------------------------------------------------------------------------- // TUT // ------------------------------------------------------------------------------------------- diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 56cb2ae73e..daf3a6857b 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -33,6 +33,7 @@ class LLVector4; #include "llerror.h" #include "llmath.h" #include "llsd.h" +#include <string.h> // LLColor3 = |r g b| diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index ff31f7665e..700525e1fa 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -87,6 +87,9 @@ namespace LLAvatarNameCache /// Time when unrefreshed cached names were checked last static F64 sLastExpireCheck; + /// Time-to-live for a temp cache entry. + const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; + //----------------------------------------------------------------------- // Internal methods //----------------------------------------------------------------------- @@ -274,7 +277,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) { // there is no existing cache entry, so make a temporary name from legacy LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent " - << agent_id << LL_ENDL; + << agent_id << LL_ENDL; gCacheName->get(agent_id, false, // legacy compatibility boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3)); @@ -287,13 +290,14 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) // Clear this agent from the pending list LLAvatarNameCache::sPendingQueue.erase(agent_id); - const LLAvatarName& av_name = existing->second; + LLAvatarName& av_name = existing->second; LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << "user '" << av_name.mUsername << "' " << "display '" << av_name.mDisplayName << "' " << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds" << LL_ENDL; + av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest. } } @@ -330,8 +334,9 @@ void LLAvatarNameCache::requestNamesViaCapability() // http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0 // // Apache can handle URLs of 4096 chars, but let's be conservative - const U32 NAME_URL_MAX = 4096; - const U32 NAME_URL_SEND_THRESHOLD = 3000; + static const U32 NAME_URL_MAX = 4096; + static const U32 NAME_URL_SEND_THRESHOLD = 3500; + std::string url; url.reserve(NAME_URL_MAX); @@ -339,10 +344,12 @@ void LLAvatarNameCache::requestNamesViaCapability() agent_ids.reserve(128); U32 ids = 0; - ask_queue_t::const_iterator it = sAskQueue.begin(); - for ( ; it != sAskQueue.end(); ++it) + ask_queue_t::const_iterator it; + while(!sAskQueue.empty()) { + it = sAskQueue.begin(); const LLUUID& agent_id = *it; + sAskQueue.erase(it); if (url.empty()) { @@ -365,27 +372,17 @@ void LLAvatarNameCache::requestNamesViaCapability() if (url.size() > NAME_URL_SEND_THRESHOLD) { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first " - << ids << " ids" - << LL_ENDL; - LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids)); - url.clear(); - agent_ids.clear(); + break; } } if (!url.empty()) { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all " + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested " << ids << " ids" << LL_ENDL; LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids)); - url.clear(); - agent_ids.clear(); } - - // We've moved all asks to the pending request queue - sAskQueue.clear(); } void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, @@ -402,20 +399,25 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, << LL_ENDL; buildLegacyName(full_name, &av_name); - // Don't add to cache, the data already exists in the legacy name system - // cache and we don't want or need duplicate storage, because keeping the - // two copies in sync is complex. - processName(agent_id, av_name, false); + // Add to cache, because if we don't we'll keep rerequesting the + // same record forever. buildLegacyName should always guarantee + // that these records expire reasonably soon + // (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due + // to something temporary we will eventually request and get the right data. + processName(agent_id, av_name, true); } void LLAvatarNameCache::requestNamesViaLegacy() { + static const S32 MAX_REQUESTS = 100; F64 now = LLFrameTimer::getTotalSeconds(); std::string full_name; - ask_queue_t::const_iterator it = sAskQueue.begin(); - for (; it != sAskQueue.end(); ++it) + ask_queue_t::const_iterator it; + for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests) { + it = sAskQueue.begin(); const LLUUID& agent_id = *it; + sAskQueue.erase(it); // Mark as pending first, just in case the callback is immediately // invoked below. This should never happen in practice. @@ -427,10 +429,6 @@ void LLAvatarNameCache::requestNamesViaLegacy() boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3)); } - - // We've either answered immediately or moved all asks to the - // pending queue - sAskQueue.clear(); } void LLAvatarNameCache::initClass(bool running) @@ -507,11 +505,11 @@ void LLAvatarNameCache::idle() // *TODO: Possibly re-enabled this based on People API load measurements // 100 ms is the threshold for "user speed" operations, so we can // stall for about that long to batch up requests. - //const F32 SECS_BETWEEN_REQUESTS = 0.1f; - //if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) - //{ - // return; - //} + const F32 SECS_BETWEEN_REQUESTS = 0.1f; + if (!sRequestTimer.hasExpired()) + { + return; + } if (!sAskQueue.empty()) { @@ -526,6 +524,12 @@ void LLAvatarNameCache::idle() } } + if (sAskQueue.empty()) + { + // cleared the list, reset the request timer. + sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS); + } + // erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME eraseUnrefreshed(); } @@ -583,7 +587,7 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name, av_name->mDisplayName = full_name; av_name->mIsDisplayNameDefault = true; av_name->mIsTemporaryName = true; - av_name->mExpires = F64_MAX; // not used because these are not cached + av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName " << full_name << LL_ENDL; @@ -737,12 +741,6 @@ void LLAvatarNameCache::erase(const LLUUID& agent_id) sCache.erase(agent_id); } -void LLAvatarNameCache::fetch(const LLUUID& agent_id) -{ - // re-request, even if request is already pending - sAskQueue.insert(agent_id); -} - void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name) { // *TODO: update timestamp if zero? diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 064942fe53..79f170f7c8 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -86,10 +86,6 @@ namespace LLAvatarNameCache /// Provide some fallback for agents that return errors void handleAgentError(const LLUUID& agent_id); - // Force a re-fetch of the most recent data, but keep the current - // data in cache - void fetch(const LLUUID& agent_id); - void insert(const LLUUID& agent_id, const LLAvatarName& av_name); // Compute name expiration time from HTTP Cache-Control header, diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 10c83e6572..8ffa8e4271 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -294,6 +294,8 @@ LLCurl::Easy* LLCurl::Easy::getEasy() // multi handles cache if they are added to one. CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); check_curl_code(result); + result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + check_curl_code(result); ++gCurlEasyCount; return easy; @@ -482,7 +484,8 @@ void LLCurl::Easy::prepRequest(const std::string& url, //setopt(CURLOPT_VERBOSE, 1); // useful for debugging setopt(CURLOPT_NOSIGNAL, 1); - + setopt(CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + // Set the CURL options for either Socks or HTTP proxy LLProxy::getInstance()->applyProxySettings(this); @@ -938,8 +941,8 @@ bool LLCurlThread::CurlRequest::processRequest() if(!completed) { - setPriority(LLQueuedThread::PRIORITY_LOW) ; - } + setPriority(LLQueuedThread::PRIORITY_LOW) ; + } } return completed ; @@ -949,7 +952,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed) { if(mMulti->isDead()) { - mCurlThread->deleteMulti(mMulti) ; + mCurlThread->deleteMulti(mMulti) ; } else { @@ -993,6 +996,7 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi) return ; } + multi->markDead() ; } @@ -1098,7 +1102,9 @@ void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder) { getByteRange(url, headers_t(), 0, -1, responder); } - + +// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or +// the remainder of the file if not. bool LLCurlRequest::getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, @@ -1117,6 +1123,11 @@ bool LLCurlRequest::getByteRange(const std::string& url, std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1); easy->slist_append(range.c_str()); } + else if (offset > 0) + { + std::string range = llformat("Range: bytes=%d-", offset); + easy->slist_append(range.c_str()); + } easy->setHeaders(); bool res = addEasy(easy); return res; @@ -1244,6 +1255,208 @@ S32 LLCurlRequest::getQueued() return queued; } +LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) : + LLCurlRequest(), + mConcurrency(concurrency), + mInQueue(0), + mMutex(NULL), + mHandleCounter(1), + mTotalIssuedRequests(0), + mTotalReceivedBits(0) +{ + mGlobalTimer.reset(); +} + +LLCurlTextureRequest::~LLCurlTextureRequest() +{ + mRequestMap.clear(); + + for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter) + { + delete *iter; + } + mCachedRequests.clear(); +} + +//return 0: success +// > 0: cached handle +U32 LLCurlTextureRequest::getByteRange(const std::string& url, + const headers_t& headers, + S32 offset, S32 length, U32 pri, + LLCurl::ResponderPtr responder, F32 delay_time) +{ + U32 ret_val = 0; + bool success = false; + + if(mInQueue < mConcurrency && delay_time < 0.f) + { + success = LLCurlRequest::getByteRange(url, headers, offset, length, responder); + } + + LLMutexLock lock(&mMutex); + + if(success) + { + mInQueue++; + mTotalIssuedRequests++; + } + else + { + request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder); + if(delay_time > 0.f) + { + request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time; + } + + mCachedRequests.insert(request); + mRequestMap[mHandleCounter] = request; + ret_val = mHandleCounter; + mHandleCounter++; + + if(!mHandleCounter) + { + mHandleCounter = 1; + } + } + + return ret_val; +} + +void LLCurlTextureRequest::completeRequest(S32 received_bytes) +{ + LLMutexLock lock(&mMutex); + + llassert_always(mInQueue > 0); + + mInQueue--; + mTotalReceivedBits += received_bytes * 8; +} + +void LLCurlTextureRequest::nextRequests() +{ + if(mCachedRequests.empty() || mInQueue >= mConcurrency) + { + return; + } + + F32 cur_time = mGlobalTimer.getElapsedTimeF32(); + + req_queue_t::iterator iter; + { + LLMutexLock lock(&mMutex); + iter = mCachedRequests.begin(); + } + while(1) + { + request_t* request = *iter; + if(request->mStartTime < cur_time) + { + if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder)) + { + break; + } + + LLMutexLock lock(&mMutex); + ++iter; + mInQueue++; + mTotalIssuedRequests++; + mCachedRequests.erase(request); + mRequestMap.erase(request->mHandle); + delete request; + + if(iter == mCachedRequests.end() || mInQueue >= mConcurrency) + { + break; + } + } + else + { + LLMutexLock lock(&mMutex); + ++iter; + if(iter == mCachedRequests.end() || mInQueue >= mConcurrency) + { + break; + } + } + } + + return; +} + +void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri) +{ + if(!handle) + { + return; + } + + LLMutexLock lock(&mMutex); + + std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle); + if(iter != mRequestMap.end()) + { + request_t* req = iter->second; + + if(req->mPriority != pri) + { + mCachedRequests.erase(req); + req->mPriority = pri; + mCachedRequests.insert(req); + } + } +} + +void LLCurlTextureRequest::removeRequest(U32 handle) +{ + if(!handle) + { + return; + } + + LLMutexLock lock(&mMutex); + + std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle); + if(iter != mRequestMap.end()) + { + request_t* req = iter->second; + mRequestMap.erase(iter); + mCachedRequests.erase(req); + delete req; + } +} + +bool LLCurlTextureRequest::isWaiting(U32 handle) +{ + if(!handle) + { + return false; + } + + LLMutexLock lock(&mMutex); + return mRequestMap.find(handle) != mRequestMap.end(); +} + +U32 LLCurlTextureRequest::getTotalReceivedBits() +{ + LLMutexLock lock(&mMutex); + + U32 bits = mTotalReceivedBits; + mTotalReceivedBits = 0; + return bits; +} + +U32 LLCurlTextureRequest::getTotalIssuedRequests() +{ + LLMutexLock lock(&mMutex); + return mTotalIssuedRequests; +} + +S32 LLCurlTextureRequest::getNumRequests() +{ + LLMutexLock lock(&mMutex); + return mInQueue; +} + //////////////////////////////////////////////////////////////////////////// // For generating one easy request // associated with a single multi request diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 62947bdb9d..7bcf61e233 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -407,6 +407,71 @@ private: BOOL mProcessing; }; +//for texture fetch only +class LLCurlTextureRequest : public LLCurlRequest +{ +public: + LLCurlTextureRequest(S32 concurrency); + ~LLCurlTextureRequest(); + + U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder, F32 delay_time = -1.f); + void nextRequests(); + void completeRequest(S32 received_bytes); + + void updatePriority(U32 handle, U32 pri); + void removeRequest(U32 handle); + + U32 getTotalReceivedBits(); + U32 getTotalIssuedRequests(); + S32 getNumRequests(); + bool isWaiting(U32 handle); + +private: + LLMutex mMutex; + S32 mConcurrency; + S32 mInQueue; //request currently in queue. + U32 mHandleCounter; + U32 mTotalIssuedRequests; + U32 mTotalReceivedBits; + + typedef struct _request_t + { + _request_t(U32 handle, const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder) : + mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder), mStartTime(0.f) + {} + + U32 mHandle; + std::string mUrl; + LLCurlRequest::headers_t mHeaders; + S32 mOffset; + S32 mLength; + LLCurl::ResponderPtr mResponder; + U32 mPriority; + F32 mStartTime; //start time to issue this request + } request_t; + + struct request_compare + { + bool operator()(const request_t* lhs, const request_t* rhs) const + { + if(lhs->mPriority != rhs->mPriority) + { + return lhs->mPriority > rhs->mPriority; // higher priority in front of queue (set) + } + else + { + return (U32)lhs < (U32)rhs; + } + } + }; + + typedef std::set<request_t*, request_compare> req_queue_t; + req_queue_t mCachedRequests; + std::map<S32, request_t*> mRequestMap; + + LLFrameTimer mGlobalTimer; +}; + class LLCurlEasyRequest { public: diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index 612d765969..d6ed08055e 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -749,7 +749,7 @@ LLAssetRequest* LLHTTPAssetStorage::findNextRequest(LLAssetStorage::request_list request_list_t::iterator pending_iter = pending.begin(); request_list_t::iterator pending_end = pending.end(); // Loop over all pending requests until we miss finding it in the running list. - for (; pending_iter != pending.end(); ++pending_iter) + for (; pending_iter != pending_end; ++pending_iter) { LLAssetRequest* req = *pending_iter; // Look for this pending request in the running list. diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 30532247ac..6dee192783 100644..100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -149,7 +149,8 @@ bool LLPrimitive::cleanupVolumeManager() LLPrimitive::LLPrimitive() : mTextureList(), mNumTEs(0), - mMiscFlags(0) + mMiscFlags(0), + mNumBumpmapTEs(0) { mPrimitiveCode = 0; @@ -237,7 +238,10 @@ void LLPrimitive::setAllTETextures(const LLUUID &tex_id) //=============================================================== void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) { - mTextureList.copyTexture(index, te); + if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0) + { + mNumBumpmapTEs++; + } } S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id) @@ -316,6 +320,7 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r) //=============================================================== S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) { + updateNumBumpmap(index, bump); return mTextureList.setBumpShinyFullbright(index, bump); } @@ -326,11 +331,13 @@ S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media) S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump) { + updateNumBumpmap(index, bump); return mTextureList.setBumpMap(index, bump); } S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny) { + updateNumBumpmap(index, bump_shiny); return mTextureList.setBumpShiny(index, bump_shiny); } @@ -1445,6 +1452,26 @@ void LLPrimitive::takeTextureList(LLPrimTextureList& other_list) mTextureList.take(other_list); } +void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump) +{ + LLTextureEntry* te = getTE(index); + if(!te) + { + return; + } + + U8 old_bump = te->getBumpmap(); + if(old_bump > 0) + { + mNumBumpmapTEs--; + } + if((bump & TEM_BUMP_MASK) > 0) + { + mNumBumpmapTEs++; + } + + return; +} //============================================================================ // Moved from llselectmgr.cpp diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 998016f8f6..8dcaa8c740 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -421,7 +421,8 @@ public: inline BOOL isAvatar() const; inline BOOL isSittingAvatar() const; inline BOOL isSittingAvatarOnGround() const; - + inline bool hasBumpmap() const { return mNumBumpmapTEs > 0;} + void setFlags(U32 flags) { mMiscFlags = flags; } void addFlags(U32 flags) { mMiscFlags |= flags; } void removeFlags(U32 flags) { mMiscFlags &= ~flags; } @@ -435,6 +436,9 @@ public: inline static BOOL isPrimitive(const LLPCode pcode); inline static BOOL isApp(const LLPCode pcode); +private: + void updateNumBumpmap(const U8 index, const U8 bump); + protected: LLPCode mPrimitiveCode; // Primitive code LLVector3 mVelocity; // how fast are we moving? @@ -444,6 +448,7 @@ protected: LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets U8 mMaterial; // Material code U8 mNumTEs; // # of faces on the primitve + U8 mNumBumpmapTEs; // number of bumpmap TEs. U32 mMiscFlags; // home for misc bools public: diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 4dc2fcd714..647512eb2e 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -789,7 +789,7 @@ const LLFontDescriptor& LLFontGL::getFontDesc() const } // static -void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures) +void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures) { sVertDPI = (F32)llfloor(screen_dpi * y_scale); sHorizDPI = (F32)llfloor(screen_dpi * x_scale); @@ -800,7 +800,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st // Font registry init if (!sFontRegistry) { - sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures); + sFontRegistry = new LLFontRegistry(create_gl_textures); sFontRegistry->parseFontInfo("fonts.xml"); } else diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 5ed5d2c4eb..0988e99deb 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -150,7 +150,7 @@ public: const LLFontDescriptor& getFontDesc() const; - static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures = true); + static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true); // Load sans-serif, sans-serif-small, etc. // Slow, requires multiple seconds to load fonts. diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 4d22eba3d9..b5bdba996f 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -163,14 +163,9 @@ LLFontDescriptor LLFontDescriptor::normalize() const return LLFontDescriptor(new_name,new_size,new_style,getFileNames()); } -LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths, - bool create_gl_textures) +LLFontRegistry::LLFontRegistry(bool create_gl_textures) : mCreateGLTextures(create_gl_textures) { - // Propagate this down from LLUICtrlFactory so LLRender doesn't - // need an upstream dependency on LLUI. - mXUIPaths = xui_paths; - // This is potentially a slow directory traversal, so we want to // cache the result. mUltimateFallbackList = LLWindow::getDynamicFallbackFontList(); @@ -183,27 +178,30 @@ LLFontRegistry::~LLFontRegistry() bool LLFontRegistry::parseFontInfo(const std::string& xml_filename) { - bool success = false; // Succeed if we find at least one XUI file - const string_vec_t& xml_paths = mXUIPaths; + bool success = false; // Succeed if we find and read at least one XUI file + const string_vec_t xml_paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename); + if (xml_paths.empty()) + { + // We didn't even find one single XUI file + return false; + } + for (string_vec_t::const_iterator path_it = xml_paths.begin(); path_it != xml_paths.end(); ++path_it) { - LLXMLNodePtr root; - std::string full_filename = gDirUtilp->findSkinnedFilename(*path_it, xml_filename); - bool parsed_file = LLXMLNode::parseFile(full_filename, root, NULL); + bool parsed_file = LLXMLNode::parseFile(*path_it, root, NULL); if (!parsed_file) continue; - + if ( root.isNull() || ! root->hasName( "fonts" ) ) { - llwarns << "Bad font info file: " - << full_filename << llendl; + llwarns << "Bad font info file: " << *path_it << llendl; continue; } - + std::string root_name; root->getAttributeString("name",root_name); if (root->hasName("fonts")) @@ -215,7 +213,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename) } //if (success) // dump(); - + return success; } diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 8b06191c56..059248fbbd 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -67,8 +67,7 @@ class LLFontRegistry public: // create_gl_textures - set to false for test apps with no OpenGL window, // such as llui_libtest - LLFontRegistry(const string_vec_t& xui_paths, - bool create_gl_textures); + LLFontRegistry(bool create_gl_textures); ~LLFontRegistry(); // Load standard font info from XML file(s). @@ -105,7 +104,6 @@ private: font_size_map_t mFontSizes; string_vec_t mUltimateFallbackList; - string_vec_t mXUIPaths; bool mCreateGLTextures; }; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 964495a3ab..d70e764769 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -424,6 +424,10 @@ const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms class LLGLFence { public: + virtual ~LLGLFence() + { + } + virtual void placeFence() = 0; virtual bool isCompleted() = 0; virtual void wait() = 0; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index a0727b8686..509de51f4d 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -993,7 +993,12 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); } #endif +#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1070 +#include <OpenGL/gl.h> +#else #include <AGL/gl.h> +#endif + #endif // LL_MESA / LL_WINDOWS / LL_DARWIN diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h index e26aead676..0e2c3bcb44 100644 --- a/indra/llrender/llglstates.h +++ b/indra/llrender/llglstates.h @@ -59,7 +59,6 @@ protected: LLGLEnable mColorMaterial; LLGLDisable mAlphaTest, mBlend, mCullFace, mDither, mFog, mLineSmooth, mLineStipple, mNormalize, mPolygonSmooth, - mTextureGenQ, mTextureGenR, mTextureGenS, mTextureGenT, mGLMultisample; public: LLGLSDefault() @@ -76,10 +75,6 @@ public: mLineStipple(GL_LINE_STIPPLE), mNormalize(GL_NORMALIZE), mPolygonSmooth(GL_POLYGON_SMOOTH), - mTextureGenQ(GL_TEXTURE_GEN_Q), - mTextureGenR(GL_TEXTURE_GEN_R), - mTextureGenS(GL_TEXTURE_GEN_S), - mTextureGenT(GL_TEXTURE_GEN_T), mGLMultisample(GL_MULTISAMPLE_ARB) { } }; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index a842211764..a4d7872ec2 100644..100755 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -478,7 +478,7 @@ bool LLImageGL::checkSize(S32 width, S32 height) return check_power_of_two(width) && check_power_of_two(height); } -void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents) +void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level) { if (width != mWidth || height != mHeight || ncomponents != mComponents) { @@ -511,6 +511,11 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents) width >>= 1; height >>= 1; } + + if(discard_level > 0) + { + mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level); + } } else { @@ -860,14 +865,13 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image) llassert(mCurrentDiscardLevel >= 0); discard_level = mCurrentDiscardLevel; } - discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - + // Actual image width/height = raw image width/height * 2^discard_level S32 w = raw_image->getWidth() << discard_level; S32 h = raw_image->getHeight() << discard_level; // setSize may call destroyGLTexture if the size does not match - setSize(w, h, raw_image->getComponents()); + setSize(w, h, raw_image->getComponents(), discard_level); if( !mHasExplicitFormat ) { @@ -1264,8 +1268,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S llassert(mCurrentDiscardLevel >= 0); discard_level = mCurrentDiscardLevel; } - discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - + // Actual image width/height = raw image width/height * 2^discard_level S32 raw_w = imageraw->getWidth() ; S32 raw_h = imageraw->getHeight() ; @@ -1273,7 +1276,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S S32 h = raw_h << discard_level; // setSize may call destroyGLTexture if the size does not match - setSize(w, h, imageraw->getComponents()); + setSize(w, h, imageraw->getComponents(), discard_level); if( !mHasExplicitFormat ) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index e118c28c1b..cf3c484c79 100644..100755 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -100,7 +100,7 @@ protected: public: virtual void dump(); // debugging info to llinfos - void setSize(S32 width, S32 height, S32 ncomponents); + void setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1); void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;} void setAllowCompression(bool allow) { mAllowCompression = allow; } diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 348c1eb1b7..4597d06260 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -648,7 +648,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT gGL.flush(); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); } - + // We want an early out, because this function does a LOT of stuff. if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2)) || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty) @@ -1437,6 +1437,17 @@ void LLRender::matrixMode(U32 mode) mMatrixMode = mode; } +U32 LLRender::getMatrixMode() +{ + if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3) + { //always return MM_TEXTURE if current matrix mode points at any texture matrix + return MM_TEXTURE; + } + + return mMatrixMode; +} + + void LLRender::loadIdentity() { flush(); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index fa5f7f311d..78a310e525 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -346,6 +346,7 @@ public: void loadIdentity(); void multMatrix(const GLfloat* m); void matrixMode(U32 mode); + U32 getMatrixMode(); const glh::matrix4f& getModelviewMatrix(); const glh::matrix4f& getProjectionMatrix(); diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index cc5c232380..c1b96a43da 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -51,11 +51,13 @@ void check_framebuffer_status() } bool LLRenderTarget::sUseFBO = false; +U32 LLRenderTarget::sCurFBO = 0; LLRenderTarget::LLRenderTarget() : mResX(0), mResY(0), mFBO(0), + mPreviousFBO(0), mDepth(0), mStencil(0), mUseDepth(false), @@ -107,6 +109,9 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt) bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) { + resx = llmin(resx, (U32) 4096); + resy = llmin(resy, (U32) 4096); + stop_glerror(); release(); stop_glerror(); @@ -146,7 +151,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); } stop_glerror(); @@ -163,10 +168,19 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) } U32 offset = mTex.size(); - if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) + + if( offset >= 4 ) { - llerrs << "Too many color attachments!" << llendl; + llwarns << "Too many color attachments" << llendl; + llassert( offset < 4 ); + return false; + } + if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) ) + { + llwarns << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << llendl; + llassert( mFBO != 0 ); + llassert( gGLManager.mHasDrawBuffers ); + return false; } U32 tex; @@ -224,7 +238,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) check_framebuffer_status(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); } mTex.push_back(tex); @@ -313,7 +327,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) check_framebuffer_status(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); target.mUseDepth = true; } @@ -376,9 +390,13 @@ void LLRenderTarget::bindTarget() { if (mFBO) { + mPreviousFBO = sCurFBO; + stop_glerror(); glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + sCurFBO = mFBO; + stop_glerror(); if (gGLManager.mHasDrawBuffers) { //setup multiple render targets @@ -404,16 +422,6 @@ void LLRenderTarget::bindTarget() sBoundTarget = this; } -// static -void LLRenderTarget::unbindTarget() -{ - if (gGLManager.mHasFramebufferObject) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - sBoundTarget = NULL; -} - void LLRenderTarget::clear(U32 mask_in) { U32 mask = GL_COLOR_BUFFER_BIT; @@ -479,7 +487,8 @@ void LLRenderTarget::flush(bool fetch_depth) else { stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO); + sCurFBO = mPreviousFBO; stop_glerror(); } } @@ -509,7 +518,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, stop_glerror(); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); stop_glerror(); } else @@ -526,7 +535,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, stop_glerror(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); stop_glerror(); } } @@ -552,7 +561,7 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0 stop_glerror(); glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); stop_glerror(); } } diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index e1a51304f1..cf15f66d31 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -63,6 +63,7 @@ public: //whether or not to use FBO implementation static bool sUseFBO; static U32 sBytesAllocated; + static U32 sCurFBO; LLRenderTarget(); ~LLRenderTarget(); @@ -96,9 +97,6 @@ public: //applies appropriate viewport void bindTarget(); - //unbind target for rendering - static void unbindTarget(); - //clear render targer, clears depth buffer if present, //uses scissor rect if in copy-to-texture mode void clear(U32 mask = 0xFFFFFFFF); @@ -148,6 +146,7 @@ protected: std::vector<U32> mTex; std::vector<U32> mInternalFormat; U32 mFBO; + U32 mPreviousFBO; U32 mDepth; bool mStencil; bool mUseDepth; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index a9248d4d73..b6a9a6b653 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -643,7 +643,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade text[count++] = strdup("#define textureCube texture\n"); text[count++] = strdup("#define texture2DLod textureLod\n"); text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n"); - + if (major_version > 1 || minor_version >= 40) { //GLSL 1.40 replaces texture2DRect et al with texture text[count++] = strdup("#define texture2DRect texture\n"); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 80752231d7..2fe0aa0b72 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -38,10 +38,6 @@ #include "llglslshader.h" #include "llmemory.h" -#if LL_DARWIN -#define LL_VBO_POOLING 1 -#else -#endif //Next Highest Power Of Two //helper function, returns first number > v that is a power of 2, or v if v is already a power of 2 U32 nhpo2(U32 v) @@ -294,6 +290,7 @@ void LLVBOPool::seedPool() } + void LLVBOPool::cleanup() { U32 size = LL_VBO_BLOCK_SIZE; @@ -558,8 +555,21 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con gGL.syncMatrices(); U32 count = pos.size(); - llassert_always(norm.size() >= pos.size()); - llassert_always(count > 0); + + llassert(norm.size() >= pos.size()); + llassert(count > 0); + + if( count == 0 ) + { + llwarns << "Called drawArrays with 0 vertices" << llendl; + return; + } + + if( norm.size() < pos.size() ) + { + llwarns << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << llendl; + return; + } unbind(); diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index cca4ca3981..d92b6aa1c0 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -155,7 +155,6 @@ set(llui_HEADER_FILES llflyoutbutton.h llfocusmgr.h llfunctorregistry.h - llhandle.h llhelp.h lliconctrl.h llkeywords.h diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 806d2ef3f6..41e5d74042 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -563,8 +563,7 @@ void LLComboBox::showList() S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); // make sure we have up to date content width metrics - mList->calcColumnWidths(); - S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); + S32 list_width = llclamp(mList->calcMaxContentWidth(), min_width, max_width); if (mListPosition == BELOW) { diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8ca1e685a9..054b9173d3 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -748,6 +748,10 @@ void LLFloater::closeFloater(bool app_quitting) dependee->setFocus(TRUE); } } + + // STORM-1879: since this floater has focus, treat the closeFloater- call + // like a click on the close-button, and close gear- and contextmenus + LLMenuGL::sMenuContainer->hideMenus(); } dirtyRect(); @@ -3229,24 +3233,14 @@ bool LLFloater::isVisible(const LLFloater* floater) static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters"); -bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_node) +bool LLFloater::buildFromFile(const std::string& filename) { LLFastTimer timer(FTM_BUILD_FLOATERS); LLXMLNodePtr root; - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) - { - llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return false; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) { - llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + llwarns << "Couldn't find (or parse) floater from: " << filename << llendl; return false; } @@ -3271,7 +3265,7 @@ bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_n getCommitCallbackRegistrar().pushScope(); getEnableCallbackRegistrar().pushScope(); - res = initFloaterXML(root, getParent(), filename, output_node); + res = initFloaterXML(root, getParent(), filename, NULL); setXMLFilename(filename); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 64d6dcea04..e64b6d04d3 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -202,7 +202,7 @@ public: // Don't export top/left for rect, only height/width static void setupParamsForExport(Params& p, LLView* parent); - bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL); + bool buildFromFile(const std::string &filename); boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb ); boost::signals2::connection setOpenCallback( const commit_signal_t::slot_type& cb ); diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 9115eb7174..306caf2b91 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -154,7 +154,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) llwarns << "Failed to build floater type: '" << name << "'." << llendl; return NULL; } - bool success = res->buildFromFile(xui_file, NULL); + bool success = res->buildFromFile(xui_file); if (!success) { llwarns << "Failed to build floater type: '" << name << "'." << llendl; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 629eef2c3b..210a320f41 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1424,25 +1424,19 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path bool LLNotifications::loadTemplates() { llinfos << "Reading notifications template" << llendl; - std::vector<std::string> search_paths; - - std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml"; - std::string localized_skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml"; - - addPathIfExists(gDirUtilp->getDefaultSkinDir() + skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getDefaultSkinDir() + localized_skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getSkinDir() + skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getSkinDir() + localized_skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getUserSkinDir() + skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getUserSkinDir() + localized_skin_relative_path, search_paths); + // Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it + // output all relevant pathnames instead of just the ones from the most + // specific skin. + std::vector<std::string> search_paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS); std::string base_filename = search_paths.front(); LLXMLNodePtr root; BOOL success = LLXMLNode::getLayeredXMLNode(root, search_paths); - + if (!success || root.isNull() || !root->hasName( "notifications" )) { - llerrs << "Problem reading UI Notifications file: " << base_filename << llendl; + llerrs << "Problem reading XML from UI Notifications file: " << base_filename << llendl; return false; } @@ -1452,7 +1446,7 @@ bool LLNotifications::loadTemplates() if(!params.validateBlock()) { - llerrs << "Problem reading UI Notifications file: " << base_filename << llendl; + llerrs << "Problem reading XUI from UI Notifications file: " << base_filename << llendl; return false; } @@ -1508,7 +1502,9 @@ bool LLNotifications::loadTemplates() bool LLNotifications::loadVisibilityRules() { const std::string xml_filename = "notification_visibility.xml"; - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename); + // Note that here we're looking for the "en" version, the default + // language, rather than the most localized version of this file. + std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, xml_filename); LLNotificationVisibilityRule::Rules params; LLSimpleXUIParser parser; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 00318cec6b..67472ad166 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -968,25 +968,15 @@ static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels"); //----------------------------------------------------------------------------- // buildPanel() //----------------------------------------------------------------------------- -BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_node, const LLPanel::Params& default_params) +BOOL LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& default_params) { LLFastTimer timer(FTM_BUILD_PANELS); BOOL didPost = FALSE; LLXMLNodePtr root; - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) - { - llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return didPost; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) { - llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + llwarns << "Couldn't parse panel from: " << filename << llendl; return didPost; } @@ -1010,7 +1000,7 @@ BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_nod getCommitCallbackRegistrar().pushScope(); getEnableCallbackRegistrar().pushScope(); - didPost = initPanelXML(root, NULL, output_node, default_params); + didPost = initPanelXML(root, NULL, NULL, default_params); getCommitCallbackRegistrar().popScope(); getEnableCallbackRegistrar().popScope(); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index f620201020..e63b41f97c 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -105,7 +105,7 @@ protected: LLPanel(const LLPanel::Params& params = getDefaultParams()); public: - BOOL buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL, const LLPanel::Params&default_params = getDefaultParams()); + BOOL buildFromFile(const std::string &filename, const LLPanel::Params& default_params = getDefaultParams()); static LLPanel* createFactoryPanel(const std::string& name); diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 07a6dfaa10..af124d9826 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -98,6 +98,7 @@ BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) if (canResize() && mResizeBar->getRect().pointInRect(x, y)) { // reshape column to max content width + mColumn->mParentCtrl->calcMaxContentWidth(); LLRect column_rect = getRect(); column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; setShape(column_rect, true); @@ -127,6 +128,8 @@ LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& m LLRect snap_rect = getSnapRect(); + mColumn->mParentCtrl->calcMaxContentWidth(); + S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth(); // x coord growing means column growing, so same signs mean we're going in right direction diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 802914e25b..3e0653e9a4 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -35,6 +35,7 @@ #include "llboost.h" //#include "indra_constants.h" +#include "llavatarnamecache.h" #include "llcheckboxctrl.h" #include "llclipboard.h" #include "llfocusmgr.h" @@ -158,15 +159,14 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mMouseWheelOpaque(p.mouse_wheel_opaque), mPageLines(p.page_lines), mMaxSelectable(0), - mAllowKeyboardMovement(TRUE), + mAllowKeyboardMovement(true), mCommitOnKeyboardMovement(p.commit_on_keyboard_movement), - mCommitOnSelectionChange(FALSE), - mSelectionChanged(FALSE), - mNeedsScroll(FALSE), - mCanSelect(TRUE), - mColumnsDirty(FALSE), + mCommitOnSelectionChange(false), + mSelectionChanged(false), + mNeedsScroll(false), + mCanSelect(true), + mColumnsDirty(false), mMaxItemCount(INT_MAX), - mMaxContentWidth(0), mBorderThickness( 2 ), mOnDoubleClickCallback( NULL ), mOnMaximumSelectCallback( NULL ), @@ -180,7 +180,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mTotalStaticColumnWidth(0), mTotalColumnPadding(0), mSorted(false), - mDirty(FALSE), + mDirty(false), mOriginalSelection(-1), mLastSelected(NULL), mHeadingHeight(p.heading_height), @@ -356,7 +356,7 @@ void LLScrollListCtrl::clearRows() mScrollLines = 0; mLastSelected = NULL; updateLayout(); - mDirty = FALSE; + mDirty = false; } @@ -591,13 +591,11 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r // NOTE: This is *very* expensive for large lists, especially when we are dirtying the list every frame // while receiving a long list of names. // *TODO: Use bookkeeping to make this an incramental cost with item additions -void LLScrollListCtrl::calcColumnWidths() +S32 LLScrollListCtrl::calcMaxContentWidth() { const S32 HEADING_TEXT_PADDING = 25; const S32 COLUMN_TEXT_PADDING = 10; - mMaxContentWidth = 0; - S32 max_item_width = 0; ordered_columns_t::iterator column_itor; @@ -606,6 +604,35 @@ void LLScrollListCtrl::calcColumnWidths() LLScrollListColumn* column = *column_itor; if (!column) continue; + if (mColumnWidthsDirty) + { + mColumnWidthsDirty = false; + // update max content width for this column, by looking at all items + column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); + if (!cellp) continue; + + column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + } + } + max_item_width += column->mMaxContentWidth; + } + + return max_item_width; +} + +bool LLScrollListCtrl::updateColumnWidths() +{ + bool width_changed = false; + ordered_columns_t::iterator column_itor; + for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) + { + LLScrollListColumn* column = *column_itor; + if (!column) continue; + // update column width S32 new_width = column->getWidth(); if (column->mRelWidth >= 0) @@ -617,23 +644,13 @@ void LLScrollListCtrl::calcColumnWidths() new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns; } - column->setWidth(new_width); - - // update max content width for this column, by looking at all items - column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (column->getWidth() != new_width) { - LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); - if (!cellp) continue; - - column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + column->setWidth(new_width); + width_changed = true; } - - max_item_width += column->mMaxContentWidth; } - - mMaxContentWidth = max_item_width; + return width_changed; } const S32 SCROLL_LIST_ROW_PAD = 2; @@ -669,7 +686,12 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) void LLScrollListCtrl::updateColumns() { - calcColumnWidths(); + if (!mColumnsDirty) + return; + + mColumnsDirty = false; + + bool columns_changed_width = updateColumnWidths(); // update column headers std::vector<LLScrollListColumn*>::iterator column_ordered_it; @@ -718,20 +740,22 @@ void LLScrollListCtrl::updateColumns() } // propagate column widths to individual cells - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (columns_changed_width) { - LLScrollListItem *itemp = *iter; - S32 num_cols = itemp->getNumColumns(); - S32 i = 0; - for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { - if (i >= (S32)mColumnsIndexed.size()) break; + LLScrollListItem *itemp = *iter; + S32 num_cols = itemp->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; - cell->setWidth(mColumnsIndexed[i]->getWidth()); + cell->setWidth(mColumnsIndexed[i]->getWidth()); + } } } - } void LLScrollListCtrl::setHeadingHeight(S32 heading_height) @@ -772,7 +796,7 @@ BOOL LLScrollListCtrl::selectFirstItem() { deselectItem(itemp); } - first_item = FALSE; + first_item = false; } if (mCommitOnSelectionChange) { @@ -1406,17 +1430,23 @@ void LLScrollListCtrl::drawItems() S32 cur_y = y; - S32 line = 0; S32 max_columns = 0; LLColor4 highlight_color = LLColor4::white; static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0); highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); + S32 first_line = mScrollLines; + S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage()); + + if (first_line >= mItemList.size()) + { + return; + } item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (S32 line = first_line; line <= last_line; line++) { - LLScrollListItem* item = *iter; + LLScrollListItem* item = mItemList[line]; item_rect.setOriginAndSize( x, @@ -1480,7 +1510,6 @@ void LLScrollListCtrl::drawItems() cur_y -= mLineHeight; } - line++; } } } @@ -1496,7 +1525,7 @@ void LLScrollListCtrl::draw() if (mNeedsScroll) { scrollToShowSelected(); - mNeedsScroll = FALSE; + mNeedsScroll = false; } LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0); // Draw background @@ -1507,11 +1536,7 @@ void LLScrollListCtrl::draw() gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() % alpha : mBgReadOnlyColor.get() % alpha ); } - if (mColumnsDirty) - { - updateColumns(); - mColumnsDirty = FALSE; - } + updateColumns(); getChildView("comment_text")->setVisible(mItemList.empty()); @@ -1719,7 +1744,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) setFocus(TRUE); // clear selection changed flag because user is starting a selection operation - mSelectionChanged = FALSE; + mSelectionChanged = false; handleClick(x, y, mask); } @@ -1737,15 +1762,15 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } // always commit when mouse operation is completed inside list if (mItemListRect.pointInRect(x,y)) { - mDirty |= mSelectionChanged; - mSelectionChanged = FALSE; + mDirty = mDirty || mSelectionChanged; + mSelectionChanged = false; onCommit(); } @@ -1805,7 +1830,9 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group) } else { - gCacheName->getFullName(LLUUID(id), name); + LLAvatarName av_name; + LLAvatarNameCache::get(LLUUID(id), &av_name); + name = av_name.getLegacyName(); } LLUrlAction::copyURLToClipboard(name); } @@ -1859,7 +1886,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) { selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; } // propagate state of cell to rest of selected column @@ -1888,7 +1915,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) // treat this as a normal single item selection selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; // do not eat click (allow double click callback) return FALSE; } @@ -1994,7 +2021,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } else @@ -2041,7 +2068,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectPrevItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2050,7 +2077,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectNextItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2058,7 +2085,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2071,7 +2098,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2084,7 +2111,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectFirstItem(); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2097,7 +2124,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getItemCount() - 1); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2136,7 +2163,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) } else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE)) { - mNeedsScroll = TRUE; + mNeedsScroll = true; // update search string only on successful match mSearchTimer.reset(); @@ -2177,7 +2204,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE)) { // update search string only on successful match - mNeedsScroll = TRUE; + mNeedsScroll = true; mSearchString += uni_char; mSearchTimer.reset(); @@ -2223,7 +2250,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) { selectItem(item); - mNeedsScroll = TRUE; + mNeedsScroll = true; cellp->highlightText(0, 1); mSearchTimer.reset(); @@ -2294,7 +2321,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it } itemp->setSelected(TRUE); mLastSelected = itemp; - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2315,7 +2342,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp) { cellp->highlightText(0, 0); } - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2323,7 +2350,7 @@ void LLScrollListCtrl::commitIfChanged() { if (mSelectionChanged) { - mDirty = TRUE; + mDirty = true; mSelectionChanged = FALSE; onCommit(); } @@ -2434,7 +2461,8 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending) void LLScrollListCtrl::dirtyColumns() { - mColumnsDirty = TRUE; + mColumnsDirty = true; + mColumnWidthsDirty = true; // need to keep mColumnsIndexed up to date // just in case someone indexes into it immediately @@ -2720,6 +2748,11 @@ BOOL LLScrollListCtrl::hasSortOrder() const return !mSortColumns.empty(); } +void LLScrollListCtrl::clearSortOrder() +{ + mSortColumns.clear(); +} + void LLScrollListCtrl::clearColumns() { column_map_t::iterator itor; @@ -2998,7 +3031,7 @@ void LLScrollListCtrl::resetDirty() void LLScrollListCtrl::onFocusReceived() { // forget latent selection changes when getting focus - mSelectionChanged = FALSE; + mSelectionChanged = false; LLUICtrl::onFocusReceived(); } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 44d9635838..38450b6313 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -343,8 +343,8 @@ public: static void onClickColumn(void *userdata); virtual void updateColumns(); - void calcColumnWidths(); - S32 getMaxContentWidth() { return mMaxContentWidth; } + S32 calcMaxContentWidth(); + bool updateColumnWidths(); void setHeadingHeight(S32 heading_height); /** @@ -374,6 +374,7 @@ public: std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } BOOL hasSortOrder() const; + void clearSortOrder(); S32 selectMultiple( uuid_vec_t ids ); // conceptually const, but mutates mItemList @@ -439,16 +440,17 @@ private: S32 mHeadingHeight; // the height of the column header buttons, if visible U32 mMaxSelectable; LLScrollbar* mScrollbar; - BOOL mAllowMultipleSelection; - BOOL mAllowKeyboardMovement; - BOOL mCommitOnKeyboardMovement; - BOOL mCommitOnSelectionChange; - BOOL mSelectionChanged; - BOOL mNeedsScroll; - BOOL mMouseWheelOpaque; - BOOL mCanSelect; - const BOOL mDisplayColumnHeaders; - BOOL mColumnsDirty; + bool mAllowMultipleSelection; + bool mAllowKeyboardMovement; + bool mCommitOnKeyboardMovement; + bool mCommitOnSelectionChange; + bool mSelectionChanged; + bool mNeedsScroll; + bool mMouseWheelOpaque; + bool mCanSelect; + bool mDisplayColumnHeaders; + bool mColumnsDirty; + bool mColumnWidthsDirty; mutable item_list mItemList; @@ -457,7 +459,6 @@ private: S32 mMaxItemCount; LLRect mItemListRect; - S32 mMaxContentWidth; S32 mColumnPadding; BOOL mBackgroundVisible; @@ -497,7 +498,7 @@ private: typedef std::map<std::string, LLScrollListColumn*> column_map_t; column_map_t mColumns; - BOOL mDirty; + bool mDirty; S32 mOriginalSelection; ContextMenuType mContextMenuType; diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp index d29260750f..e4d1a37569 100644 --- a/indra/llui/lltoggleablemenu.cpp +++ b/indra/llui/lltoggleablemenu.cpp @@ -57,7 +57,9 @@ void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn) S32 x,y; LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y); - if (!curVisibilityIn && mButtonRect.pointInRect(x, y)) + // STORM-1879: also check MouseCapture to see if the button was really + // clicked (otherwise the VisibilityChange was triggered via keyboard shortcut) + if (!curVisibilityIn && mButtonRect.pointInRect(x, y) && gFocusMgr.getMouseCapture()) { mClosedByButtonClick = true; } diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 58fa8a0828..80d079cbc8 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -31,15 +31,20 @@ #include "lltrans.h" #include "lluictrlfactory.h" #include "llxmlnode.h" - +#include "lldir.h" bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args) { LLXMLNodePtr root; - BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + // Pass LLDir::ALL_SKINS to load a composite of all the individual string + // definitions in the default skin and the current skin. This means an + // individual skin can provide an xml_filename that overrides only a + // subset of the available string definitions; any string definition not + // overridden by that skin will be sought in the default skin. + bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS); if (!success) { - llerrs << "Couldn't load string table" << llendl; + llerrs << "Couldn't load string table " << xml_filename << llendl; return false; } @@ -54,7 +59,7 @@ bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename) if (!success) { - llerrs << "Couldn't load string table " << xml_filename << llendl; + llerrs << "Couldn't load localization table " << xml_filename << llendl; return false; } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 87bf518aa1..6d2bc1837c 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1836,88 +1836,37 @@ struct Paths : public LLInitParam::Block<Paths> {} }; -//static -void LLUI::setupPaths() -{ - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "paths.xml"); - - LLXMLNodePtr root; - BOOL success = LLXMLNode::parseFile(filename, root, NULL); - Paths paths; - - if(success) - { - LLXUIParser parser; - parser.readXUI(root, paths, filename); - } - sXUIPaths.clear(); - - if (success && paths.validateBlock()) - { - LLStringUtil::format_map_t path_args; - path_args["[LANGUAGE]"] = LLUI::getLanguage(); - - for (LLInitParam::ParamIterator<Directory>::const_iterator it = paths.directories.begin(), - end_it = paths.directories.end(); - it != end_it; - ++it) - { - std::string path_val_ui; - for (LLInitParam::ParamIterator<SubDir>::const_iterator subdir_it = it->subdirs.begin(), - subdir_end_it = it->subdirs.end(); - subdir_it != subdir_end_it;) - { - path_val_ui += subdir_it->value(); - if (++subdir_it != subdir_end_it) - path_val_ui += gDirUtilp->getDirDelimiter(); - } - LLStringUtil::format(path_val_ui, path_args); - if (std::find(sXUIPaths.begin(), sXUIPaths.end(), path_val_ui) == sXUIPaths.end()) - { - sXUIPaths.push_back(path_val_ui); - } - - } - } - else // parsing failed - { - std::string slash = gDirUtilp->getDirDelimiter(); - std::string dir = "xui" + slash + "en"; - llwarns << "XUI::config file unable to open: " << filename << llendl; - sXUIPaths.push_back(dir); - } -} - //static std::string LLUI::locateSkin(const std::string& filename) { - std::string slash = gDirUtilp->getDirDelimiter(); std::string found_file = filename; - if (!gDirUtilp->fileExists(found_file)) + if (gDirUtilp->fileExists(found_file)) { - found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS? + return found_file; } - if (sSettingGroups["config"] && sSettingGroups["config"]->controlExists("Language")) + + found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS? + if (gDirUtilp->fileExists(found_file)) { - if (!gDirUtilp->fileExists(found_file)) - { - std::string localization = getLanguage(); - std::string local_skin = "xui" + slash + localization + slash + filename; - found_file = gDirUtilp->findSkinnedFilename(local_skin); - } + return found_file; } - if (!gDirUtilp->fileExists(found_file)) + + found_file = gDirUtilp->findSkinnedFilename(LLDir::XUI, filename); + if (! found_file.empty()) { - std::string local_skin = "xui" + slash + "en" + slash + filename; - found_file = gDirUtilp->findSkinnedFilename(local_skin); + return found_file; } - if (!gDirUtilp->fileExists(found_file)) + + found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); + if (gDirUtilp->fileExists(found_file)) { - found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); + return found_file; } - return found_file; -} + LL_WARNS("LLUI") << "Can't find '" << filename + << "' in user settings, any skin directory or app_settings" << LL_ENDL; + return ""; +} //static LLVector2 LLUI::getWindowSize() diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 28e84fa444..c5a12d2b31 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -292,11 +292,6 @@ public: // Return the ISO639 language name ("en", "ko", etc.) for the viewer UI. // http://www.loc.gov/standards/iso639-2/php/code_list.php static std::string getLanguage(); - - static void setupPaths(); - static const std::vector<std::string>& getXUIPaths() { return sXUIPaths; } - static std::string getSkinPath() { return sXUIPaths.front(); } - static std::string getLocalizedSkinPath() { return sXUIPaths.back(); } //all files may not exist at the localized path //helper functions (should probably move free standing rendering helper functions here) static LLView* getRootView() { return sRootView; } diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 9455d09cc0..ffeff15968 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -32,6 +32,7 @@ #include "llui.h" #include "lluicolortable.h" #include "lluictrlfactory.h" +#include <boost/foreach.hpp> LLUIColorTable::ColorParams::ColorParams() : value("value"), @@ -206,19 +207,12 @@ bool LLUIColorTable::loadFromSettings() { bool result = false; - std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml"); - result |= loadFromFilename(default_filename, mLoadedColors); - - std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml"); - if(current_filename != default_filename) - { - result |= loadFromFilename(current_filename, mLoadedColors); - } - - current_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); - if(current_filename != default_filename) + // pass constraint=LLDir::ALL_SKINS because we want colors.xml from every + // skin dir + BOOST_FOREACH(std::string colors_path, + gDirUtilp->findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS)) { - result |= loadFromFilename(current_filename, mLoadedColors); + result |= loadFromFilename(colors_path, mLoadedColors); } std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml"); diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 25e7a31e90..bd06476936 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -90,10 +90,12 @@ LLUICtrlFactory::~LLUICtrlFactory() void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block) { - std::string filename = std::string("widgets") + gDirUtilp->getDirDelimiter() + widget_tag + ".xml"; + std::string filename = gDirUtilp->add("widgets", widget_tag + ".xml"); LLXMLNodePtr root_node; - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), filename); + // Here we're looking for the "en" version, the default-language version + // of the file, rather than the localized version. + std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename); if (!full_filename.empty()) { LLUICtrlFactory::instance().pushFileName(full_filename); @@ -149,22 +151,12 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing"); //----------------------------------------------------------------------------- // getLayeredXMLNode() //----------------------------------------------------------------------------- -bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root) +bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root, + LLDir::ESkinConstraint constraint) { LLFastTimer timer(FTM_XML_PARSE); - - std::vector<std::string> paths; - std::string path = gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), xui_filename); - if (!path.empty()) - { - paths.push_back(path); - } - - std::string localize_path = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename); - if (!localize_path.empty() && localize_path != path) - { - paths.push_back(localize_path); - } + std::vector<std::string> paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename, constraint); if (paths.empty()) { @@ -177,23 +169,6 @@ bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNo //----------------------------------------------------------------------------- -// getLocalizedXMLNode() -//----------------------------------------------------------------------------- -bool LLUICtrlFactory::getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root) -{ - LLFastTimer timer(FTM_XML_PARSE); - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename); - if (!LLXMLNode::parseFile(full_filename, root, NULL)) - { - return false; - } - else - { - return true; - } -} - -//----------------------------------------------------------------------------- // saveToXML() //----------------------------------------------------------------------------- S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename) @@ -239,8 +214,10 @@ std::string LLUICtrlFactory::getCurFileName() void LLUICtrlFactory::pushFileName(const std::string& name) -{ - mFileNames.push_back(gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), name)); +{ + // Here we seem to be looking for the default language file ("en") rather + // than the localized one, if any. + mFileNames.push_back(gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, name)); } void LLUICtrlFactory::popFileName() @@ -255,14 +232,6 @@ void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group) parent->addChild(view, tab_group); } - -// Avoid directly using LLUI and LLDir in the template code -//static -std::string LLUICtrlFactory::findSkinnedFilename(const std::string& filename) -{ - return gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename); -} - //static void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest) { diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index d612ad5005..f6971261d7 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -31,18 +31,11 @@ #include "llinitparam.h" #include "llregistry.h" #include "llxuiparser.h" +#include "llstl.h" +#include "lldir.h" class LLView; -// sort functor for typeid maps -struct LLCompareTypeID -{ - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } -}; - // lookup widget constructor funcs by widget name template <typename DERIVED_TYPE> class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> @@ -71,14 +64,14 @@ protected: // lookup widget name by type class LLWidgetNameRegistry -: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID> +: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry> {}; // lookup function for generating empty param block by widget type // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); //class LLDefaultParamBlockRegistry -//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID> +//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry> //{}; extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP; @@ -169,32 +162,21 @@ public: LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node ); template<typename T> - static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL) + static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry) { T* widget = NULL; - - std::string skinned_filename = findSkinnedFilename(filename); + instance().pushFileName(filename); { LLXMLNodePtr root_node; - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root_node)) - { - llwarns << "Couldn't parse XUI file: " << filename << llendl; - goto fail; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) { - llwarns << "Couldn't parse XUI file: " << skinned_filename << llendl; + llwarns << "Couldn't parse XUI file: " << instance().getCurFileName() << llendl; goto fail; } - - LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node); + + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, NULL); if (view) { widget = dynamic_cast<T*>(view); @@ -222,8 +204,8 @@ fail: static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); - static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); - static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root); + static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root, + LLDir::ESkinConstraint constraint=LLDir::CURRENT_SKIN); private: //NOTE: both friend declarations are necessary to keep both gcc and msvc happy @@ -308,9 +290,6 @@ private: // this exists to get around dependency on llview static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group); - // Avoid directly using LLUI and LLDir in the template code - static std::string findSkinnedFilename(const std::string& filename); - class LLPanel* mDummyPanel; std::vector<std::string> mFileNames; }; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 54843227b7..ad9bec9f61 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1549,16 +1549,18 @@ void LLView::screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* l void LLView::localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const { - *screen_x = local_x + getRect().mLeft; - *screen_y = local_y + getRect().mBottom; + *screen_x = local_x; + *screen_y = local_y; const LLView* cur = this; - while( cur->mParentView ) + do { + LLRect cur_rect = cur->getRect(); + *screen_x += cur_rect.mLeft; + *screen_y += cur_rect.mBottom; cur = cur->mParentView; - *screen_x += cur->getRect().mLeft; - *screen_y += cur->getRect().mBottom; } + while( cur ); } void LLView::screenRectToLocal(const LLRect& screen, LLRect* local) const diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 32d081d552..5e5aeefba1 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -41,6 +41,17 @@ #include "lluuid.h" #include "lldiriterator.h" +#include "stringize.h" +#include <boost/foreach.hpp> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/assign/list_of.hpp> +#include <boost/bind.hpp> +#include <boost/ref.hpp> +#include <algorithm> + +using boost::assign::list_of; +using boost::assign::map_list_of; #if LL_WINDOWS #include "lldir_win32.h" @@ -58,6 +69,14 @@ LLDir_Linux gDirUtil; LLDir *gDirUtilp = (LLDir *)&gDirUtil; +/// Values for findSkinnedFilenames(subdir) parameter +const char + *LLDir::XUI = "xui", + *LLDir::TEXTURES = "textures", + *LLDir::SKINBASE = ""; + +static const char* const empty = ""; + LLDir::LLDir() : mAppName(""), mExecutablePathAndName(""), @@ -70,7 +89,8 @@ LLDir::LLDir() mOSCacheDir(""), mCAFile(""), mTempDir(""), - mDirDelimiter("/") // fallback to forward slash if not overridden + mDirDelimiter("/"), // fallback to forward slash if not overridden + mLanguage("en") { } @@ -96,9 +116,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) LLDirIterator iter(dirname, mask); while (iter.next(filename)) { - fullpath = dirname; - fullpath += getDirDelimiter(); - fullpath += filename; + fullpath = add(dirname, filename); if(LLFile::isdir(fullpath)) { @@ -270,12 +288,12 @@ std::string LLDir::buildSLOSCacheDir() const } else { - res = getOSUserAppDir() + mDirDelimiter + "cache"; + res = add(getOSUserAppDir(), "cache"); } } else { - res = getOSCacheDir() + mDirDelimiter + "SecondLife"; + res = add(getOSCacheDir(), "SecondLife"); } return res; } @@ -298,19 +316,24 @@ const std::string &LLDir::getDirDelimiter() const return mDirDelimiter; } +const std::string& LLDir::getDefaultSkinDir() const +{ + return mDefaultSkinDir; +} + const std::string &LLDir::getSkinDir() const { return mSkinDir; } -const std::string &LLDir::getUserSkinDir() const +const std::string &LLDir::getUserDefaultSkinDir() const { - return mUserSkinDir; + return mUserDefaultSkinDir; } -const std::string& LLDir::getDefaultSkinDir() const +const std::string &LLDir::getUserSkinDir() const { - return mDefaultSkinDir; + return mUserSkinDir; } const std::string LLDir::getSkinBaseDir() const @@ -323,6 +346,39 @@ const std::string &LLDir::getLLPluginDir() const return mLLPluginDir; } +static std::string ELLPathToString(ELLPath location) +{ + typedef std::map<ELLPath, const char*> ELLPathMap; +#define ENT(symbol) (symbol, #symbol) + static const ELLPathMap sMap = map_list_of + ENT(LL_PATH_NONE) + ENT(LL_PATH_USER_SETTINGS) + ENT(LL_PATH_APP_SETTINGS) + ENT(LL_PATH_PER_SL_ACCOUNT) // returns/expands to blank string if we don't know the account name yet + ENT(LL_PATH_CACHE) + ENT(LL_PATH_CHARACTER) + ENT(LL_PATH_HELP) + ENT(LL_PATH_LOGS) + ENT(LL_PATH_TEMP) + ENT(LL_PATH_SKINS) + ENT(LL_PATH_TOP_SKIN) + ENT(LL_PATH_CHAT_LOGS) + ENT(LL_PATH_PER_ACCOUNT_CHAT_LOGS) + ENT(LL_PATH_USER_SKIN) + ENT(LL_PATH_LOCAL_ASSETS) + ENT(LL_PATH_EXECUTABLE) + ENT(LL_PATH_DEFAULT_SKIN) + ENT(LL_PATH_FONTS) + ENT(LL_PATH_LAST) + ; +#undef ENT + + ELLPathMap::const_iterator found = sMap.find(location); + if (found != sMap.end()) + return found->second; + return STRINGIZE("Invalid ELLPath value " << location); +} + std::string LLDir::getExpandedFilename(ELLPath location, const std::string& filename) const { return getExpandedFilename(location, "", filename); @@ -343,15 +399,11 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd break; case LL_PATH_APP_SETTINGS: - prefix = getAppRODataDir(); - prefix += mDirDelimiter; - prefix += "app_settings"; + prefix = add(getAppRODataDir(), "app_settings"); break; case LL_PATH_CHARACTER: - prefix = getAppRODataDir(); - prefix += mDirDelimiter; - prefix += "character"; + prefix = add(getAppRODataDir(), "character"); break; case LL_PATH_HELP: @@ -363,16 +415,22 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd break; case LL_PATH_USER_SETTINGS: - prefix = getOSUserAppDir(); - prefix += mDirDelimiter; - prefix += "user_settings"; + prefix = add(getOSUserAppDir(), "user_settings"); break; case LL_PATH_PER_SL_ACCOUNT: prefix = getLindenUserDir(); if (prefix.empty()) { - // if we're asking for the per-SL-account directory but we haven't logged in yet (or otherwise don't know the account name from which to build this string), then intentionally return a blank string to the caller and skip the below warning about a blank prefix. + // if we're asking for the per-SL-account directory but we haven't + // logged in yet (or otherwise don't know the account name from + // which to build this string), then intentionally return a blank + // string to the caller and skip the below warning about a blank + // prefix. + LL_DEBUGS("LLDir") << "getLindenUserDir() not yet set: " + << ELLPathToString(location) + << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename + << "' => ''" << LL_ENDL; return std::string(); } break; @@ -386,9 +444,7 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd break; case LL_PATH_LOGS: - prefix = getOSUserAppDir(); - prefix += mDirDelimiter; - prefix += "logs"; + prefix = add(getOSUserAppDir(), "logs"); break; case LL_PATH_TEMP: @@ -412,9 +468,7 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd break; case LL_PATH_LOCAL_ASSETS: - prefix = getAppRODataDir(); - prefix += mDirDelimiter; - prefix += "local_assets"; + prefix = add(getAppRODataDir(), "local_assets"); break; case LL_PATH_EXECUTABLE: @@ -422,56 +476,36 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd break; case LL_PATH_FONTS: - prefix = getAppRODataDir(); - prefix += mDirDelimiter; - prefix += "fonts"; + prefix = add(getAppRODataDir(), "fonts"); break; default: llassert(0); } - std::string filename = in_filename; - if (!subdir2.empty()) - { - filename = subdir2 + mDirDelimiter + filename; - } - - if (!subdir1.empty()) - { - filename = subdir1 + mDirDelimiter + filename; - } - if (prefix.empty()) { - llwarns << "prefix is empty, possible bad filename" << llendl; - } - - std::string expanded_filename; - if (!filename.empty()) - { - if (!prefix.empty()) - { - expanded_filename += prefix; - expanded_filename += mDirDelimiter; - expanded_filename += filename; - } - else - { - expanded_filename = filename; - } - } - else if (!prefix.empty()) - { - // Directory only, no file name. - expanded_filename = prefix; + llwarns << ELLPathToString(location) + << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename + << "': prefix is empty, possible bad filename" << llendl; } - else + + std::string expanded_filename = add(add(prefix, subdir1), subdir2); + if (expanded_filename.empty() && in_filename.empty()) { - expanded_filename.assign(""); + return ""; } - - //llinfos << "*** EXPANDED FILENAME: <" << expanded_filename << ">" << llendl; + // Use explicit concatenation here instead of another add() call. Callers + // passing in_filename as "" expect to obtain a pathname ending with + // mDirSeparator so they can later directly concatenate with a specific + // filename. A caller using add() doesn't care, but there's still code + // loose in the system that uses std::string::operator+(). + expanded_filename += mDirDelimiter; + expanded_filename += in_filename; + + LL_DEBUGS("LLDir") << ELLPathToString(location) + << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename + << "' => '" << expanded_filename << "'" << LL_ENDL; return expanded_filename; } @@ -511,31 +545,207 @@ std::string LLDir::getExtension(const std::string& filepath) const return exten; } -std::string LLDir::findSkinnedFilename(const std::string &filename) const +std::string LLDir::findSkinnedFilenameBaseLang(const std::string &subdir, + const std::string &filename, + ESkinConstraint constraint) const { - return findSkinnedFilename("", "", filename); + // This implementation is basically just as described in the declaration comments. + std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint)); + if (found.empty()) + { + return ""; + } + return found.front(); } -std::string LLDir::findSkinnedFilename(const std::string &subdir, const std::string &filename) const +std::string LLDir::findSkinnedFilename(const std::string &subdir, + const std::string &filename, + ESkinConstraint constraint) const { - return findSkinnedFilename("", subdir, filename); + // This implementation is basically just as described in the declaration comments. + std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint)); + if (found.empty()) + { + return ""; + } + return found.back(); } -std::string LLDir::findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const +// This method exists because the two code paths for +// findSkinnedFilenames(ALL_SKINS) and findSkinnedFilenames(CURRENT_SKIN) must +// generate the list of candidate pathnames in identical ways. The only +// difference is in the body of the inner loop. +template <typename FUNCTION> +void LLDir::walkSearchSkinDirs(const std::string& subdir, + const std::vector<std::string>& subsubdirs, + const std::string& filename, + const FUNCTION& function) const { - // generate subdirectory path fragment, e.g. "/foo/bar", "/foo", "" - std::string subdirs = ((subdir1.empty() ? "" : mDirDelimiter) + subdir1) - + ((subdir2.empty() ? "" : mDirDelimiter) + subdir2); + BOOST_FOREACH(std::string skindir, mSearchSkinDirs) + { + std::string subdir_path(add(skindir, subdir)); + BOOST_FOREACH(std::string subsubdir, subsubdirs) + { + std::string full_path(add(add(subdir_path, subsubdir), filename)); + if (fileExists(full_path)) + { + function(subsubdir, full_path); + } + } + } +} - std::vector<std::string> search_paths; - - search_paths.push_back(getUserSkinDir() + subdirs); // first look in user skin override - search_paths.push_back(getSkinDir() + subdirs); // then in current skin - search_paths.push_back(getDefaultSkinDir() + subdirs); // then default skin - search_paths.push_back(getCacheDir() + subdirs); // and last in preload directory +// ridiculous little helper function that should go away when we can use lambda +inline void push_back(std::vector<std::string>& vector, const std::string& value) +{ + vector.push_back(value); +} + +typedef std::map<std::string, std::string> StringMap; +// ridiculous little helper function that should go away when we can use lambda +inline void store_in_map(StringMap& map, const std::string& key, const std::string& value) +{ + map[key] = value; +} + +std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir, + const std::string& filename, + ESkinConstraint constraint) const +{ + // Recognize subdirs that have no localization. + static const std::set<std::string> sUnlocalized = list_of + ("") // top-level directory not localized + ("textures") // textures not localized + ; + + LL_DEBUGS("LLDir") << "subdir '" << subdir << "', filename '" << filename + << "', constraint " + << ((constraint == CURRENT_SKIN)? "CURRENT_SKIN" : "ALL_SKINS") + << LL_ENDL; + + // Cache the default language directory for each subdir we've encountered. + // A cache entry whose value is the empty string means "not localized, + // don't bother checking again." + static StringMap sLocalized; + + // Check whether we've already discovered if this subdir is localized. + StringMap::const_iterator found = sLocalized.find(subdir); + if (found == sLocalized.end()) + { + // We have not yet determined that. Is it one of the subdirs "known" + // to be unlocalized? + if (sUnlocalized.find(subdir) != sUnlocalized.end()) + { + // This subdir is known to be unlocalized. Remember that. + found = sLocalized.insert(StringMap::value_type(subdir, "")).first; + } + else + { + // We do not recognize this subdir. Investigate. + std::string subdir_path(add(getDefaultSkinDir(), subdir)); + if (fileExists(add(subdir_path, "en"))) + { + // defaultSkinDir/subdir contains subdir "en". That's our + // default language; this subdir is localized. + found = sLocalized.insert(StringMap::value_type(subdir, "en")).first; + } + else if (fileExists(add(subdir_path, "en-us"))) + { + // defaultSkinDir/subdir contains subdir "en-us" but not "en". + // Set as default language; this subdir is localized. + found = sLocalized.insert(StringMap::value_type(subdir, "en-us")).first; + } + else + { + // defaultSkinDir/subdir contains neither "en" nor "en-us". + // Assume it's not localized. Remember that assumption. + found = sLocalized.insert(StringMap::value_type(subdir, "")).first; + } + } + } + // Every code path above should have resulted in 'found' becoming a valid + // iterator to an entry in sLocalized. + llassert(found != sLocalized.end()); + + // Now -- is this subdir localized, or not? The answer determines what + // subdirectories we check (under subdir) for the requested filename. + std::vector<std::string> subsubdirs; + if (found->second.empty()) + { + // subdir is not localized. filename should be located directly within it. + subsubdirs.push_back(""); + } + else + { + // subdir is localized, and found->second is the default language + // directory within it. Check both the default language and the + // current language -- if it differs from the default, of course. + subsubdirs.push_back(found->second); + if (mLanguage != found->second) + { + subsubdirs.push_back(mLanguage); + } + } + + // Build results vector. + std::vector<std::string> results; + // The process we use depends on 'constraint'. + if (constraint != CURRENT_SKIN) // meaning ALL_SKINS + { + // ALL_SKINS is simpler: just return every pathname generated by + // walkSearchSkinDirs(). Tricky bit: walkSearchSkinDirs() passes its + // FUNCTION the subsubdir as well as the full pathname. We just want + // the full pathname. + walkSearchSkinDirs(subdir, subsubdirs, filename, + boost::bind(push_back, boost::ref(results), _2)); + } + else // CURRENT_SKIN + { + // CURRENT_SKIN turns out to be a bit of a misnomer because we might + // still return files from two different skins. In any case, this + // value of 'constraint' means we will return at most two paths: one + // for the default language, one for the current language (supposing + // those differ). + // It is important to allow a user to override only the localization + // for a particular file, for all viewer installs, without also + // overriding the default-language file. + // It is important to allow a user to override only the default- + // language file, for all viewer installs, without also overriding the + // applicable localization of that file. + // Therefore, treat the default language and the current language as + // two separate cases. For each, capture the most-specialized file + // that exists. + // Use a map keyed by subsubdir (i.e. language code). This allows us + // to handle the case of a single subsubdirs entry with the same logic + // that handles two. For every real file path generated by + // walkSearchSkinDirs(), update the map entry for its subsubdir. + StringMap path_for; + walkSearchSkinDirs(subdir, subsubdirs, filename, + boost::bind(store_in_map, boost::ref(path_for), _1, _2)); + // Now that we have a path for each of the default language and the + // current language, copy them -- in proper order -- into results. + // Don't drive this by walking the map itself: it matters that we + // generate results in the same order as subsubdirs. + BOOST_FOREACH(std::string subsubdir, subsubdirs) + { + StringMap::const_iterator found(path_for.find(subsubdir)); + if (found != path_for.end()) + { + results.push_back(found->second); + } + } + } - std::string found_file = findFile(filename, search_paths); - return found_file; + LL_DEBUGS("LLDir") << empty; + const char* comma = ""; + BOOST_FOREACH(std::string path, results) + { + LL_CONT << comma << "'" << path << "'"; + comma = ", "; + } + LL_CONT << LL_ENDL; + + return results; } std::string LLDir::getTempFilename() const @@ -546,12 +756,7 @@ std::string LLDir::getTempFilename() const random_uuid.generate(); random_uuid.toString(uuid_str); - std::string temp_filename = getTempDir(); - temp_filename += mDirDelimiter; - temp_filename += uuid_str; - temp_filename += ".tmp"; - - return temp_filename; + return add(getTempDir(), uuid_str + ".tmp"); } // static @@ -587,9 +792,7 @@ void LLDir::setLindenUserDir(const std::string &username) std::string userlower(username); LLStringUtil::toLower(userlower); LLStringUtil::replaceChar(userlower, ' ', '_'); - mLindenUserDir = getOSUserAppDir(); - mLindenUserDir += mDirDelimiter; - mLindenUserDir += userlower; + mLindenUserDir = add(getOSUserAppDir(), userlower); } else { @@ -621,9 +824,7 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username) std::string userlower(username); LLStringUtil::toLower(userlower); LLStringUtil::replaceChar(userlower, ' ', '_'); - mPerAccountChatLogsDir = getChatLogsDir(); - mPerAccountChatLogsDir += mDirDelimiter; - mPerAccountChatLogsDir += userlower; + mPerAccountChatLogsDir = add(getChatLogsDir(), userlower); } else { @@ -632,25 +833,59 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username) } -void LLDir::setSkinFolder(const std::string &skin_folder) +void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language) { - mSkinDir = getSkinBaseDir(); - mSkinDir += mDirDelimiter; - mSkinDir += skin_folder; + LL_DEBUGS("LLDir") << "Setting skin '" << skin_folder << "', language '" << language << "'" + << LL_ENDL; + mSkinName = skin_folder; + mLanguage = language; - // user modifications to current skin - // e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle - mUserSkinDir = getOSUserAppDir(); - mUserSkinDir += mDirDelimiter; - mUserSkinDir += "skins"; - mUserSkinDir += mDirDelimiter; - mUserSkinDir += skin_folder; + // This method is called multiple times during viewer initialization. Each + // time it's called, reset mSearchSkinDirs. + mSearchSkinDirs.clear(); // base skin which is used as fallback for all skinned files // e.g. c:\program files\secondlife\skins\default mDefaultSkinDir = getSkinBaseDir(); - mDefaultSkinDir += mDirDelimiter; - mDefaultSkinDir += "default"; + append(mDefaultSkinDir, "default"); + // This is always the most general of the search skin directories. + addSearchSkinDir(mDefaultSkinDir); + + mSkinDir = getSkinBaseDir(); + append(mSkinDir, skin_folder); + // Next level of generality is a skin installed with the viewer. + addSearchSkinDir(mSkinDir); + + // user modifications to skins, current and default + // e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle + mUserSkinDir = getOSUserAppDir(); + append(mUserSkinDir, "skins"); + mUserDefaultSkinDir = mUserSkinDir; + append(mUserDefaultSkinDir, "default"); + append(mUserSkinDir, skin_folder); + // Next level of generality is user modifications to default skin... + addSearchSkinDir(mUserDefaultSkinDir); + // then user-defined skins. + addSearchSkinDir(mUserSkinDir); +} + +void LLDir::addSearchSkinDir(const std::string& skindir) +{ + if (std::find(mSearchSkinDirs.begin(), mSearchSkinDirs.end(), skindir) == mSearchSkinDirs.end()) + { + LL_DEBUGS("LLDir") << "search skin: '" << skindir << "'" << LL_ENDL; + mSearchSkinDirs.push_back(skindir); + } +} + +std::string LLDir::getSkinFolder() const +{ + return mSkinName; +} + +std::string LLDir::getLanguage() const +{ + return mLanguage; } bool LLDir::setCacheDir(const std::string &path) @@ -664,7 +899,7 @@ bool LLDir::setCacheDir(const std::string &path) else { LLFile::mkdir(path); - std::string tempname = path + mDirDelimiter + "temp"; + std::string tempname = add(path, "temp"); LLFILE* file = LLFile::fopen(tempname,"wt"); if (file) { @@ -697,6 +932,57 @@ void LLDir::dumpCurrentDirectories() LL_DEBUGS2("AppInit","Directories") << " SkinDir: " << getSkinDir() << LL_ENDL; } +std::string LLDir::add(const std::string& path, const std::string& name) const +{ + std::string destpath(path); + append(destpath, name); + return destpath; +} + +void LLDir::append(std::string& destpath, const std::string& name) const +{ + // Delegate question of whether we need a separator to helper method. + SepOff sepoff(needSep(destpath, name)); + if (sepoff.first) // do we need a separator? + { + destpath += mDirDelimiter; + } + // If destpath ends with a separator, AND name starts with one, skip + // name's leading separator. + destpath += name.substr(sepoff.second); +} + +LLDir::SepOff LLDir::needSep(const std::string& path, const std::string& name) const +{ + if (path.empty() || name.empty()) + { + // If either path or name are empty, we do not need a separator + // between them. + return SepOff(false, 0); + } + // Here we know path and name are both non-empty. But if path already ends + // with a separator, or if name already starts with a separator, we need + // not add one. + std::string::size_type seplen(mDirDelimiter.length()); + bool path_ends_sep(path.substr(path.length() - seplen) == mDirDelimiter); + bool name_starts_sep(name.substr(0, seplen) == mDirDelimiter); + if ((! path_ends_sep) && (! name_starts_sep)) + { + // If neither path nor name brings a separator to the junction, then + // we need one. + return SepOff(true, 0); + } + if (path_ends_sep && name_starts_sep) + { + // But if BOTH path and name bring a separator, we need not add one. + // Moreover, we should actually skip the leading separator of 'name'. + return SepOff(false, seplen); + } + // Here we know that either path_ends_sep or name_starts_sep is true -- + // but not both. So don't add a separator, and don't skip any characters: + // simple concatenation will do the trick. + return SepOff(false, 0); +} void dir_exists_or_crash(const std::string &dir_name) { diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 35b2654ae7..300ff1eef6 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -56,7 +56,7 @@ typedef enum ELLPath LL_PATH_LAST } ELLPath; - +/// Directory operations class LLDir { public: @@ -98,9 +98,10 @@ class LLDir const std::string &getOSCacheDir() const; // location of OS-specific cache folder (may be empty string) const std::string &getCAFile() const; // File containing TLS certificate authorities const std::string &getDirDelimiter() const; // directory separator for platform (ie. '\' or '/' or ':') + const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default const std::string &getSkinDir() const; // User-specified skin folder. + const std::string &getUserDefaultSkinDir() const; // dir with user modifications to default skin const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin - const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default const std::string getSkinBaseDir() const; // folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins const std::string &getLLPluginDir() const; // Directory containing plugins and plugin shell @@ -115,10 +116,61 @@ class LLDir std::string getExtension(const std::string& filepath) const; // Excludes '.', e.g getExtension("foo.wav") == "wav" // these methods search the various skin paths for the specified file in the following order: - // getUserSkinDir(), getSkinDir(), getDefaultSkinDir() - std::string findSkinnedFilename(const std::string &filename) const; - std::string findSkinnedFilename(const std::string &subdir, const std::string &filename) const; - std::string findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const; + // getUserSkinDir(), getUserDefaultSkinDir(), getSkinDir(), getDefaultSkinDir() + /// param value for findSkinnedFilenames(), explained below + enum ESkinConstraint { CURRENT_SKIN, ALL_SKINS }; + /** + * Given a filename within skin, return an ordered sequence of paths to + * search. Nonexistent files will be filtered out -- which means that the + * vector might be empty. + * + * @param subdir Identify top-level skin subdirectory by passing one of + * LLDir::XUI (file lives under "xui" subtree), LLDir::TEXTURES (file + * lives under "textures" subtree), LLDir::SKINBASE (file lives at top + * level of skin subdirectory). + * @param filename Desired filename within subdir within skin, e.g. + * "panel_login.xml". DO NOT prepend (e.g.) "xui" or the desired language. + * @param constraint Callers perform two different kinds of processing. + * When fetching a XUI file, for instance, the existence of @a filename in + * the specified skin completely supercedes any @a filename in the default + * skin. For that case, leave the default @a constraint=CURRENT_SKIN. The + * returned vector will contain only + * ".../<i>current_skin</i>/xui/en/<i>filename</i>", + * ".../<i>current_skin</i>/xui/<i>current_language</i>/<i>filename</i>". + * But for (e.g.) "strings.xml", we want a given skin to be able to + * override only specific entries from the default skin. Any string not + * defined in the specified skin will be sought in the default skin. For + * that case, pass @a constraint=ALL_SKINS. The returned vector will + * contain at least ".../default/xui/en/strings.xml", + * ".../default/xui/<i>current_language</i>/strings.xml", + * ".../<i>current_skin</i>/xui/en/strings.xml", + * ".../<i>current_skin</i>/xui/<i>current_language</i>/strings.xml". + */ + std::vector<std::string> findSkinnedFilenames(const std::string& subdir, + const std::string& filename, + ESkinConstraint constraint=CURRENT_SKIN) const; + /// Values for findSkinnedFilenames(subdir) parameter + static const char *XUI, *TEXTURES, *SKINBASE; + /** + * Return the base-language pathname from findSkinnedFilenames(), or + * the empty string if no such file exists. Parameters are identical to + * findSkinnedFilenames(). This is shorthand for capturing the vector + * returned by findSkinnedFilenames(), checking for empty() and then + * returning front(). + */ + std::string findSkinnedFilenameBaseLang(const std::string &subdir, + const std::string &filename, + ESkinConstraint constraint=CURRENT_SKIN) const; + /** + * Return the "most localized" pathname from findSkinnedFilenames(), or + * the empty string if no such file exists. Parameters are identical to + * findSkinnedFilenames(). This is shorthand for capturing the vector + * returned by findSkinnedFilenames(), checking for empty() and then + * returning back(). + */ + std::string findSkinnedFilename(const std::string &subdir, + const std::string &filename, + ESkinConstraint constraint=CURRENT_SKIN) const; // random filename in common temporary directory std::string getTempFilename() const; @@ -130,15 +182,37 @@ class LLDir virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir virtual void setPerAccountChatLogsDir(const std::string &username); // Set the per user chat log directory. virtual void setLindenUserDir(const std::string &username); // Set the linden user dir to this user's dir - virtual void setSkinFolder(const std::string &skin_folder); + virtual void setSkinFolder(const std::string &skin_folder, const std::string& language); + virtual std::string getSkinFolder() const; + virtual std::string getLanguage() const; virtual bool setCacheDir(const std::string &path); virtual void dumpCurrentDirectories(); - + // Utility routine std::string buildSLOSCacheDir() const; + /// Append specified @a name to @a destpath, separated by getDirDelimiter() + /// if both are non-empty. + void append(std::string& destpath, const std::string& name) const; + /// Append specified @a name to @a path, separated by getDirDelimiter() + /// if both are non-empty. Return result, leaving @a path unmodified. + std::string add(const std::string& path, const std::string& name) const; + protected: + // Does an add() or append() call need a directory delimiter? + typedef std::pair<bool, unsigned short> SepOff; + SepOff needSep(const std::string& path, const std::string& name) const; + // build mSearchSkinDirs without adding duplicates + void addSearchSkinDir(const std::string& skindir); + + // Internal to findSkinnedFilenames() + template <typename FUNCTION> + void walkSearchSkinDirs(const std::string& subdir, + const std::vector<std::string>& subsubdirs, + const std::string& filename, + const FUNCTION& function) const; + std::string mAppName; // install directory under progams/ ie "SecondLife" std::string mExecutablePathAndName; // full path + Filename of .exe std::string mExecutableFilename; // Filename of .exe @@ -156,10 +230,18 @@ protected: std::string mDefaultCacheDir; // default cache diretory std::string mOSCacheDir; // operating system cache dir std::string mDirDelimiter; + std::string mSkinName; // caller-specified skin name std::string mSkinBaseDir; // Base for skins paths. - std::string mSkinDir; // Location for current skin info. std::string mDefaultSkinDir; // Location for default skin info. + std::string mSkinDir; // Location for current skin info. + std::string mUserDefaultSkinDir; // Location for default skin info. std::string mUserSkinDir; // Location for user-modified skin info. + // Skin directories to search, most general to most specific. This order + // works well for composing fine-grained files, in which an individual item + // in a specific file overrides the corresponding item in more general + // files. Of course, for a file-level search, iterate backwards. + std::vector<std::string> mSearchSkinDirs; + std::string mLanguage; // Current viewer language std::string mLLPluginDir; // Location for plugins and plugin shell }; diff --git a/indra/llvfs/tests/lldir_test.cpp b/indra/llvfs/tests/lldir_test.cpp index ea321c5ae9..323f876c12 100644 --- a/indra/llvfs/tests/lldir_test.cpp +++ b/indra/llvfs/tests/lldir_test.cpp @@ -27,11 +27,167 @@ #include "linden_common.h" +#include "llstring.h" +#include "tests/StringVec.h" #include "../lldir.h" #include "../lldiriterator.h" #include "../test/lltut.h" +#include "stringize.h" +#include <boost/foreach.hpp> +#include <boost/assign/list_of.hpp> + +using boost::assign::list_of; + +// We use ensure_equals(..., vec(list_of(...))) not because it's functionally +// required, but because ensure_equals() knows how to format a StringVec. +// Turns out that when ensure_equals() displays a test failure with just +// list_of("string")("another"), you see 'stringanother' vs. '("string", +// "another")'. +StringVec vec(const StringVec& v) +{ + return v; +} +// For some tests, use a dummy LLDir that uses memory data instead of touching +// the filesystem +struct LLDir_Dummy: public LLDir +{ + /*----------------------------- LLDir API ------------------------------*/ + LLDir_Dummy() + { + // Initialize important LLDir data members based on the filesystem + // data below. + mDirDelimiter = "/"; + mExecutableDir = "install"; + mExecutableFilename = "test"; + mExecutablePathAndName = add(mExecutableDir, mExecutableFilename); + mWorkingDir = mExecutableDir; + mAppRODataDir = "install"; + mSkinBaseDir = add(mAppRODataDir, "skins"); + mOSUserDir = "user"; + mOSUserAppDir = mOSUserDir; + mLindenUserDir = ""; + + // Make the dummy filesystem look more or less like what we expect in + // the real one. + static const char* preload[] = + { + // We group these fixture-data pathnames by basename, rather than + // sorting by full path as you might expect, because the outcome + // of each test strongly depends on which skins/languages provide + // a given basename. + "install/skins/default/colors.xml", + "install/skins/steam/colors.xml", + "user/skins/default/colors.xml", + "user/skins/steam/colors.xml", + + "install/skins/default/xui/en/strings.xml", + "install/skins/default/xui/fr/strings.xml", + "install/skins/steam/xui/en/strings.xml", + "install/skins/steam/xui/fr/strings.xml", + "user/skins/default/xui/en/strings.xml", + "user/skins/default/xui/fr/strings.xml", + "user/skins/steam/xui/en/strings.xml", + "user/skins/steam/xui/fr/strings.xml", + + "install/skins/default/xui/en/floater.xml", + "install/skins/default/xui/fr/floater.xml", + "user/skins/default/xui/fr/floater.xml", + + "install/skins/default/xui/en/newfile.xml", + "install/skins/default/xui/fr/newfile.xml", + "user/skins/default/xui/en/newfile.xml", + + "install/skins/default/html/en-us/welcome.html", + "install/skins/default/html/fr/welcome.html", + + "install/skins/default/textures/only_default.jpeg", + "install/skins/steam/textures/only_steam.jpeg", + "user/skins/default/textures/only_user_default.jpeg", + "user/skins/steam/textures/only_user_steam.jpeg", + + "install/skins/default/future/somefile.txt" + }; + BOOST_FOREACH(const char* path, preload) + { + buildFilesystem(path); + } + } + + virtual ~LLDir_Dummy() {} + + virtual void initAppDirs(const std::string& app_name, const std::string& app_read_only_data_dir) + { + // Implement this when we write a test that needs it + } + + virtual std::string getCurPath() + { + // Implement this when we write a test that needs it + return ""; + } + + virtual U32 countFilesInDir(const std::string& dirname, const std::string& mask) + { + // Implement this when we write a test that needs it + return 0; + } + + virtual BOOL fileExists(const std::string& pathname) const + { + // Record fileExists() calls so we can check whether caching is + // working right. Certain LLDir calls should be able to make decisions + // without calling fileExists() again, having already checked existence. + mChecked.insert(pathname); + // For our simple flat set of strings, see whether the identical + // pathname exists in our set. + return (mFilesystem.find(pathname) != mFilesystem.end()); + } + + virtual std::string getLLPluginLauncher() + { + // Implement this when we write a test that needs it + return ""; + } + + virtual std::string getLLPluginFilename(std::string base_name) + { + // Implement this when we write a test that needs it + return ""; + } + + /*----------------------------- Dummy data -----------------------------*/ + void clearFilesystem() { mFilesystem.clear(); } + void buildFilesystem(const std::string& path) + { + // Split the pathname on slashes, ignoring leading, trailing, doubles + StringVec components; + LLStringUtil::getTokens(path, components, "/"); + // Ensure we have an entry representing every level of this path + std::string partial; + BOOST_FOREACH(std::string component, components) + { + append(partial, component); + mFilesystem.insert(partial); + } + } + + void clear_checked() { mChecked.clear(); } + void ensure_checked(const std::string& pathname) const + { + tut::ensure(STRINGIZE(pathname << " was not checked but should have been"), + mChecked.find(pathname) != mChecked.end()); + } + void ensure_not_checked(const std::string& pathname) const + { + tut::ensure(STRINGIZE(pathname << " was checked but should not have been"), + mChecked.find(pathname) == mChecked.end()); + } + + std::set<std::string> mFilesystem; + mutable std::set<std::string> mChecked; +}; namespace tut { @@ -419,5 +575,193 @@ namespace tut LLFile::rmdir(dir1); LLFile::rmdir(dir2); } -} + template<> template<> + void LLDirTest_object_t::test<6>() + { + set_test_name("findSkinnedFilenames()"); + LLDir_Dummy lldir; + /*------------------------ "default", "en" -------------------------*/ + // Setting "default" means we shouldn't consider any "*/skins/steam" + // directories; setting "en" means we shouldn't consider any "xui/fr" + // directories. + lldir.setSkinFolder("default", "en"); + ensure_equals(lldir.getSkinFolder(), "default"); + ensure_equals(lldir.getLanguage(), "en"); + + // top-level directory of a skin isn't localized + ensure_equals(lldir.findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS), + vec(list_of("install/skins/default/colors.xml") + ("user/skins/default/colors.xml"))); + // We should not have needed to check for skins/default/en. We should + // just "know" that SKINBASE is not localized. + lldir.ensure_not_checked("install/skins/default/en"); + + ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_default.jpeg"), + vec(list_of("install/skins/default/textures/only_default.jpeg"))); + // Nor should we have needed to check skins/default/textures/en + // because textures is known not to be localized. + lldir.ensure_not_checked("install/skins/default/textures/en"); + + StringVec expected(vec(list_of("install/skins/default/xui/en/strings.xml") + ("user/skins/default/xui/en/strings.xml"))); + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS), + expected); + // The first time, we had to probe to find out whether xui was localized. + lldir.ensure_checked("install/skins/default/xui/en"); + lldir.clear_checked(); + // Now make the same call again -- should return same result -- + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS), + expected); + // but this time it should remember that xui is localized. + lldir.ensure_not_checked("install/skins/default/xui/en"); + + // localized subdir with "en-us" instead of "en" + ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"), + vec(list_of("install/skins/default/html/en-us/welcome.html"))); + lldir.ensure_checked("install/skins/default/html/en"); + lldir.ensure_checked("install/skins/default/html/en-us"); + lldir.clear_checked(); + ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"), + vec(list_of("install/skins/default/html/en-us/welcome.html"))); + lldir.ensure_not_checked("install/skins/default/html/en"); + lldir.ensure_not_checked("install/skins/default/html/en-us"); + + ensure_equals(lldir.findSkinnedFilenames("future", "somefile.txt"), + vec(list_of("install/skins/default/future/somefile.txt"))); + // Test probing for an unrecognized unlocalized future subdir. + lldir.ensure_checked("install/skins/default/future/en"); + lldir.clear_checked(); + ensure_equals(lldir.findSkinnedFilenames("future", "somefile.txt"), + vec(list_of("install/skins/default/future/somefile.txt"))); + // Second time it should remember that future is unlocalized. + lldir.ensure_not_checked("install/skins/default/future/en"); + + // When language is set to "en", requesting an html file pulls up the + // "en-us" version -- not because it magically matches those strings, + // but because there's no "en" localization and it falls back on the + // default "en-us"! Note that it would probably still be better to + // make the default localization be "en" and allow "en-gb" (or + // whatever) localizations, which would work much more the way you'd + // expect. + ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"), + vec(list_of("install/skins/default/html/en-us/welcome.html"))); + + /*------------------------ "default", "fr" -------------------------*/ + // We start being able to distinguish localized subdirs from + // unlocalized when we ask for a non-English language. + lldir.setSkinFolder("default", "fr"); + ensure_equals(lldir.getLanguage(), "fr"); + + // pass merge=true to request this filename in all relevant skins + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS), + vec(list_of + ("install/skins/default/xui/en/strings.xml") + ("install/skins/default/xui/fr/strings.xml") + ("user/skins/default/xui/en/strings.xml") + ("user/skins/default/xui/fr/strings.xml"))); + + // pass (or default) merge=false to request only most specific skin + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"), + vec(list_of + ("user/skins/default/xui/en/strings.xml") + ("user/skins/default/xui/fr/strings.xml"))); + + // Our dummy floater.xml has a user localization (for "fr") but no + // English override. This is a case in which CURRENT_SKIN nonetheless + // returns paths from two different skins. + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "floater.xml"), + vec(list_of + ("install/skins/default/xui/en/floater.xml") + ("user/skins/default/xui/fr/floater.xml"))); + + // Our dummy newfile.xml has an English override but no user + // localization. This is another case in which CURRENT_SKIN + // nonetheless returns paths from two different skins. + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "newfile.xml"), + vec(list_of + ("user/skins/default/xui/en/newfile.xml") + ("install/skins/default/xui/fr/newfile.xml"))); + + ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"), + vec(list_of + ("install/skins/default/html/en-us/welcome.html") + ("install/skins/default/html/fr/welcome.html"))); + + /*------------------------ "default", "zh" -------------------------*/ + lldir.setSkinFolder("default", "zh"); + // Because strings.xml has only a "fr" override but no "zh" override + // in any skin, the most localized version we can find is "en". + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"), + vec(list_of("user/skins/default/xui/en/strings.xml"))); + + /*------------------------- "steam", "en" --------------------------*/ + lldir.setSkinFolder("steam", "en"); + + ensure_equals(lldir.findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS), + vec(list_of + ("install/skins/default/colors.xml") + ("install/skins/steam/colors.xml") + ("user/skins/default/colors.xml") + ("user/skins/steam/colors.xml"))); + + ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_default.jpeg"), + vec(list_of("install/skins/default/textures/only_default.jpeg"))); + + ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_steam.jpeg"), + vec(list_of("install/skins/steam/textures/only_steam.jpeg"))); + + ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_user_default.jpeg"), + vec(list_of("user/skins/default/textures/only_user_default.jpeg"))); + + ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_user_steam.jpeg"), + vec(list_of("user/skins/steam/textures/only_user_steam.jpeg"))); + + // CURRENT_SKIN + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"), + vec(list_of("user/skins/steam/xui/en/strings.xml"))); + + // pass constraint=ALL_SKINS to request this filename in all relevant skins + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS), + vec(list_of + ("install/skins/default/xui/en/strings.xml") + ("install/skins/steam/xui/en/strings.xml") + ("user/skins/default/xui/en/strings.xml") + ("user/skins/steam/xui/en/strings.xml"))); + + /*------------------------- "steam", "fr" --------------------------*/ + lldir.setSkinFolder("steam", "fr"); + + // pass CURRENT_SKIN to request only the most specialized files + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"), + vec(list_of + ("user/skins/steam/xui/en/strings.xml") + ("user/skins/steam/xui/fr/strings.xml"))); + + // pass ALL_SKINS to request this filename in all relevant skins + ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS), + vec(list_of + ("install/skins/default/xui/en/strings.xml") + ("install/skins/default/xui/fr/strings.xml") + ("install/skins/steam/xui/en/strings.xml") + ("install/skins/steam/xui/fr/strings.xml") + ("user/skins/default/xui/en/strings.xml") + ("user/skins/default/xui/fr/strings.xml") + ("user/skins/steam/xui/en/strings.xml") + ("user/skins/steam/xui/fr/strings.xml"))); + } + + template<> template<> + void LLDirTest_object_t::test<7>() + { + set_test_name("add()"); + LLDir_Dummy lldir; + ensure_equals("both empty", lldir.add("", ""), ""); + ensure_equals("path empty", lldir.add("", "b"), "b"); + ensure_equals("name empty", lldir.add("a", ""), "a"); + ensure_equals("both simple", lldir.add("a", "b"), "a/b"); + ensure_equals("name leading slash", lldir.add("a", "/b"), "a/b"); + ensure_equals("path trailing slash", lldir.add("a/", "b"), "a/b"); + ensure_equals("both bring slashes", lldir.add("a/", "/b"), "a/b"); + } +} diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 2ffb0d8503..b775249219 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -897,7 +897,8 @@ bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, std::vector<std::string>::const_iterator itor; - for (itor = paths.begin(), ++itor; itor != paths.end(); ++itor) + // We've already dealt with the first item, skip that one + for (itor = paths.begin() + 1; itor != paths.end(); ++itor) { std::string layer_filename = *itor; if(layer_filename.empty() || layer_filename == filename) diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt index aa70e64b71..4f39e941a1 100644 --- a/indra/mac_updater/CMakeLists.txt +++ b/indra/mac_updater/CMakeLists.txt @@ -63,6 +63,7 @@ target_link_libraries(mac-updater ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${COCOA_LIBRARIES} + ${BOOST_FILESYSTEM_LIBRARY} ${IOKIT_LIBRARY} ${CURL_LIBRARIES} ${CARES_LIBRARIES} diff --git a/indra/mac_updater/MacUpdaterAppDelegate.mm b/indra/mac_updater/MacUpdaterAppDelegate.mm index 179946a238..3ddf8f9274 100644 --- a/indra/mac_updater/MacUpdaterAppDelegate.mm +++ b/indra/mac_updater/MacUpdaterAppDelegate.mm @@ -124,30 +124,6 @@ void sendProgress(int cur, int max, const std::string str) setProgressText(str); } -bool mkTempDir(boost::filesystem::path& temp_dir) -{ - NSString * tempDir = NSTemporaryDirectory(); - if (tempDir == nil) - tempDir = @"/tmp/"; - - std::string* temp_str = NSToString(tempDir); - *temp_str += std::string("SecondLifeUpdate_XXXXXX"); - - char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ - strncpy(temp, temp_str->c_str(), temp_str->length()); - - if(mkdtemp(temp) == NULL) - { - return false; - } - - temp_dir = boost::filesystem::path(temp); - - delete temp_str; - - return true; -} - bool copyDir(const std::string& src_dir, const std::string& dest_dir) { NSString* file = [NSString stringWithCString:src_dir.c_str() diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index 47fc16769c..34d2b07438 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -494,6 +494,20 @@ bool LLMacUpdater::doInstall(const boost::filesystem::path& app_dir, return true; } +bool mkTempDir(boost::filesystem::path& temp_dir) +{ + char temp_str[PATH_MAX] = "/tmp/SecondLifeUpdate_XXXXXX"; + + if(mkdtemp(temp_str) == NULL) + { + return false; + } + + temp_dir = boost::filesystem::path(temp_str); + + return true; +} + void* LLMacUpdater::updatethreadproc(void*) { char tempDir[PATH_MAX] = ""; /* Flawfinder: ignore */ diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a8a7e05fd5..7eea9ece5a 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -18,6 +18,7 @@ include(JsonCpp) include(LLAudio) include(LLCharacter) include(LLCommon) +include(LLCoreHttp) include(LLImage) include(LLImageJ2COJ) include(LLInventory) @@ -57,6 +58,7 @@ include_directories( ${LLAUDIO_INCLUDE_DIRS} ${LLCHARACTER_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} + ${LLCOREHTTP_INCLUDE_DIRS} ${LLPHYSICS_INCLUDE_DIRS} ${FMOD_INCLUDE_DIR} ${LLIMAGE_INCLUDE_DIRS} @@ -97,6 +99,7 @@ set(viewer_SOURCE_FILES llagentwearables.cpp llagentwearablesfetch.cpp llanimstatelabels.cpp + llappcorehttp.cpp llappearancemgr.cpp llappviewer.cpp llappviewerlistener.cpp @@ -672,6 +675,7 @@ set(viewer_HEADER_FILES llagentwearables.h llagentwearablesfetch.h llanimstatelabels.h + llappcorehttp.h llappearance.h llappearancemgr.h llappviewer.h @@ -1812,6 +1816,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLXML_LIBRARIES} ${LSCRIPT_LIBRARIES} ${LLMATH_LIBRARIES} + ${LLCOREHTTP_LIBRARIES} ${LLCOMMON_LIBRARIES} ${NDOF_LIBRARY} ${HUNSPELL_LIBRARY} @@ -1956,6 +1961,12 @@ if (DARWIN) ) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-updater mac-crash-logger) + + if (ENABLE_SIGNING) + set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") + else (ENABLE_SIGNING) + set(SIGNING_SETTING "") + endif (ENABLE_SIGNING) if (PACKAGE) add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME}) @@ -1975,6 +1986,7 @@ if (DARWIN) --login_channel=${VIEWER_LOGIN_CHANNEL} --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched + ${SIGNING_SETTING} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 711191128b..7ab7787d77 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -357,7 +357,7 @@ <key>count</key> <integer>1</integer> <key>map-to</key> - <string>SkinFolder</string> + <string>SkinCurrent</string> </map> <key>slurl</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1bf773bb9e..7801edb155 100644..100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3270,6 +3270,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>FastCacheFetchEnabled</key> + <map> + <key>Comment</key> + <string>Enable texture fast cache fetching if set</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <string>1</string> + </map> <key>FeatureManagerHTTPTable</key> <map> <key>Comment</key> @@ -4040,17 +4051,6 @@ <key>Value</key> <integer>305</integer> </map> - <key>HelpUseLocal</key> - <map> - <key>Comment</key> - <string>If set, always use this for help: skins/default/html/[LANGUAGE]/help-offline/index.html</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>HelpURLFormat</key> <map> <key>Comment</key> @@ -8090,7 +8090,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0</real> + <real>-0.007</real> </map> <key>RenderShadowOffsetError</key> <map> @@ -10778,6 +10778,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>TextureFetchConcurrency</key> + <map> + <key>Comment</key> + <string>Maximum number of HTTP connections used for texture fetches</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>TextureFetchDebuggerEnabled</key> <map> <key>Comment</key> @@ -10789,6 +10800,83 @@ <key>Value</key> <integer>0</integer> </map> + <key>TextureFetchSource</key> + <map> + <key>Comment</key> + <string>Debug use: Source to fetch textures</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>TextureFetchUpdateHighPriority</key> + <map> + <key>Comment</key> + <string>Number of high priority textures to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>32</integer> + </map> + <key>TextureFetchUpdateMaxMediumPriority</key> + <map> + <key>Comment</key> + <string>Maximum number of medium priority textures to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>256</integer> + </map> + <key>TextureFetchUpdateMinMediumPriority</key> + <map> + <key>Comment</key> + <string>Minimum number of medium priority textures to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>32</integer> + </map> + <key>TextureFetchUpdatePriorityThreshold</key> + <map> + <key>Comment</key> + <string>Threshold under which textures will be considered too low priority and skipped for update</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>0.0</integer> + </map> + <key>TextureFetchUpdateSkipLowPriority</key> + <map> + <key>Comment</key> + <string>Flag indicating if we want to skip textures with too low of a priority</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>TextureFetchUpdatePriorities</key> + <map> + <key>Comment</key> + <string>Number of priority texture to update per frame</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>32</integer> + </map> <key>TextureLoadFullRes</key> <map> <key>Comment</key> @@ -12285,6 +12373,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>sourceid</key> + <map> + <key>Comment</key> + <string>Identify referring agency to Linden web servers</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string /> + </map> <key>SpeakerParticipantDefaultOrder</key> <map> <key>Comment</key> @@ -13971,5 +14070,17 @@ <real>1.0</real> </array> </map> + + <key>SimulateFBOFailure</key> + <map> + <key>Comment</key> + <string>[DEBUG] Make allocateScreenBuffer return false. Used to test error handling.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 46d2aa4877..bfd9b9b3eb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -46,6 +46,6 @@ void main() frag_data[0] = vec4(diff.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 680eadb852..23c4ea2fff 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -52,5 +52,5 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(tnorm); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index b2027d3a5d..c1fa9e4aac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -49,6 +49,6 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index ead384b07c..4c68123fac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -48,5 +48,5 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index f73fa6f231..ad65c7d330 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -49,6 +49,6 @@ void main() frag_data[0] = vec4(col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); // spec vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 227aa2aae3..86390bdd83 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -42,6 +42,6 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index d442e5403a..788b966af8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -41,5 +41,5 @@ void main() frag_data[1] = vertex_color.aaaa; // spec //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl index e02a7b405b..2cef8f2a5d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl @@ -2093,7 +2093,6 @@ uniform sampler2D diffuseMap; uniform vec2 rcp_screen_res; uniform vec4 rcp_frame_opt; uniform vec4 rcp_frame_opt2; -uniform vec2 screen_res; VARYING vec2 vary_fragcoord; VARYING vec2 vary_tc; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 4d01eeb64e..7e79317543 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -79,7 +79,7 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm norm = normalize(norm); vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index f671d5b750..75757b26c8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -84,7 +84,7 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm float da = dot(norm, lv); if (da < 0.0) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 66e3cf6d13..89448e2167 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -277,7 +277,7 @@ void main() float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 2422d73a3e..bac74cbbef 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -123,7 +123,7 @@ void main() vec4 pos = getPosition(pos_screen); vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm frag_color[0] = 1.0; frag_color[1] = calcAmbientOcclusion(pos, norm); diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 8a5e482e80..daf1cc7ea2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -56,6 +56,6 @@ void main() frag_data[0] = vec4(outColor.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 6cf6106b51..da253846ef 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -48,5 +48,5 @@ void main() frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0); frag_data[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); - frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); + frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 42dc7c0980..3427d6db57 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -161,5 +161,5 @@ void main() frag_data[0] = vec4(color.rgb, 0.5); // diffuse frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec - frag_data[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace + frag_data[2] = vec4(screenspacewavef.xyz*0.5+0.5, screenspacewavef.z*0.5); // normalxyz, displace } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 8db4cb58cf..12706f130b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -34,10 +34,10 @@ out vec4 frag_color; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DRect depthMap; uniform mat4 shadow_matrix[6]; @@ -58,22 +58,22 @@ uniform float shadow_bias; uniform mat4 inv_proj; -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; - - stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here + + stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here - float cs = shadow2DRect(shadowMap, stc.xyz).x; + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; - - return shadow*0.2; + + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + + return shadow*0.2; } @@ -99,8 +99,7 @@ void main() if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; shadow += pcfShadow(shadowMap3, lpos)*w; @@ -111,8 +110,7 @@ void main() if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; @@ -123,8 +121,7 @@ void main() if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; @@ -135,8 +132,7 @@ void main() if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl index 33958a5010..228dc104ac 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -31,17 +31,16 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DRect depthMap; uniform sampler2D diffuseMap; uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; -uniform vec2 shadow_res; vec3 atmosLighting(vec3 light); vec3 scaleSoftClip(vec3 light); @@ -54,6 +53,7 @@ VARYING vec3 vary_pointlight_col; VARYING vec2 vary_texcoord0; VARYING vec4 vertex_color; +uniform vec2 shadow_res; uniform float shadow_bias; uniform mat4 inv_proj; @@ -71,22 +71,22 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; - stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here + stc.x = floor(stc.x*shadow_res.x + fract(stc.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here - float cs = shadow2DRect(shadowMap, stc.xyz).x; + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; - - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; + + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; - return shadow*0.2; + return shadow*0.2; } @@ -112,8 +112,7 @@ void main() if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; shadow += pcfShadow(shadowMap3, lpos)*w; @@ -124,8 +123,7 @@ void main() if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; @@ -136,8 +134,7 @@ void main() if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; @@ -148,8 +145,7 @@ void main() if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl index 2093fc37dc..c3950a10e1 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -33,17 +33,16 @@ out vec4 frag_color; uniform float minimum_alpha; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DRect depthMap; uniform sampler2D diffuseMap; uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; -uniform vec2 shadow_res; vec3 atmosLighting(vec3 light); vec3 scaleSoftClip(vec3 light); @@ -55,6 +54,8 @@ VARYING vec3 vary_position; VARYING vec3 vary_pointlight_col; VARYING vec2 vary_texcoord0; +uniform vec2 shadow_res; + uniform float shadow_bias; uniform mat4 inv_proj; @@ -72,20 +73,20 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) { stc.xyz /= stc.w; stc.z += shadow_bias; - stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here + stc.x = floor(stc.x*shadow_res.x + fract(stc.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here + float cs = shadow2D(shadowMap, stc.xyz).x; - float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; return shadow*0.2; } @@ -120,8 +121,7 @@ void main() if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; shadow += pcfShadow(shadowMap3, lpos)*w; @@ -132,8 +132,7 @@ void main() if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; @@ -144,8 +143,7 @@ void main() if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; @@ -156,8 +154,7 @@ void main() if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index f7f1f649ce..5621e47ab7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -154,7 +154,7 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm norm = normalize(norm); float l_dist = -dot(lv, proj_n); diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index a137bea30f..9df9d75905 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -279,7 +279,7 @@ void main() float depth = texture2DRect(depthMap, tc.xy).r; vec3 pos = getPosition_d(tc, depth).xyz; vec3 norm = texture2DRect(normalMap, tc).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index ab077d9e02..6d6ad6d565 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -154,7 +154,7 @@ void main() } vec3 norm = texture2DRect(normalMap, frag.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = (norm.xyz-0.5)*2.0; // unpack norm norm = normalize(norm); float l_dist = -dot(lv, proj_n); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index db3d760359..890486c4b1 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -35,10 +35,10 @@ out vec4 frag_color; uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DShadow shadowMap4; uniform sampler2DShadow shadowMap5; @@ -55,10 +55,10 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; -uniform vec2 shadow_res; uniform vec2 proj_shadow_res; uniform vec3 sun_dir; +uniform vec2 shadow_res; uniform float shadow_bias; uniform float shadow_offset; @@ -78,30 +78,31 @@ vec4 getPosition(vec2 pos_screen) return pos; } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; - stc.z += shadow_bias*scl; + stc.z += shadow_bias; - stc.x = floor(stc.x + fract(pos_screen.y*0.666666666)); // add some jitter to X sample pos according to Y to disguise the snapping going on here + stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here + float cs = shadow2D(shadowMap, stc.xyz).x; - float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, -1.5, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + - return shadow*0.2; + return shadow*0.2; } -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += spot_shadow_bias*scl; stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap - + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; @@ -125,7 +126,7 @@ void main() vec4 pos = getPosition(pos_screen); vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm float displace = nmap4.w; vec3 norm = nmap4.xyz; @@ -162,8 +163,7 @@ void main() if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; @@ -174,8 +174,7 @@ void main() if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; @@ -186,7 +185,6 @@ void main() if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; @@ -198,7 +196,6 @@ void main() if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; @@ -237,11 +234,11 @@ void main() //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; - frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen); + frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen); //spotlight shadow 2 lpos = shadow_matrix[5]*spos; - frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen); + frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen); //frag_color.rgb = pos.xyz; //frag_color.b = shadow; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index dfe108eb01..2dcd3d656f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -34,10 +34,10 @@ out vec4 frag_color; uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; uniform sampler2DShadow shadowMap4; uniform sampler2DShadow shadowMap5; uniform sampler2D noiseMap; @@ -55,10 +55,11 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; -uniform vec2 shadow_res; uniform vec2 proj_shadow_res; uniform vec3 sun_dir; +uniform vec2 shadow_res; + uniform float shadow_bias; uniform float shadow_offset; @@ -139,30 +140,30 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) return min(ret, 1.0); } -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; - stc.z += shadow_bias*scl; + stc.z += shadow_bias; - stc.x = floor(stc.x + fract(pos_screen.y*0.666666666)); + stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; + float cs = shadow2D(shadowMap, stc.xyz).x; - float cs = shadow2DRect(shadowMap, stc.xyz).x; float shadow = cs; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x; - shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x; - + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + return shadow*0.2; } -float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) +float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen) { stc.xyz /= stc.w; stc.z += spot_shadow_bias*scl; stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap - + float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs; @@ -186,7 +187,7 @@ void main() vec4 pos = getPosition(pos_screen); vec4 nmap4 = texture2DRect(normalMap, pos_screen); - nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm float displace = nmap4.w; vec3 norm = nmap4.xyz; @@ -223,8 +224,7 @@ void main() if (spos.z < near_split.z) { lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w; @@ -235,8 +235,7 @@ void main() if (spos.z < near_split.y && spos.z > far_split.z) { lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; @@ -247,8 +246,7 @@ void main() if (spos.z < near_split.x && spos.z > far_split.y) { lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; @@ -259,8 +257,7 @@ void main() if (spos.z > far_split.x) { lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - + float w = 1.0; w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; @@ -298,11 +295,11 @@ void main() //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; - frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen); + frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen); //spotlight shadow 2 lpos = shadow_matrix[5]*spos; - frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen); + frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen); //frag_color.rgb = pos.xyz; //frag_color.b = shadow; diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index eeb632acaf..e877e15053 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 32 +version 33 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -98,9 +98,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 @@ -130,9 +127,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -160,9 +154,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -190,9 +181,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 2 // @@ -230,30 +218,66 @@ RenderFSAASamples 1 2 // list Unknown RenderVBOEnable 1 0 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 0 Hardware (just old) // list Class0 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 1 Hardware // list Class1 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 3 Hardware (make it purty) +// Class 3 Hardware (deferred enabled) // list Class3 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 + +// +// Class 4 Hardware (deferred + SSAO) +// +list Class4 +RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 + +// +// Class 5 Hardware (deferred + SSAO + shadows) +// +list Class5 +RenderVBOEnable 1 1 +RenderShadowDetail 1 2 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 + // // VRAM > 512MB diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 3a0e7e3697..5699bd9c8a 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 27 +version 28 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -95,9 +95,6 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -126,9 +123,6 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -156,9 +150,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -186,9 +177,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 2 // @@ -226,32 +214,66 @@ RenderFSAASamples 1 2 // list Unknown RenderVBOEnable 1 0 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 0 Hardware (just old) // list Class0 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 1 Hardware // list Class1 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 3 Hardware (make it purty) +// Class 3 Hardware (deferred enabled) // list Class3 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 // +// Class 4 Hardware (deferred + SSAO) +// +list Class4 +RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 + +// +// Class 5 Hardware (deferred + SSAO + shadows) +// +list Class5 +RenderVBOEnable 1 1 +RenderShadowDetail 1 2 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +// // VRAM > 512MB // list VRAMGT512 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 96362ff4bb..3a91f19c58 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 32 +version 34 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -97,9 +97,6 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -128,9 +125,6 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -158,9 +152,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -188,9 +179,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 2 RenderFSAASamples 1 2 // @@ -228,30 +216,65 @@ RenderFSAASamples 1 2 // list Unknown RenderVBOEnable 1 0 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 0 Hardware (just old) // list Class0 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 1 Hardware // list Class1 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 3 Hardware (make it purty) +// Class 3 Hardware (deferred enabled) // list Class3 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 + +// +// Class 4 Hardware (deferred + SSAO) +// +list Class4 +RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 + +// +// Class 5 Hardware (deferred + SSAO + shadows) +// +list Class5 +RenderVBOEnable 1 1 +RenderShadowDetail 1 2 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 // // No Pixel Shaders available diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index a945f7a693..ad16e2533b 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 31 +version 32 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -63,9 +63,9 @@ Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 @@ -97,9 +97,6 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -128,9 +125,6 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -158,9 +152,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 RenderFSAASamples 1 0 // @@ -188,9 +179,6 @@ RenderVolumeLODFactor 1 1.125 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 2 RenderFSAASamples 1 2 // @@ -228,30 +216,65 @@ RenderFSAASamples 1 2 // list Unknown RenderVBOEnable 1 0 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 0 Hardware (just old) // list Class0 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 // // Class 1 Hardware // list Class1 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 2 Hardware (make it purty) +// Class 2 Hardware // list Class2 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 + // -// Class 3 Hardware (make it purty) +// Class 3 Hardware (deferred enabled) // list Class3 RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 0 + +// +// Class 4 Hardware (deferred + SSAO) +// +list Class4 +RenderVBOEnable 1 1 +RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 + +// +// Class 5 Hardware (deferred + SSAO + shadows) +// +list Class5 +RenderVBOEnable 1 1 +RenderShadowDetail 1 2 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 // // VRAM > 512MB diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 777d54a5c3..4c39014c8b 100644 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -17,520 +17,582 @@ // // Format: // Fields are separated by one or more tab (not space) characters -// <recognizer name> <regular expression> <class> <supported> +// <recognizer name> <regular expression> <class> <supported> <stats based> <expected OpenGL version> // // Class Numbers: // 0 - Defaults to low graphics settings. No shaders on by default // 1 - Defaults to mid graphics settings. Basic shaders on by default // 2 - Defaults to high graphics settings. Atmospherics on by default. -// 3 - Same as class 2 for now. +// 3 - Same as 2, but with lighting and shadows enabled. +// 4 - Same as 3, but with ambient occlusion enabled. +// 5 - Same as 4, but with shadows set to "Sun/Moon+Projectors." // // Supported Number: // 0 - We claim to not support this card. // 1 - We claim to support this card. // -3Dfx .*3Dfx.* 0 0 -3Dlabs .*3Dlabs.* 0 0 -ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 -ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 -ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 -ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 -ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 -ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 -ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 -ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 2 1 -ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 -ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 -ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 -ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 -ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 -ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 -ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 -ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 3 1 -ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1 -ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 3 1 -ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 3 1 -ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 -ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 -ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 -ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 -ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 -ATI ASUS EAH29xx .*ATI.*ASUS.*EAH29.* 3 1 -ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1 -ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 3 1 -ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 3 1 -ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 1 1 -ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 1 1 -ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1 -ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1 -ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 3 1 -ATI ASUS EAH6xxx .*ATI.*ASUS.*EAH6.* 3 1 -ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 3 1 -ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 -ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 3 1 -ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 -ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 2 1 -ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 2 1 -ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 2 1 -ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 -ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 1 1 -ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1 -ATI Display Adapter .*ATI.*display adapter.* 0 1 -ATI FireGL 5200 .*ATI.*FireGL V52.* 0 1 -ATI FireGL 5xxx .*ATI.*FireGL V5.* 1 1 -ATI FireGL .*ATI.*Fire.*GL.* 0 1 -ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 -ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 -ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 -ATI FirePro M7820 .*ATI.*FirePro.*M78.* 3 1 -ATI FireMV .*ATI.*FireMV.* 0 1 -ATI Geforce 9500 GT .*ATI.*Geforce 9500 *GT.* 2 1 -ATI Geforce 9600 GT .*ATI.*Geforce 9600 *GT.* 2 1 -ATI Geforce 9800 GT .*ATI.*Geforce 9800 *GT.* 2 1 -ATI Generic .*ATI.*Generic.* 0 0 -ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 -ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 -ATI M52 .*ATI.*M52.* 1 1 -ATI M54 .*ATI.*M54.* 1 1 -ATI M56 .*ATI.*M56.* 1 1 -ATI M71 .*ATI.*M71.* 1 1 -ATI M72 .*ATI.*M72.* 1 1 -ATI M76 .*ATI.*M76.* 3 1 -ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 3 1 -ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 3 1 -ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 -ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 -ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 -ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 -ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 -ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 1 1 -ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 0 1 -ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1 -ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 2 1 -ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1 -ATI Mobility Radeon HD 550v .*ATI.*Mobility.*HD *550v.* 2 1 -ATI Mobility Radeon HD 560v .*ATI.*Mobility.*HD *560v.* 2 1 -ATI Mobility Radeon HD 565v .*ATI.*Mobility.*HD *565v.* 2 1 -ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD *23.* 2 1 -ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD *24.* 2 1 -ATI Mobility Radeon HD 2600 .*ATI.*Mobility.*HD *26.* 3 1 -ATI Mobility Radeon HD 2700 .*ATI.*Mobility.*HD *27.* 3 1 -ATI Mobility Radeon HD 3100 .*ATI.*Mobility.*HD *31.* 0 1 -ATI Mobility Radeon HD 3200 .*ATI.*Mobility.*HD *32.* 0 1 -ATI Mobility Radeon HD 3400 .*ATI.*Mobility.*HD *34.* 2 1 -ATI Mobility Radeon HD 3600 .*ATI.*Mobility.*HD *36.* 3 1 -ATI Mobility Radeon HD 3800 .*ATI.*Mobility.*HD *38.* 3 1 -ATI Mobility Radeon HD 4200 .*ATI.*Mobility.*HD *42.* 2 1 -ATI Mobility Radeon HD 4300 .*ATI.*Mobility.*HD *43.* 2 1 -ATI Mobility Radeon HD 4500 .*ATI.*Mobility.*HD *45.* 3 1 -ATI Mobility Radeon HD 4600 .*ATI.*Mobility.*HD *46.* 3 1 -ATI Mobility Radeon HD 4800 .*ATI.*Mobility.*HD *48.* 3 1 -ATI Mobility Radeon HD 5100 .*ATI.*Mobility.*HD *51.* 3 1 -ATI Mobility Radeon HD 5300 .*ATI.*Mobility.*HD *53.* 3 1 -ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD *54.* 3 1 -ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD *55.* 3 1 -ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD *56.* 3 1 -ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD *57.* 3 1 -ATI Mobility Radeon HD 6200 .*ATI.*Mobility.*HD *62.* 3 1 -ATI Mobility Radeon HD 6300 .*ATI.*Mobility.*HD *63.* 3 1 -ATI Mobility Radeon HD 6400M .*ATI.*Mobility.*HD *64.* 3 1 -ATI Mobility Radeon HD 6500M .*ATI.*Mobility.*HD *65.* 3 1 -ATI Mobility Radeon HD 6600M .*ATI.*Mobility.*HD *66.* 3 1 -ATI Mobility Radeon HD 6700M .*ATI.*Mobility.*HD *67.* 3 1 -ATI Mobility Radeon HD 6800M .*ATI.*Mobility.*HD *68.* 3 1 -ATI Mobility Radeon HD 6900M .*ATI.*Mobility.*HD *69.* 3 1 -ATI Radeon HD 2300 .*ATI.*Radeon HD *23.. 2 1 -ATI Radeon HD 2400 .*ATI.*Radeon HD *24.. 2 1 -ATI Radeon HD 2600 .*ATI.*Radeon HD *26.. 2 1 -ATI Radeon HD 2900 .*ATI.*Radeon HD *29.. 3 1 -ATI Radeon HD 3000 .*ATI.*Radeon HD *30.. 0 1 -ATI Radeon HD 3100 .*ATI.*Radeon HD *31.. 1 1 -ATI Radeon HD 3200 .*ATI.*Radeon HD *32.. 1 1 -ATI Radeon HD 3300 .*ATI.*Radeon HD *33.. 2 1 -ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 2 1 -ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 -ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 -ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 -ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 -ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 -ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 -ATI Radeon HD 4300 .*ATI.*Radeon HD *43.. 2 1 -ATI Radeon HD 4400 .*ATI.*Radeon HD *44.. 2 1 -ATI Radeon HD 4500 .*ATI.*Radeon HD *45.. 3 1 -ATI Radeon HD 4600 .*ATI.*Radeon HD *46.. 3 1 -ATI Radeon HD 4700 .*ATI.*Radeon HD *47.. 3 1 -ATI Radeon HD 4800 .*ATI.*Radeon HD *48.. 3 1 -ATI Radeon HD 5400 .*ATI.*Radeon HD *54.. 3 1 -ATI Radeon HD 5500 .*ATI.*Radeon HD *55.. 3 1 -ATI Radeon HD 5600 .*ATI.*Radeon HD *56.. 3 1 -ATI Radeon HD 5700 .*ATI.*Radeon HD *57.. 3 1 -ATI Radeon HD 5800 .*ATI.*Radeon HD *58.. 3 1 -ATI Radeon HD 5900 .*ATI.*Radeon HD *59.. 3 1 -ATI Radeon HD 6200 .*ATI.*Radeon HD *62.. 3 1 -ATI Radeon HD 6300 .*ATI.*Radeon HD *63.. 3 1 -ATI Radeon HD 6400 .*ATI.*Radeon HD *64.. 3 1 -ATI Radeon HD 6500 .*ATI.*Radeon HD *65.. 3 1 -ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 -ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 -ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 3 1 -ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 3 1 -ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 -ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 -ATI Radeon 3000 .*ATI.*Radeon 30.. 0 1 -ATI Radeon 3100 .*ATI.*Radeon 31.. 1 1 -ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 -ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 -ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 -ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 -ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 -ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 -ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 -ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 -ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 -ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 -ATI Radeon RV250 .*ATI.*RV250.* 0 1 -ATI Radeon RV600 .*ATI.*RV6.* 1 1 -ATI Radeon RX700 .*ATI.*RX70.* 1 1 -ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 -ATI RS880M .*ATI.*RS880M 1 1 -ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 -ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 -ATI Radeon X300 .*ATI.*Radeon *X3.* 0 1 -ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 -ATI Radeon X500 .*ATI.*Radeon ?X5.* 0 1 -ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1 -ATI Radeon X700 .*ATI.*Radeon ?X7.* 1 1 -ATI Radeon X800 .*ATI.*Radeon ?X8.* 2 1 -ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 -ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 -ATI Rage 128 .*ATI.*Rage 128.* 0 1 -ATI R300 (9700) .*R300.* 1 1 -ATI R350 (9800) .*R350.* 1 1 -ATI R580 (X1900) .*R580.* 3 1 -ATI RC410 (Xpress 200) .*RC410.* 0 0 -ATI RS48x (Xpress 200x) .*RS48.* 0 0 -ATI RS600 (Xpress 3200) .*RS600.* 0 0 -ATI RV350 (9600) .*RV350.* 0 1 -ATI RV370 (X300) .*RV370.* 0 1 -ATI RV410 (X700) .*RV410.* 1 1 -ATI RV515 .*RV515.* 1 1 -ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 -ATI RV380 .*RV380.* 0 1 -ATI RV530 .*RV530.* 1 1 -ATI RX480 (Xpress 200P) .*RX480.* 0 1 -ATI RX700 .*RX700.* 1 1 -AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 -AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 -AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 -AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 -AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 -AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 -AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 -AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 -AMD PARK .*(AMD|ATI).*Park.* 3 1 -AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 -AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 -AMD RS780 (HD 3200) .*RS780.* 0 1 -AMD RS880 (HD 4200) .*RS880.* 1 1 -AMD RV610 (HD 2400) .*RV610.* 1 1 -AMD RV620 (HD 3400) .*RV620.* 1 1 -AMD RV630 (HD 2600) .*RV630.* 2 1 -AMD RV635 (HD 3600) .*RV635.* 3 1 -AMD RV670 (HD 3800) .*RV670.* 3 1 -AMD R680 (HD 3870 X2) .*R680.* 3 1 -AMD R700 (HD 4800 X2) .*R700.* 3 1 -AMD RV710 (HD 4300) .*RV710.* 1 1 -AMD RV730 (HD 4600) .*RV730.* 3 1 -AMD RV740 (HD 4700) .*RV740.* 3 1 -AMD RV770 (HD 4800) .*RV770.* 3 1 -AMD RV790 (HD 4800) .*RV790.* 3 1 -ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 -ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 -ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 -ATI FirePro 2000 .*ATI.*FirePro 2.* 1 1 -ATI FirePro 3000 .*ATI.*FirePro V3.* 1 1 -ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 -ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 -ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 -ATI FirePro M .*ATI.*FirePro M.* 3 1 -ATI Technologies .*ATI *Technologies.* 0 1 -// This entry is last to work around the "R300" driver problem. -ATI R300 (9700) .*R300.* 1 1 -ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 -Intel X3100 .*Intel.*X3100.* 0 1 -Intel 830M .*Intel.*830M 0 0 -Intel 845G .*Intel.*845G 0 0 -Intel 855GM .*Intel.*855GM 0 0 -Intel 865G .*Intel.*865G 0 0 -Intel 900 .*Intel.*900.*900 0 0 -Intel 915GM .*Intel.*915GM 0 0 -Intel 915G .*Intel.*915G 0 0 -Intel 945GM .*Intel.*945GM.* 0 1 -Intel 945G .*Intel.*945G.* 0 1 -Intel 950 .*Intel.*950.* 0 1 -Intel 965 .*Intel.*965.* 0 1 -Intel G33 .*Intel.*G33.* 0 0 -Intel G41 .*Intel.*G41.* 0 1 -Intel G45 .*Intel.*G45.* 0 1 -Intel Bear Lake .*Intel.*Bear Lake.* 0 0 -Intel Broadwater .*Intel.*Broadwater.* 0 0 -Intel Brookdale .*Intel.*Brookdale.* 0 0 -Intel Cantiga .*Intel.*Cantiga.* 0 0 -Intel Eaglelake .*Intel.*Eaglelake.* 0 1 -Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 0 1 -Intel HD Graphics .*Intel.*HD Graphics.* 2 1 -Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 -Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 -Intel Montara .*Intel.*Montara.* 0 0 -Intel Pineview .*Intel.*Pineview.* 0 1 -Intel Springdale .*Intel.*Springdale.* 0 0 -Intel HD Graphics 2000 .*Intel.*HD2000.* 1 1 -Intel HD Graphics 3000 .*Intel.*HD3000.* 2 1 -Matrox .*Matrox.* 0 0 -Mesa .*Mesa.* 0 0 -NVIDIA 205 .*NVIDIA .*GeForce 205.* 2 1 -NVIDIA 210 .*NVIDIA .*GeForce 210.* 2 1 -NVIDIA 310M .*NVIDIA .*GeForce 310M.* 1 1 -NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 -NVIDIA 315M .*NVIDIA .*GeForce 315M.* 2 1 -NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 -NVIDIA 320M .*NVIDIA .*GeForce 320M.* 2 1 -NVIDIA G100M .*NVIDIA .*100M.* 0 1 -NVIDIA G100 .*NVIDIA .*100.* 0 1 -NVIDIA G102M .*NVIDIA .*102M.* 0 1 -NVIDIA G103M .*NVIDIA .*103M.* 0 1 -NVIDIA G105M .*NVIDIA .*105M.* 0 1 -NVIDIA G 110M .*NVIDIA .*110M.* 0 1 -NVIDIA G 120M .*NVIDIA .*120M.* 1 1 -NVIDIA G 200 .*NVIDIA .*200(M)?.* 0 1 -NVIDIA G 205M .*NVIDIA .*205(M)?.* 0 1 -NVIDIA G 210 .*NVIDIA .*210(M)?.* 1 1 -NVIDIA 305M .*NVIDIA .*305(M)?.* 1 1 -NVIDIA G 310M .*NVIDIA .*310(M)?.* 2 1 -NVIDIA G 315 .*NVIDIA .*315(M)?.* 2 1 -NVIDIA G 320M .*NVIDIA .*320(M)?.* 2 1 -NVIDIA G 405 .*NVIDIA .*405(M)?.* 1 1 -NVIDIA G 410M .*NVIDIA .*410(M)?.* 1 1 -NVIDIA GT 120M .*NVIDIA .*GT *120(M)?.* 2 1 -NVIDIA GT 120 .*NVIDIA .*GT.*120 2 1 -NVIDIA GT 130M .*NVIDIA .*GT *130(M)?.* 2 1 -NVIDIA GT 140M .*NVIDIA .*GT *140(M)?.* 2 1 -NVIDIA GT 150M .*NVIDIA .*GT(S)? *150(M)?.* 2 1 -NVIDIA GT 160M .*NVIDIA .*GT *160(M)?.* 2 1 -NVIDIA GT 220M .*NVIDIA .*GT *220(M)?.* 2 1 -NVIDIA GT 230M .*NVIDIA .*GT *230(M)?.* 2 1 -NVIDIA GT 240M .*NVIDIA .*GT *240(M)?.* 2 1 -NVIDIA GT 250M .*NVIDIA .*GT *250(M)?.* 2 1 -NVIDIA GT 260M .*NVIDIA .*GT *260(M)?.* 2 1 -NVIDIA GT 320M .*NVIDIA .*GT *320(M)?.* 2 1 -NVIDIA GT 325M .*NVIDIA .*GT *325(M)?.* 0 1 -NVIDIA GT 330M .*NVIDIA .*GT *330(M)?.* 3 1 -NVIDIA GT 335M .*NVIDIA .*GT *335(M)?.* 1 1 -NVIDIA GT 340M .*NVIDIA .*GT *340(M)?.* 2 1 -NVIDIA GT 415M .*NVIDIA .*GT *415(M)?.* 2 1 -NVIDIA GT 420M .*NVIDIA .*GT *420(M)?.* 2 1 -NVIDIA GT 425M .*NVIDIA .*GT *425(M)?.* 3 1 -NVIDIA GT 430M .*NVIDIA .*GT *430(M)?.* 3 1 -NVIDIA GT 435M .*NVIDIA .*GT *435(M)?.* 3 1 -NVIDIA GT 440M .*NVIDIA .*GT *440(M)?.* 3 1 -NVIDIA GT 445M .*NVIDIA .*GT *445(M)?.* 3 1 -NVIDIA GT 450M .*NVIDIA .*GT *450(M)?.* 3 1 -NVIDIA GT 520M .*NVIDIA .*GT *52.(M)?.* 3 1 -NVIDIA GT 530M .*NVIDIA .*GT *530(M)?.* 3 1 -NVIDIA GT 540M .*NVIDIA .*GT *54.(M)?.* 3 1 -NVIDIA GT 550M .*NVIDIA .*GT *550(M)?.* 3 1 -NVIDIA GT 555M .*NVIDIA .*GT *555(M)?.* 3 1 -NVIDIA GTS 160M .*NVIDIA .*GT(S)? *160(M)?.* 2 1 -NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 3 1 -NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 3 1 -NVIDIA GTS 350M .*NVIDIA .*GTS *350M.* 3 1 -NVIDIA GTS 360M .*NVIDIA .*GTS *360M.* 3 1 -NVIDIA GTS 360 .*NVIDIA .*GTS *360.* 3 1 -NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 3 1 -NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 3 1 -NVIDIA GTX 275 .*NVIDIA .*GTX *275.* 3 1 -NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 3 1 -NVIDIA GTX 285 .*NVIDIA .*GTX *285.* 3 1 -NVIDIA GTX 280 .*NVIDIA .*GTX *280.* 3 1 -NVIDIA GTX 290 .*NVIDIA .*GTX *290.* 3 1 -NVIDIA GTX 295 .*NVIDIA .*GTX *295.* 3 1 -NVIDIA GTX 460M .*NVIDIA .*GTX *460M.* 3 1 -NVIDIA GTX 465 .*NVIDIA .*GTX *465.* 3 1 -NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 3 1 -NVIDIA GTX 470M .*NVIDIA .*GTX *470M.* 3 1 -NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 3 1 -NVIDIA GTX 480M .*NVIDIA .*GTX *480M.* 3 1 -NVIDIA GTX 485M .*NVIDIA .*GTX *485M.* 3 1 -NVIDIA GTX 480 .*NVIDIA .*GTX *48.* 3 1 -NVIDIA GTX 530 .*NVIDIA .*GTX *53.* 3 1 -NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 3 1 -NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 3 1 -NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 3 1 -NVIDIA GTX 580M .*NVIDIA .*GTX *580M.* 3 1 -NVIDIA GTX 580 .*NVIDIA .*GTX *58.* 3 1 -NVIDIA GTX 590 .*NVIDIA .*GTX *59.* 3 1 -NVIDIA C51 .*NVIDIA .*C51.* 0 1 -NVIDIA G72 .*NVIDIA .*G72.* 1 1 -NVIDIA G73 .*NVIDIA .*G73.* 1 1 -NVIDIA G84 .*NVIDIA .*G84.* 2 1 -NVIDIA G86 .*NVIDIA .*G86.* 3 1 -NVIDIA G92 .*NVIDIA .*G92.* 3 1 -NVIDIA GeForce .*GeForce 256.* 0 0 -NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 -NVIDIA GeForce 3 .*GeForce ?3 ?.* 0 1 -NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 -NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 -NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 -NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 -NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 -NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 -NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 0 1 -NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 -NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 0 1 -NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 1 1 -NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 -NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 2 1 -NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 0 1 -NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 0 1 -NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 -NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 -NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 1 1 -NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 -NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 -NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 2 1 -NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 -NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 -NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 -NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 2 1 -NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 2 1 -NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 -NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 3 1 -NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1 -NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 -NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 3 1 -NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 -NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 3 1 -NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 -NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 -NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 -NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 -NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 -NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 2 1 -NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 2 1 -NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 -NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 2 1 -NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 2 1 -NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 2 1 -NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 3 1 -NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 2 1 -NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 2 1 -NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 3 1 -NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 -NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 -NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 -NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 -NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 -NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 0 1 -NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 1 1 -NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 -NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 -NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 -NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 -NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 -NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 -NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 -NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 -NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 -NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 -NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 -NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 -NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 -NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 -NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 -NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 1 1 -NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 -NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 1 1 -NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 -NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 0 1 -NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 -NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 -NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 2 1 -NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 2 1 -NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 -NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 2 1 -NVIDIA D9M .*NVIDIA .*D9M.* 1 1 -NVIDIA G94 .*NVIDIA .*G94.* 3 1 -NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 -NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 -NVIDIA ION .*NVIDIA .*ION.* 2 1 -NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 -NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 -NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 -NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 -NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 -NVIDIA N10 .*NVIDIA .*N10.* 1 1 -NVIDIA GeForce PCX .*GeForce PCX.* 0 1 -NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 -NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 -NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 -NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 -NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 -NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 -NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 -NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 -NVIDIA nForce .*NVIDIA .*nForce.* 0 0 -NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 -NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 -NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 -NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 -NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 -NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 -NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 -NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 -NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 -NVIDIA Quadro2 .*Quadro2.* 0 1 -NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 -NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 -NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 -NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 -NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 -NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 -NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 -NVIDIA Quadro 400 .*Quadro.*400.* 2 1 -NVIDIA Quadro 600 .*Quadro.*600.* 2 1 -NVIDIA Quadro4 .*Quadro4.* 0 1 -NVIDIA Quadro DCC .*Quadro DCC.* 0 1 -NVIDIA Quadro CX .*Quadro.*CX.* 3 1 -NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 -NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 -NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 -NVIDIA Quadro FX 2500M .*Quadro.*FX *2500M.* 2 1 -NVIDIA Quadro FX 2700M .*Quadro.*FX *2700M.* 3 1 -NVIDIA Quadro FX 2800M .*Quadro.*FX *2800M.* 3 1 -NVIDIA Quadro FX 3500 .*Quadro.*FX *3500.* 2 1 -NVIDIA Quadro FX 3600 .*Quadro.*FX *3600.* 3 1 -NVIDIA Quadro FX 3700 .*Quadro.*FX *3700.* 3 1 -NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 -NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 -NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 -NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 -NVIDIA Quadro FX .*Quadro FX.* 1 1 -NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 -NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1 -NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 -NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS *2100M.* 2 1 -NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 -NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 -NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 -NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 -NVIDIA RIVA TNT .*RIVA TNT.* 0 0 -S3 .*S3 Graphics.* 0 0 -SiS SiS.* 0 0 -Trident Trident.* 0 0 -Tungsten Graphics Tungsten.* 0 0 -XGI XGI.* 0 0 -VIA VIA.* 0 0 -Apple Generic Apple.*Generic.* 0 0 -Apple Software Renderer Apple.*Software Renderer.* 0 0 -Humper Humper.* 0 1 +3Dfx .*3Dfx.* 0 0 0 0 +3Dlabs .*3Dlabs.* 0 0 0 0 +ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0 +ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0 +ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0 +ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0 +ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 0 0 +ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3 +ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0 +ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1 +ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0 +ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0 +ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0 +ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0 +ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 0 0 +ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 0 0 +ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 1 3.3 +ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 1 1 1 3.3 +ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1 1 3.3 +ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 1 1 1 3.3 +ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 2 1 1 3.3 +ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 0 0 +ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 0 0 +ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 0 0 +ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 0 0 +ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 0 0 +ATI ASUS EAH29xx .*ATI.*ASUS.*EAH29.* 3 1 0 0 +ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1 0 0 +ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 2 1 0 0 +ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 2 1 1 3.3 +ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 2 1 1 3.3 +ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 2 1 0 0 +ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1 1 3.3 +ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1 1 4.1 +ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 5 1 1 4.1 +ATI ASUS EAH62xx .*ATI.*ASUS.*EAH62.* 2 1 0 0 +ATI ASUS EAH63xx .*ATI.*ASUS.*EAH63.* 2 1 0 0 +ATI ASUS EAH64xx .*ATI.*ASUS.*EAH64.* 2 1 0 0 +ATI ASUS EAH65xx .*ATI.*ASUS.*EAH65.* 2 1 0 4.1 +ATI ASUS EAH66xx .*ATI.*ASUS.*EAH66.* 3 1 0 4.1 +ATI ASUS EAH67xx .*ATI.*ASUS.*EAH67.* 3 1 0 0 +ATI ASUS EAH68xx .*ATI.*ASUS.*EAH68.* 5 1 0 4 +ATI ASUS EAH69xx .*ATI.*ASUS.*EAH69.* 5 1 0 4.1 +ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 2 1 1 2.1 +ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 0 0 +ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 2 1 1 2.1 +ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1 +ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1 +ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 1 1 1 2.1 +ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 1 1 1 2.1 +ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 1 2.1 +ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 0 1 1 2.1 +ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1 1 2.1 +ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1 +ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1 +ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3 +ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2 +ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 0 0 +ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0 +ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0 +ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2 +ATI FireMV .*ATI.*FireMV.* 0 1 1 1.3 +ATI Generic .*ATI.*Generic.* 0 0 0 0 +ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 0 0 +ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 0 0 +ATI M52 .*ATI.*M52.* 1 1 0 0 +ATI M54 .*ATI.*M54.* 1 1 0 0 +ATI M56 .*ATI.*M56.* 1 1 0 0 +ATI M71 .*ATI.*M71.* 1 1 0 0 +ATI M72 .*ATI.*M72.* 1 1 0 0 +ATI M76 .*ATI.*M76.* 3 1 0 0 +ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 2 1 1 4.2 +ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 2 1 1 4.2 +ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 1 4.2 +ATI Radeon HD 7100 .*ATI.*AMD Radeon.* HD 71.* 2 1 0 0 +ATI Radeon HD 7200 .*ATI.*AMD Radeon.* HD 72.* 2 1 0 0 +ATI Radeon HD 7300 .*ATI.*AMD Radeon.* HD 73.* 2 1 0 4.2 +ATI Radeon HD 7400 .*ATI.*AMD Radeon.* HD 74.* 2 1 0 4.2 +ATI Radeon HD 7500 .*ATI.*AMD Radeon.* HD 75.* 3 1 1 4.2 +ATI Radeon HD 7600 .*ATI.*AMD Radeon.* HD 76.* 3 1 0 4.2 +ATI Radeon HD 7700 .*ATI.*AMD Radeon.* HD 77.* 4 1 1 4.2 +ATI Radeon HD 7800 .*ATI.*AMD Radeon.* HD 78.* 5 1 1 4.2 +ATI Radeon HD 7900 .*ATI.*AMD Radeon.* HD 79.* 5 1 1 4.2 +ATI ASUS HD7100 .*ATI.*ASUS.* HD71.* 2 1 0 0 +ATI ASUS HD7200 .*ATI.*ASUS.* HD72.* 2 1 0 0 +ATI ASUS HD7300 .*ATI.*ASUS.* HD73.* 2 1 0 0 +ATI ASUS HD7400 .*ATI.*ASUS.* HD74.* 2 1 0 0 +ATI ASUS HD7500 .*ATI.*ASUS.* HD75.* 3 1 1 4.2 +ATI ASUS HD7600 .*ATI.*ASUS.* HD76.* 3 1 0 0 +ATI ASUS HD7700 .*ATI.*ASUS.* HD77.* 4 1 1 4.2 +ATI ASUS HD7800 .*ATI.*ASUS.* HD78.* 5 1 1 4.2 +ATI ASUS HD7900 .*ATI.*ASUS.* HD79.* 5 1 1 4.2 +ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 1 3.3 +ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3 +ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0 +ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 0 0 +ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 0 1 1 2.1 +ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 1 1 1 2.1 +ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1 1 3.3 +ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 1 1 1 3.3 +ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1 1 4 +ATI Mobility Radeon HD 550v .*ATI.*Mobility.*HD *550v.* 3 1 1 4 +ATI Mobility Radeon HD 560v .*ATI.*Mobility.*HD *560v.* 3 1 1 3.2 +ATI Mobility Radeon HD 565v .*ATI.*Mobility.*HD *565v.* 3 1 1 3.3 +ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD *23.* 0 1 1 2.1 +ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD *24.* 1 1 1 3.3 +ATI Mobility Radeon HD 2600 .*ATI.*Mobility.*HD *26.* 1 1 1 3.3 +ATI Mobility Radeon HD 2700 .*ATI.*Mobility.*HD *27.* 3 1 0 0 +ATI Mobility Radeon HD 3100 .*ATI.*Mobility.*HD *31.* 0 1 0 0 +ATI Mobility Radeon HD 3200 .*ATI.*Mobility.*HD *32.* 0 1 0 0 +ATI Mobility Radeon HD 3400 .*ATI.*Mobility.*HD *34.* 1 1 1 3.3 +ATI Mobility Radeon HD 3600 .*ATI.*Mobility.*HD *36.* 1 1 1 4 +ATI Mobility Radeon HD 3800 .*ATI.*Mobility.*HD *38.* 3 1 1 3.3 +ATI Mobility Radeon HD 4200 .*ATI.*Mobility.*HD *42.* 1 1 1 4 +ATI Mobility Radeon HD 4300 .*ATI.*Mobility.*HD *43.* 1 1 1 4 +ATI Mobility Radeon HD 4500 .*ATI.*Mobility.*HD *45.* 1 1 1 4 +ATI Mobility Radeon HD 4600 .*ATI.*Mobility.*HD *46.* 2 1 1 3.3 +ATI Mobility Radeon HD 4800 .*ATI.*Mobility.*HD *48.* 3 1 1 3.3 +ATI Mobility Radeon HD 5100 .*ATI.*Mobility.*HD *51.* 3 1 1 3.2 +ATI Mobility Radeon HD 5300 .*ATI.*Mobility.*HD *53.* 3 1 0 0 +ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD *54.* 2 1 1 4.2 +ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD *55.* 3 1 0 0 +ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD *56.* 3 1 1 4.2 +ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD *57.* 3 1 1 4.1 +ATI Mobility Radeon HD 6200 .*ATI.*Mobility.*HD *62.* 3 1 0 0 +ATI Mobility Radeon HD 6300 .*ATI.*Mobility.*HD *63.* 3 1 1 4.2 +ATI Mobility Radeon HD 6400M .*ATI.*Mobility.*HD *64.* 3 1 0 0 +ATI Mobility Radeon HD 6500M .*ATI.*Mobility.*HD *65.* 5 1 1 4.2 +ATI Mobility Radeon HD 6600M .*ATI.*Mobility.*HD *66.* 5 1 0 0 +ATI Mobility Radeon HD 6700M .*ATI.*Mobility.*HD *67.* 5 1 0 0 +ATI Mobility Radeon HD 6800M .*ATI.*Mobility.*HD *68.* 5 1 0 0 +ATI Mobility Radeon HD 6900M .*ATI.*Mobility.*HD *69.* 5 1 0 0 +ATI Radeon HD 2300 .*ATI.*Radeon HD *23.. 0 1 1 3.3 +ATI Radeon HD 2400 .*ATI.*Radeon HD *24.. 1 1 1 4 +ATI Radeon HD 2600 .*ATI.*Radeon HD *26.. 2 1 1 3.3 +ATI Radeon HD 2900 .*ATI.*Radeon HD *29.. 3 1 1 3.3 +ATI Radeon HD 3000 .*ATI.*Radeon HD *30.. 0 1 0 0 +ATI Radeon HD 3100 .*ATI.*Radeon HD *31.. 1 1 0 0 +ATI Radeon HD 3200 .*ATI.*Radeon HD *32.. 1 1 1 4 +ATI Radeon HD 3300 .*ATI.*Radeon HD *33.. 1 1 1 3.3 +ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 1 1 1 4 +ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 0 0 +ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 1 3.3 +ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 0 0 +ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3 +ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 1 4 +ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 0 0 +ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 1 4 +ATI Radeon HD 4300 .*ATI.*Radeon HD *43.. 2 1 1 4 +ATI Radeon HD 4400 .*ATI.*Radeon HD *44.. 2 1 0 0 +ATI Radeon HD 4500 .*ATI.*Radeon HD *45.. 2 1 1 3.3 +ATI Radeon HD 4600 .*ATI.*Radeon HD *46.. 3 1 1 4 +ATI Radeon HD 4700 .*ATI.*Radeon HD *47.. 3 1 1 3.3 +ATI Radeon HD 4800 .*ATI.*Radeon HD *48.. 3 1 1 4 +ATI ASUS EAH5400 .*ATI.*ASUS EAH54.. 3 1 1 4.2 +ATI Radeon HD 5400 .*ATI.*Radeon HD *54.. 3 1 1 4.2 +ATI Radeon HD 5500 .*ATI.*Radeon HD *55.. 3 1 1 4.2 +ATI ASUS EAH5500 .*ATI.*ASUS EAH55.. 3 1 1 4.2 +ATI Radeon HD 5600 .*ATI.*Radeon HD *56.. 3 1 1 4.2 +ATI Radeon HD 5700 .*ATI.*Radeon HD *57.. 3 1 1 4.2 +ATI Radeon HD 5800 .*ATI.*Radeon HD *58.. 4 1 1 4.2 +ATI Radeon HD 5900 .*ATI.*Radeon HD *59.. 4 1 1 4.2 +ATI Radeon HD 6200 .*ATI.*Radeon HD *62.. 0 1 1 4.2 +ATI Radeon HD 6300 .*ATI.*Radeon HD *63.. 1 1 1 4.2 +ATI Radeon HD 6400 .*ATI.*Radeon HD *64.. 3 1 1 4.2 +ATI Radeon HD 6500 .*ATI.*Radeon HD *65.. 3 1 1 4.2 +ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 1 4.2 +ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 1 4.2 +ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 4 1 1 4.2 +ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 5 1 1 4.2 +ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0 +ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1 +ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4 +ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3 +ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0 +ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2 +ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0 +ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3 +ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0 +ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3 +ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1 +ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1 +ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0 +ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1 +ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0 +ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0 +ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0 +ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 0 0 +ATI RS880M .*ATI.*RS880M 1 1 0 0 +ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0 +ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0 +ATI Radeon X300 .*ATI.*Radeon *X3.* 1 1 1 2.1 +ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0 +ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1 +ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1 1 2.1 +ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1 +ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1 +ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0 +ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1 +ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0 +ATI R300 (9700) .*R300.* 0 1 1 2.1 +ATI R350 (9800) .*R350.* 1 1 0 0 +ATI R580 (X1900) .*R580.* 3 1 0 0 +ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0 +ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0 +ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0 +ATI RV350 (9600) .*RV350.* 0 1 0 0 +ATI RV370 (X300) .*RV370.* 0 1 0 0 +ATI RV410 (X700) .*RV410.* 1 1 0 0 +ATI RV515 .*RV515.* 1 1 0 0 +ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0 +ATI RV380 .*RV380.* 0 1 0 0 +ATI RV530 .*RV530.* 1 1 0 0 +ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0 +ATI RX700 .*RX700.* 1 1 0 0 +AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0 +AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1 +AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0 +AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0 +AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 0 0 +AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0 +AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0 +AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0 +AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0 +AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 0 +AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 0 +AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1 +AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2 +AMD RV610 (HD 2400) .*RV610.* 1 1 0 0 +AMD RV620 (HD 3400) .*RV620.* 1 1 0 0 +AMD RV630 (HD 2600) .*RV630.* 2 1 0 0 +AMD RV635 (HD 3600) .*RV635.* 3 1 0 0 +AMD RV670 (HD 3800) .*RV670.* 3 1 0 0 +AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0 +AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0 +AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4 +AMD RV730 (HD 4600) .*RV730.* 3 1 0 0 +AMD RV740 (HD 4700) .*RV740.* 3 1 0 0 +AMD RV770 (HD 4800) .*RV770.* 3 1 0 0 +AMD RV790 (HD 4800) .*RV790.* 3 1 0 0 +ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3 +ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0 +ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0 +ATI FirePro 2000 .*ATI.*FirePro 2.* 2 1 1 4.1 +ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0 +ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 0 +ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0 +ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0 +ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2 +ATI R300 (9700) .*R300.* 0 1 1 2.1 +ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 0 4.2 +Intel X3100 .*Intel.*X3100.* 1 1 1 2.1 +Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3 +Intel 830M .*Intel.*830M 0 0 0 0 +Intel 845G .*Intel.*845G 0 0 1 1.4 +Intel 855GM .*Intel.*855GM 0 0 1 1.4 +Intel 865G .*Intel.*865G 0 0 1 1.4 +Intel 900 .*Intel.*900.*900 0 0 0 0 +Intel 915GM .*Intel.*915GM 0 0 1 1.4 +Intel 915G .*Intel.*915G 0 0 1 1.4 +Intel 945GM .*Intel.*945GM.* 0 1 1 1.4 +Intel 945G .*Intel.*945G.* 0 1 1 1.4 +Intel 950 .*Intel.*950.* 0 1 1 1.4 +Intel 965 .*Intel.*965.* 0 1 1 2.1 +Intel G33 .*Intel.*G33.* 1 0 1 1.4 +Intel G41 .*Intel.*G41.* 1 1 1 2.1 +Intel G45 .*Intel.*G45.* 1 1 1 2.1 +Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4 +Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4 +Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3 +Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2 +Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2 +Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1 +Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4 +Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1 +Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4 +Intel HD2000 .*Intel.*HD2000.* 2 1 0 0 +Intel HD3000 .*Intel.*HD3000.* 3 1 0 0 +Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4 +Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1 +Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1 +Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0 +Intel Montara .*Intel.*Montara.* 0 0 1 1.3 +Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4 +Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3 +Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0 +Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1 +Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1 +Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0 +Matrox .*Matrox.* 0 0 0 0 +Mesa .*Mesa.* 1 0 1 2.1 +Gallium .*Gallium.* 1 1 1 2.1 +NVIDIA G100M .*NVIDIA .*100M.* 4 1 1 3.3 +NVIDIA G102M .*NVIDIA .*102M.* 1 1 1 3.3 +NVIDIA G103M .*NVIDIA .*103M.* 2 1 1 3.3 +NVIDIA G105M .*NVIDIA .*105M.* 2 1 1 3.3 +NVIDIA G 110M .*NVIDIA .*110M.* 1 1 1 3.3 +NVIDIA G 120M .*NVIDIA .*120M.* 1 1 1 3.3 +NVIDIA G 205M .*NVIDIA .*205M.* 1 1 0 0 +NVIDIA G 410M .*NVIDIA .*410M.* 3 1 1 4.2 +NVIDIA GT 120M .*NVIDIA .*GT *12*M.* 3 1 1 3.3 +NVIDIA GT 130M .*NVIDIA .*GT *13*M.* 3 1 1 3.3 +NVIDIA GT 140M .*NVIDIA .*GT *14*M.* 3 1 1 3.3 +NVIDIA GT 150M .*NVIDIA .*GTS *15*M.* 2 1 0 0 +NVIDIA GTS 160M .*NVIDIA .*GTS *16*M.* 2 1 0 0 +NVIDIA G210M .*NVIDIA .*G21*M.* 3 1 0 0 +NVIDIA GT 220M .*NVIDIA .*GT *22*M.* 3 1 1 3.3 +NVIDIA GT 230M .*NVIDIA .*GT *23*M.* 3 1 1 3.3 +NVIDIA GT 240M .*NVIDIA .*GT *24*M.* 3 1 1 3.3 +NVIDIA GTS 250M .*NVIDIA .*GTS *25*M.* 3 1 0 0 +NVIDIA GTS 260M .*NVIDIA .*GTS *26*M.* 3 1 0 0 +NVIDIA GTX 260M .*NVIDIA .*GTX *26*M.* 3 1 0 0 +NVIDIA GTX 270M .*NVIDIA .*GTX *27*M.* 3 1 0 0 +NVIDIA GTX 280M .*NVIDIA .*GTX *28*M.* 3 1 0 0 +NVIDIA 300M .*NVIDIA .*30*M.* 3 1 1 4.2 +NVIDIA G 310M .*NVIDIA .*31*M.* 2 1 0 0 +NVIDIA GT 320M .*NVIDIA .*GT *32*M.* 3 1 0 0 +NVIDIA GT 325M .*NVIDIA .*GT *32*M.* 3 1 1 3.3 +NVIDIA GT 330M .*NVIDIA .*GT *33*M.* 3 1 1 3.3 +NVIDIA GT 340M .*NVIDIA .*GT *34*M.* 4 1 1 3.3 +NVIDIA GTS 350M .*NVIDIA .*GTS *35*M.* 4 1 1 3.3 +NVIDIA GTS 360M .*NVIDIA .*GTS *360M.* 5 1 1 3.3 +NVIDIA 405M .*NVIDIA .* 40*M.* 2 1 0 4.2 +NVIDIA 410M .*NVIDIA .* 41*M.* 3 1 0 0 +NVIDIA GT 415M .*NVIDIA .*GT *41*M.* 3 1 1 4.2 +NVIDIA GT 420M .*NVIDIA .*GT *42*M.* 3 1 1 4.2 +NVIDIA GT 430M .*NVIDIA .*GT *43*M.* 3 1 1 4.2 +NVIDIA GT 440M .*NVIDIA .*GT *44*M.* 3 1 1 4.2 +NVIDIA GT 450M .*NVIDIA .*GT *45*M.* 3 1 0 0 +NVIDIA GTX 460M .*NVIDIA .*GTX *46*M.* 4 1 1 4.2 +NVIDIA GTX 470M .*NVIDIA .*GTX *47*M.* 3 1 0 0 +NVIDIA GTX 480M .*NVIDIA .*GTX *48*M.* 3 1 1 4.2 +NVIDIA GT 520M .*NVIDIA .*GT *52*M.* 3 1 1 4.2 +NVIDIA GT 530M .*NVIDIA .*GT *53*M.* 3 1 1 4.2 +NVIDIA GT 540M .*NVIDIA .*GT *54*M.* 3 1 1 4.2 +NVIDIA GT 550M .*NVIDIA .*GT *55*M.* 3 1 1 4.2 +NVIDIA GTX 560M .*NVIDIA .*GTX *56*M.* 3 1 0 0 +NVIDIA GTX 570M .*NVIDIA .*GTX *57*M.* 5 1 0 0 +NVIDIA GTX 580M .*NVIDIA .*GTX *58*M.* 5 1 1 4.2 +NVIDIA 610M .*NVIDIA.* 61*M.* 3 1 1 4.2 +NVIDIA GT 620M .*NVIDIA .*GT *62*M.* 3 1 0 0 +NVIDIA GT 630M .*NVIDIA .*GT *63*M.* 3 1 0 0 +NVIDIA GT 640M .*NVIDIA .*GT *64*M.* 3 1 0 0 +NVIDIA GT 650M .*NVIDIA .*GT *65*M.* 3 1 0 0 +NVIDIA GTX 660M .*NVIDIA .*GTX *66*M.* 5 1 0 0 +NVIDIA GTX 670M .*NVIDIA .*GTX *67*M.* 5 1 1 4.2 +NVIDIA GTX 680M .*NVIDIA .*GTX *68*M.* 5 1 0 0 +NVIDIA GTX 690M .*NVIDIA .*GTX *69*M.* 5 1 0 0 +NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2 +NVIDIA GT 120 .*NVIDIA .*GT *12.* 2 1 0 3 +NVIDIA GT 130 .*NVIDIA .*GT *13.* 2 1 0 3.3 +NVIDIA GTS 150 .*NVIDIA .*GTS *15.* 2 1 0 0 +NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3 +NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3 +NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3 +NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3 +NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3 +NVIDIA GT 230 .*NVIDIA .*GT *23.* 2 1 1 3.3 +NVIDIA GT 240 .*NVIDIA .*GT *24.* 4 1 1 3.3 +NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 4 1 1 3.3 +NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 4 1 1 3.3 +NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3 +NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 4 1 0 3.3 +NVIDIA GTX 280 .*NVIDIA .*GTX *28.* 4 1 1 3.3 +NVIDIA GTX 290 .*NVIDIA .*GTX *29.* 5 1 0 3.3 +NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3 +NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3 +NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 3.3 +NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 3.3 +NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0 +NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3 +NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.2 +NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.2 +NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 0 4.2 +NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 4 1 1 4.2 +NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 5 1 1 4.3 +NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 5 1 1 4.2 +NVIDIA GTX 480 .*NVIDIA .*GTX *48.* 5 1 1 4.2 +NVIDIA 510 .*NVIDIA .* 510.* 3 1 0 0 +NVIDIA GT 520 .*NVIDIA .*GT *52.* 3 1 1 4.2 +NVIDIA GT 530 .*NVIDIA .*GT *53.* 3 1 1 4.2 +NVIDIA GT 540 .*NVIDIA .*GT *54.* 3 1 1 4.2 +NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 5 1 1 4.3 +NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 5 1 1 4.2 +NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 5 1 1 4.2 +NVIDIA GTX 580 .*NVIDIA .*GTX *58.* 5 1 1 4.3 +NVIDIA GTX 590 .*NVIDIA .*GTX *59.* 5 1 1 4.2 +NVIDIA GT 610 .*NVIDIA .*GT *61.* 3 1 1 4.2 +NVIDIA GT 620 .*NVIDIA .*GT *62.* 3 1 0 4.2 +NVIDIA GT 630 .*NVIDIA .*GT *63.* 3 1 0 4.2 +NVIDIA GT 640 .*NVIDIA .*GT *64.* 3 1 0 4.3 +NVIDIA GT 650 .*NVIDIA .*GT *65.* 3 1 1 4.2 +NVIDIA GTX 650 .*NVIDIA .*GTX *65.* 3 1 1 4.2 +NVIDIA GTX 660 .*NVIDIA .*GTX *66.* 5 1 0 4.3 +NVIDIA GTX 670 .*NVIDIA .*GTX *67.* 5 1 1 4.2 +NVIDIA GTX 680 .*NVIDIA .*GTX *68.* 5 1 1 4.2 +NVIDIA GTX 690 .*NVIDIA .*GTX *69.* 5 1 1 4.2 +NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2 +NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0 +NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0 +NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0 +NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0 +NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0 +NVIDIA GeForce .*GeForce 256.* 0 0 0 0 +NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5 +NVIDIA GeForce 3 .*GeForce ?3 ?.* 2 1 1 2.1 +NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0 +NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5 +NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0 +NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0 +NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0 +NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0 +NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2 +NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1 +NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1 +NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1 +NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1 +NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1 +NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1 +NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1 +NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0 +NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1 +NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1 +NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1 +NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1 +NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1 +NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 0 0 +NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 0 3.3 +NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 2.1 +NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3 +NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 1 1 1 3.3 +NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3 +NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3 +NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1 1 3.3 +NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3 +NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 2 1 1 3.3 +NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0 +NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 2 1 1 3.3 +NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3 +NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 0 0 +NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3 +NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 0 3.1 +NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3 +NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 1 1 1 3.3 +NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3 +NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 1 3.3 +NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3 +NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 1 1 1 3.3 +NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3 +NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 2 1 1 3.3 +NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3 +NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 0 1 1 3.3 +NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 2 1 1 3.3 +NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3 +NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0 +NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1 +NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0 +NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1 +NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1 +NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1 +NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0 +NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1 +NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0 +NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 0 0 +NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0 +NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0 +NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1 +NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5 +NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0 +NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0 +NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0 +NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1 +NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 0 0 +NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2 +NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0 +NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1 +NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0 +NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1 +NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 0 0 +NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0 +NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1 +NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1 +NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1 +NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1 +NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0 +NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1 +NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0 +NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0 +NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0 +NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0 +NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3 +NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0 +NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0 +NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0 +NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0 +NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0 +NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 0 +NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 0 +NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 3 +NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0 +NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0 +NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0 +NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0 +NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0 +NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0 +NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0 +NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3 +NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0 +NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 0 0 +NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0 +NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0 +NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0 +NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0 +NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0 +NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0 +NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0 +NVIDIA Quadro2 .*Quadro2.* 0 1 0 0 +NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 0 4.2 +NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 0 4.2 +NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 0 0 +NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 0 0 +NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 0 4.2 +NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 0 0 +NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 0 0 +NVIDIA Quadro 400 .*Quadro.*400.* 2 1 0 3.3 +NVIDIA Quadro 600 .*Quadro.*600.* 2 1 0 3.3 +NVIDIA Quadro4 .*Quadro4.* 0 1 0 0 +NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0 +NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0 +NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 0 0 +NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 0 2.1 +NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 0 0 +NVIDIA Quadro FX 2500M .*Quadro.*FX *2500M.* 2 1 0 0 +NVIDIA Quadro FX 2700M .*Quadro.*FX *2700M.* 3 1 0 0 +NVIDIA Quadro FX 2800M .*Quadro.*FX *2800M.* 3 1 0 3.3 +NVIDIA Quadro FX 3500 .*Quadro.*FX *3500.* 2 1 0 2.1 +NVIDIA Quadro FX 3600 .*Quadro.*FX *3600.* 3 1 0 0 +NVIDIA Quadro FX 3700 .*Quadro.*FX *3700.* 3 1 0 3.3 +NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 0 3.2 +NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 0 0 +NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 0 3.3 +NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 0 0 +NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3 +NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 1 3.3 +NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1 0 0 +NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 0 0 +NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS *2100M.* 2 1 0 0 +NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 0 0 +NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 0 4.1 +NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 0 0 +NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 3.2 +NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1 +NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 0 +NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 0 +S3 .*S3 Graphics.* 0 0 1 1.4 +SiS SiS.* 0 0 1 1.5 +Trident Trident.* 0 0 0 0 +Tungsten Graphics Tungsten.* 0 0 0 0 +XGI XGI.* 0 0 0 0 +VIA VIA.* 0 0 0 0 +Apple Generic Apple.*Generic.* 0 0 0 0 +Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0 +Humper Humper.* 0 1 1 2.1 +PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 447836910d..11fa50b51a 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4045,6 +4045,12 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global) { LLViewerRegion* regionp = getRegion(); + + if (!regionp) + { + return; + } + U64 handle = to_region_handle(pos_global); LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); if(regionp && info) diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp new file mode 100644 index 0000000000..0d7d41304d --- /dev/null +++ b/indra/newview/llappcorehttp.cpp @@ -0,0 +1,192 @@ +/** + * @file llappcorehttp.cpp + * @brief + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llappcorehttp.h" + +#include "llviewercontrol.h" + + +const F64 LLAppCoreHttp::MAX_THREAD_WAIT_TIME(10.0); + +LLAppCoreHttp::LLAppCoreHttp() + : mRequest(NULL), + mStopHandle(LLCORE_HTTP_HANDLE_INVALID), + mStopRequested(0.0), + mStopped(false), + mPolicyDefault(-1) +{} + + +LLAppCoreHttp::~LLAppCoreHttp() +{ + delete mRequest; + mRequest = NULL; +} + + +void LLAppCoreHttp::init() +{ + LLCore::HttpStatus status = LLCore::HttpRequest::createService(); + if (! status) + { + LL_ERRS("Init") << "Failed to initialize HTTP services. Reason: " + << status.toString() + << LL_ENDL; + } + + // Point to our certs or SSH/https: will fail on connect + status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_CA_FILE, + gDirUtilp->getCAFile()); + if (! status) + { + LL_ERRS("Init") << "Failed to set CA File for HTTP services. Reason: " + << status.toString() + << LL_ENDL; + } + + // Establish HTTP Proxy. "LLProxy" is a special string which directs + // the code to use LLProxy::applyProxySettings() to establish any + // HTTP or SOCKS proxy for http operations. + status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_LLPROXY, 1); + if (! status) + { + LL_ERRS("Init") << "Failed to set HTTP proxy for HTTP services. Reason: " + << status.toString() + << LL_ENDL; + } + + // Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy): + // 0 - None + // 1 - Basic start, stop simple transitions + // 2 - libcurl CURLOPT_VERBOSE mode with brief lines + // 3 - with partial data content + static const std::string http_trace("QAModeHttpTrace"); + if (gSavedSettings.controlExists(http_trace)) + { + long trace_level(0L); + trace_level = long(gSavedSettings.getU32(http_trace)); + status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_TRACE, trace_level); + } + + // Setup default policy and constrain if directed to + mPolicyDefault = LLCore::HttpRequest::DEFAULT_POLICY_ID; + static const std::string texture_concur("TextureFetchConcurrency"); + if (gSavedSettings.controlExists(texture_concur)) + { + U32 concur(llmin(gSavedSettings.getU32(texture_concur), U32(12))); + + if (concur > 0) + { + LLCore::HttpStatus status; + status = LLCore::HttpRequest::setPolicyClassOption(mPolicyDefault, + LLCore::HttpRequest::CP_CONNECTION_LIMIT, + concur); + if (! status) + { + LL_WARNS("Init") << "Unable to set texture fetch concurrency. Reason: " + << status.toString() + << LL_ENDL; + } + else + { + LL_INFOS("Init") << "Application settings overriding default texture fetch concurrency. New value: " + << concur + << LL_ENDL; + } + } + } + + // Kick the thread + status = LLCore::HttpRequest::startThread(); + if (! status) + { + LL_ERRS("Init") << "Failed to start HTTP servicing thread. Reason: " + << status.toString() + << LL_ENDL; + } + + mRequest = new LLCore::HttpRequest; +} + + +void LLAppCoreHttp::requestStop() +{ + llassert_always(mRequest); + + mStopHandle = mRequest->requestStopThread(this); + if (LLCORE_HTTP_HANDLE_INVALID != mStopHandle) + { + mStopRequested = LLTimer::getTotalSeconds(); + } +} + + +void LLAppCoreHttp::cleanup() +{ + if (LLCORE_HTTP_HANDLE_INVALID == mStopHandle) + { + // Should have been started already... + requestStop(); + } + + if (LLCORE_HTTP_HANDLE_INVALID == mStopHandle) + { + LL_WARNS("Cleanup") << "Attempting to cleanup HTTP services without thread shutdown" + << LL_ENDL; + } + else + { + while (! mStopped && LLTimer::getTotalSeconds() < (mStopRequested + MAX_THREAD_WAIT_TIME)) + { + mRequest->update(200000); + ms_sleep(50); + } + if (! mStopped) + { + LL_WARNS("Cleanup") << "Attempting to cleanup HTTP services with thread shutdown incomplete" + << LL_ENDL; + } + } + + delete mRequest; + mRequest = NULL; + + LLCore::HttpStatus status = LLCore::HttpRequest::destroyService(); + if (! status) + { + LL_WARNS("Cleanup") << "Failed to shutdown HTTP services, continuing. Reason: " + << status.toString() + << LL_ENDL; + } +} + + +void LLAppCoreHttp::onCompleted(LLCore::HttpHandle, LLCore::HttpResponse *) +{ + mStopped = true; +} diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h new file mode 100644 index 0000000000..241d73ad52 --- /dev/null +++ b/indra/newview/llappcorehttp.h @@ -0,0 +1,86 @@ +/** + * @file llappcorehttp.h + * @brief Singleton initialization/shutdown class for llcorehttp library + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef _LL_APP_COREHTTP_H_ +#define _LL_APP_COREHTTP_H_ + + +#include "httprequest.h" +#include "httphandler.h" +#include "httpresponse.h" + + +// This class manages the lifecyle of the core http library. +// Slightly different style than traditional code but reflects +// the use of handler classes and light-weight interface +// object instances of the new libraries. To be used +// as a singleton and static construction is fine. +class LLAppCoreHttp : public LLCore::HttpHandler +{ +public: + LLAppCoreHttp(); + ~LLAppCoreHttp(); + + // Initialize the LLCore::HTTP library creating service classes + // and starting the servicing thread. Caller is expected to do + // other initializations (SSL mutex, thread hash function) appropriate + // for the application. + void init(); + + // Request that the servicing thread stop servicing requests, + // release resource references and stop. Request is asynchronous + // and @see cleanup() will perform a limited wait loop for this + // request to stop the thread. + void requestStop(); + + // Terminate LLCore::HTTP library services. Caller is expected + // to have made a best-effort to shutdown the servicing thread + // by issuing a requestThreadStop() and waiting for completion + // notification that the stop has completed. + void cleanup(); + + // Notification when the stop request is complete. + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + + // Retrieve the policy class for default operations. + int getPolicyDefault() const + { + return mPolicyDefault; + } + +private: + static const F64 MAX_THREAD_WAIT_TIME; + +private: + LLCore::HttpRequest * mRequest; + LLCore::HttpHandle mStopHandle; + F64 mStopRequested; + bool mStopped; + int mPolicyDefault; +}; + + +#endif // _LL_APP_COREHTTP_H_ diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6d67e098a6..06a9892c7e 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -52,7 +52,8 @@ std::string self_av_string() { - return gAgentAvatarp->avString(); + // On logout gAgentAvatarp can already be invalid + return isAgentAvatarValid() ? gAgentAvatarp->avString() : ""; } // RAII thingy to guarantee that a variable gets reset when the Setter diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4de80037ed..438194c715 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -116,6 +116,7 @@ #include "llnotificationsutil.h" #include "llleap.h" +#include "stringize.h" // Third party library includes #include <boost/bind.hpp> @@ -123,7 +124,6 @@ #include <boost/algorithm/string.hpp> - #if LL_WINDOWS # include <share.h> // For _SH_DENYWR in initMarkerFile #else @@ -219,6 +219,7 @@ #include "llmachineid.h" #include "llmainlooprepeater.h" + // *FIX: These extern globals should be cleaned up. // The globals either represent state/config/resource-storage of either // this app, or another 'component' of the viewer. App globals should be @@ -379,6 +380,9 @@ void init_default_trans_args() default_trans_args.insert("CAPITALIZED_APP_NAME"); default_trans_args.insert("SECOND_LIFE_GRID"); default_trans_args.insert("SUPPORT_SITE"); + // This URL shows up in a surprising number of places in various skin + // files. We really only want to have to maintain a single copy of it. + default_trans_args.insert("create_account_url"); } //---------------------------------------------------------------------------- @@ -688,7 +692,7 @@ bool LLAppViewer::init() gDirUtilp->initAppDirs("SecondLife"); // set skin search path to default, will be overridden later // this allows simple skinned file lookups to work - gDirUtilp->setSkinFolder("default"); + gDirUtilp->setSkinFolder("default", "en"); initLogging(); @@ -731,6 +735,10 @@ bool LLAppViewer::init() LLViewerStatsRecorder::initClass(); #endif + // Initialize the non-LLCurl libcurl library. Should be called + // before consumers (LLTextureFetch). + mAppCoreHttp.init(); + // *NOTE:Mani - LLCurl::initClass is not thread safe. // Called before threads are created. LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"), @@ -772,12 +780,15 @@ bool LLAppViewer::init() &LLUI::sGLScaleFactor); LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ; - // Setup paths and LLTrans after LLUI::initClass has been called. - LLUI::setupPaths(); - LLTransUtil::parseStrings("strings.xml", default_trans_args); - LLTransUtil::parseLanguageStrings("language_settings.xml"); + // NOW LLUI::getLanguage() should work. gDirUtilp must know the language + // for this session ASAP so all the file-loading commands that follow, + // that use findSkinnedFilenames(), will include the localized files. + gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage()); - // Setup notifications after LLUI::setupPaths() has been called. + // Setup LLTrans after LLUI::initClass has been called. + initStrings(); + + // Setup notifications after LLUI::initClass() has been called. LLNotifications::instance(); LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; @@ -1881,6 +1892,7 @@ bool LLAppViewer::cleanup() // Delete workers first // shotdown all worker threads before deleting them in case of co-dependencies + mAppCoreHttp.requestStop(); sTextureFetch->shutdown(); sTextureCache->shutdown(); sImageDecodeThread->shutdown(); @@ -1896,6 +1908,9 @@ bool LLAppViewer::cleanup() LLCurl::cleanupClass(); LL_CHECK_MEMORY + // Non-LLCurl libcurl library + mAppCoreHttp.cleanup(); + LLFilePickerThread::cleanupClass(); //MUST happen AFTER LLCurl::cleanupClass @@ -2249,10 +2264,8 @@ bool LLAppViewer::initConfiguration() OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); return false; } - - LLUI::setupPaths(); // setup paths for LLTrans based on settings files only - LLTransUtil::parseStrings("strings.xml", default_trans_args); - LLTransUtil::parseLanguageStrings("language_settings.xml"); + + initStrings(); // setup paths for LLTrans based on settings files only // - set procedural settings // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet gSavedSettings.setString("ClientSettingsFile", @@ -2566,13 +2579,15 @@ bool LLAppViewer::initConfiguration() LLStartUp::setStartSLURL(start_slurl); } - const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); - if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) - { - // hack to force the skin to default. - gDirUtilp->setSkinFolder(skinfolder->getValue().asString()); - //gDirUtilp->setSkinFolder("default"); - } + const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); + if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) + { + // Examining "Language" may not suffice -- see LLUI::getLanguage() + // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much + // good because we haven't yet called LLUI::initClass(). + gDirUtilp->setSkinFolder(skinfolder->getValue().asString(), + gSavedSettings.getString("Language")); + } if (gSavedSettings.getBOOL("SpellCheck")) { @@ -2744,6 +2759,52 @@ bool LLAppViewer::initConfiguration() return true; // Config was successful. } +// The following logic is replicated in initConfiguration() (to be able to get +// some initial strings before we've finished initializing enough to know the +// current language) and also in init() (to initialize for real). Somehow it +// keeps growing, necessitating a method all its own. +void LLAppViewer::initStrings() +{ + LLTransUtil::parseStrings("strings.xml", default_trans_args); + LLTransUtil::parseLanguageStrings("language_settings.xml"); + + // parseStrings() sets up the LLTrans substitution table. Add this one item. + LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid")); + + // Now that we've set "[sourceid]", have to go back through + // default_trans_args and reinitialize all those other keys because some + // of them, in turn, reference "[sourceid]". + BOOST_FOREACH(std::string key, default_trans_args) + { + std::string brackets(key), nobrackets(key); + // Invalid to inspect key[0] if key is empty(). But then, the entire + // body of this loop is pointless if key is empty(). + if (key.empty()) + continue; + + if (key[0] != '[') + { + // key was passed without brackets. That means that 'nobrackets' + // is correct but 'brackets' is not. + brackets = STRINGIZE('[' << brackets << ']'); + } + else + { + // key was passed with brackets. That means that 'brackets' is + // correct but 'nobrackets' is not. Erase the left bracket. + nobrackets.erase(0, 1); + std::string::size_type length(nobrackets.length()); + if (length && nobrackets[length - 1] == ']') + { + nobrackets.erase(length - 1); + } + } + // Calling LLTrans::getString() is what embeds the other default + // translation strings into this one. + LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets)); + } +} + namespace { // *TODO - decide if there's a better place for these functions. // do we need a file llupdaterui.cpp or something? -brad @@ -3596,8 +3657,7 @@ void LLAppViewer::migrateCacheDirectory() { gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE); - std::string delimiter = gDirUtilp->getDirDelimiter(); - std::string old_cache_dir = gDirUtilp->getOSUserAppDir() + delimiter + "cache"; + std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache"); std::string new_cache_dir = gDirUtilp->getCacheDir(true); if (gDirUtilp->fileExists(old_cache_dir)) @@ -3613,8 +3673,8 @@ void LLAppViewer::migrateCacheDirectory() while (iter.next(file_name)) { if (file_name == "." || file_name == "..") continue; - std::string source_path = old_cache_dir + delimiter + file_name; - std::string dest_path = new_cache_dir + delimiter + file_name; + std::string source_path = gDirUtilp->add(old_cache_dir, file_name); + std::string dest_path = gDirUtilp->add(new_cache_dir, file_name); if (!LLFile::rename(source_path, dest_path)) { file_count++; @@ -3845,7 +3905,7 @@ bool LLAppViewer::initCache() LLDirIterator iter(dir, mask); if (iter.next(found_file)) { - old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file; + old_vfs_data_file = gDirUtilp->add(dir, found_file); S32 start_pos = found_file.find_last_of('.'); if (start_pos > 0) @@ -4356,6 +4416,10 @@ void LLAppViewer::idle() { return; } + if (gTeleportDisplay) + { + return; + } gViewerWindow->updateUI(); @@ -5156,20 +5220,20 @@ void LLAppViewer::launchUpdater() // 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::vector<std::string> xui_path_vec = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_strings_file); std::string xml_search_paths; - std::vector<std::string>::const_iterator iter; + const char* delim = ""; // 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 + BOOST_FOREACH(std::string this_skin_path, xui_path_vec) + { + // Although we already have the full set of paths with the filename + // appended, the linux-updater.bin command-line switches require us to + // snip the filename OFF and pass it as a separate switch argument. :-P + llinfos << "Got a XUI path: " << this_skin_path << llendl; + xml_search_paths.append(delim); + xml_search_paths.append(gDirUtilp->getDirName(this_skin_path)); + delim = ","; } // build the overall command-line to run the updater correctly LLAppViewer::sUpdaterInfo->mUpdateExePath = diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index ae3c795d1e..7a474f9122 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -31,6 +31,7 @@ #include "llcontrol.h" #include "llsys.h" // for LLOSInfo #include "lltimer.h" +#include "llappcorehttp.h" class LLCommandLineParser; class LLFrameTimer; @@ -173,6 +174,9 @@ public: // Metrics policy helper statics. static void metricsUpdateRegion(U64 region_handle); static void metricsSend(bool enable_reporting); + + // llcorehttp init/shutdown/config information. + LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; } protected: virtual bool initWindow(); // Initialize the viewer's window. @@ -194,6 +198,7 @@ private: void initMaxHeapSize(); bool initThreads(); // Initialize viewer threads, return false on failure. bool initConfiguration(); // Initialize settings from the command line/config file. + void initStrings(); // Initialize LLTrans machinery void initUpdater(); // Initialize the updater service. bool initCache(); // Initialize local client cache. void checkMemory() ; @@ -271,6 +276,9 @@ private: boost::scoped_ptr<LLUpdaterService> mUpdater; + // llcorehttp library init/shutdown helper + LLAppCoreHttp mAppCoreHttp; + //--------------------------------------------- //*NOTE: Mani - legacy updater stuff // Still useable? diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index c9543988a6..ea0b8f00a4 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -62,6 +62,12 @@ void LLAttachmentsMgr::onIdle(void *) void LLAttachmentsMgr::onIdle() { + // Make sure we got a region before trying anything else + if( !gAgent.getRegion() ) + { + return; + } + S32 obj_count = mPendingAttachments.size(); if (obj_count == 0) { diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index b539ac38ed..b539ac38ed 100644..100755 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp index 347a467a8b..8af2f4ea33 100644 --- a/indra/newview/lldaycyclemanager.cpp +++ b/indra/newview/lldaycyclemanager.cpp @@ -184,7 +184,7 @@ void LLDayCycleManager::loadPresets(const std::string& dir) { std::string file; if (!dir_iter.next(file)) break; // no more files - loadPreset(dir + file); + loadPreset(gDirUtilp->add(dir, file)); } } diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index a0289cd2af..4894d63e13 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -99,7 +99,6 @@ void LLDrawable::init() mPositionGroup.clear(); mExtents[0].clear(); mExtents[1].clear(); - mQuietCount = 0; mState = 0; mVObjp = NULL; @@ -407,6 +406,8 @@ void LLDrawable::makeActive() if (!isRoot() && !mParent->isActive()) { mParent->makeActive(); + //NOTE: linked set will now NEVER become static + mParent->setState(LLDrawable::ACTIVE_CHILD); } //all child objects must also be active @@ -426,41 +427,27 @@ void LLDrawable::makeActive() if (mVObjp->getPCode() == LL_PCODE_VOLUME) { - if (mVObjp->isFlexible()) - { - return; - } - } - - if (mVObjp->getPCode() == LL_PCODE_VOLUME) - { gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); } updatePartition(); } - if (isRoot()) - { - mQuietCount = 0; - } - else - { - getParent()->mQuietCount = 0; - } + llassert(isAvatar() || isRoot() || mParent->isActive()); } void LLDrawable::makeStatic(BOOL warning_enabled) { - if (isState(ACTIVE)) + if (isState(ACTIVE) && + !isState(ACTIVE_CHILD) && + !mVObjp->isAttachment() && + !mVObjp->isFlexible()) { clearState(ACTIVE | ANIMATED_CHILD); - if (mParent.notNull() && mParent->isActive() && warning_enabled) - { - LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL; - } - + //drawable became static with active parent, not acceptable + llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled); + LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -487,8 +474,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) mSpatialBridge->markDead(); setSpatialBridge(NULL); } + updatePartition(); } - updatePartition(); } // Returns "distance" between target destination and resulting xfrom @@ -637,9 +624,9 @@ BOOL LLDrawable::updateMove() { return FALSE; } - + makeActive(); - + BOOL done; if (isState(MOVE_UNDAMPED)) diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 960c64fa9e..b1e32bdb5b 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -292,6 +292,7 @@ public: RIGGED = 0x08000000, PARTITION_MOVE = 0x10000000, ANIMATED_CHILD = 0x20000000, + ACTIVE_CHILD = 0x40000000, } EDrawableFlags; private: //aligned members @@ -305,8 +306,6 @@ public: LLPointer<LLDrawable> mParent; F32 mDistanceWRTCamera; - - S32 mQuietCount; static S32 getCurrentFrame() { return sCurVisible; } static S32 getMinVisFrameRange(); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 013c698445..94dd927d26 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -419,6 +419,7 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params) gGL.loadMatrix(gGLModelView); if (params.mModelMatrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix); } gPipeline.mMatrixOpCount++; diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 7fc78fb382..9bc32fddbd 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -308,6 +308,7 @@ void LLDrawPoolTerrain::drawLoop() if (model_matrix != gGLLastMatrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGLLastMatrix = model_matrix; gGL.loadMatrix(gGLModelView); if (model_matrix) @@ -594,7 +595,8 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.translatef(-1.f, 0.f, 0.f); - + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Set alpha texture and do lighting modulation gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR); gGL.getTexUnit(3)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); @@ -742,6 +744,7 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.translatef(-1.f, 0.f, 0.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); // Care about alpha only gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); @@ -781,6 +784,7 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.translatef(-2.f, 0.f, 0.f); + gGL.matrixMode(LLRender::MM_MODELVIEW); // Care about alpha only gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 83f04e45a8..fedbd782dc 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -116,6 +116,7 @@ void LLDrawPoolTree::render(S32 pass) gGL.loadMatrix(gGLModelView); if (model_matrix) { + llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix((GLfloat*) model_matrix->mMatrix); } gPipeline.mMatrixOpCount++; diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index caf15fe1cb..b5faff7968 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -192,14 +192,18 @@ void LLDrawPoolWLSky::renderStars(void) const bool error; LLColor4 star_alpha(LLColor4::black); star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; - llassert_always(!error); + + // If start_brightness is not set, exit + if( error ) + { + llwarns << "star_brightness missing in mCurParams" << llendl; + return; + } gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); gGL.pushMatrix(); gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); - // gl_FragColor.rgb = gl_Color.rgb; - // gl_FragColor.a = gl_Color.a * star_alpha.a; if (LLGLSLShader::sNoFixedFunction) { gCustomAlphaProgram.bind(); diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index bf8338e5f2..fa42b157a7 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -129,7 +129,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) llassert(mFullHeight <= 512); llassert(mFullWidth <= 512); - if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete()) + if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -216,14 +216,12 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } -#if 0 //THIS CAUSES MAINT-1092 - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete(); + bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; if (use_fbo) { gPipeline.mWaterDis.bindTarget(); } -#endif LLGLSLShader::bindNoShader(); LLVertexBuffer::unbind(); @@ -258,12 +256,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances() } } -#if 0 if (use_fbo) { gPipeline.mWaterDis.flush(); } -#endif return ret; } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 582f06eeb0..605cb81c10 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1062,7 +1062,11 @@ bool LLFace::canRenderAsMask() } const LLTextureEntry* te = getTextureEntry(); - + if( !te || !getViewerObject() || !getTexture() ) + { + return false; + } + if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive) @@ -2168,6 +2172,12 @@ BOOL LLFace::hasMedia() const const F32 LEAST_IMPORTANCE = 0.05f ; const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; +void LLFace::resetVirtualSize() +{ + setVirtualSize(0.f); + mImportanceToCamera = 0.f; +} + F32 LLFace::getTextureVirtualSize() { F32 radius; @@ -2233,8 +2243,17 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) LLVector4a t; t.load3(camera->getOrigin().mV); lookAt.setSub(center, t); + F32 dist = lookAt.getLength3().getF32(); - dist = llmax(dist-size.getLength3().getF32(), 0.f); + dist = llmax(dist-size.getLength3().getF32(), 0.001f); + //ramp down distance for nearby objects + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } + lookAt.normalize3fast() ; //get area of circle around node diff --git a/indra/newview/llface.h b/indra/newview/llface.h index efc3424858..de4d03351c 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -218,6 +218,7 @@ public: F32 getTextureVirtualSize() ; F32 getImportanceToCamera()const {return mImportanceToCamera ;} + void resetVirtualSize(); void setHasMedia(bool has_media) { mHasMedia = has_media ;} BOOL hasMedia() const ; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 393f8b9d46..24a27c5146 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -57,6 +57,7 @@ #include "lldxhardware.h" #endif +#define LL_EXPORT_GPU_TABLE 0 #if LL_DARWIN const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt"; @@ -386,6 +387,13 @@ void LLFeatureManager::parseGPUTable(std::string filename) *i = tolower(*i); } +#if LL_EXPORT_GPU_TABLE + llofstream json; + json.open("gpu_table.json"); + + json << "var gpu_table = [" << std::endl; +#endif + bool gpuFound; U32 lineNumber; for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++) @@ -411,7 +419,7 @@ void LLFeatureManager::parseGPUTable(std::string filename) // setup the tokenizer std::string buf(buffer); - std::string cls, label, expr, supported; + std::string cls, label, expr, supported, stats_based, expected_gl_version; boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n")); boost_tokenizer::iterator token_iter = tokens.begin(); @@ -432,13 +440,29 @@ void LLFeatureManager::parseGPUTable(std::string filename) { supported = *token_iter++; } + if (token_iter != tokens.end()) + { + stats_based = *token_iter++; + } + if (token_iter != tokens.end()) + { + expected_gl_version = *token_iter++; + } if (label.empty() || expr.empty() || cls.empty() || supported.empty()) { LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL; continue; } - +#if LL_EXPORT_GPU_TABLE + json << "{'label' : '" << label << "',\n" << + "'regexp' : '" << expr << "',\n" << + "'class' : '" << cls << "',\n" << + "'supported' : '" << supported << "',\n" << + "'stats_based' : " << stats_based << ",\n" << + "'gl_version' : " << expected_gl_version << "\n},\n"; +#endif + for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/ { expr[i] = tolower(expr[i]); @@ -449,12 +473,18 @@ void LLFeatureManager::parseGPUTable(std::string filename) if(boost::regex_search(renderer, re)) { // if we found it, stop! +#if !LL_EXPORT_GPU_TABLE gpuFound = true; +#endif mGPUString = label; mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10); mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10); } } +#if LL_EXPORT_GPU_TABLE + json << "];\n\n"; + json.close(); +#endif file.close(); if ( gpuFound ) @@ -585,7 +615,7 @@ void LLFeatureManager::applyRecommendedSettings() { // apply saved settings // cap the level at 2 (high) - S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2)); + S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); llinfos << "Applying Recommended Features" << llendl; @@ -678,18 +708,34 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) { //same as low, but with "Basic Shaders" enabled maskFeatures("Low"); } + maskFeatures("Class0"); break; case 1: maskFeatures("Mid"); + maskFeatures("Class1"); break; case 2: maskFeatures("High"); + maskFeatures("Class2"); break; case 3: + maskFeatures("High"); + maskFeatures("Class3"); + break; + case 4: + maskFeatures("High"); + maskFeatures("Class4"); + break; + case 5: + maskFeatures("High"); + maskFeatures("Class5"); + break; + case 6: maskFeatures("Ultra"); break; default: maskFeatures("Low"); + maskFeatures("Class0"); break; } @@ -715,14 +761,16 @@ void LLFeatureManager::applyBaseMasks() mFeatures = maskp->getFeatures(); // mask class - if (mGPUClass >= 0 && mGPUClass < 4) + if (mGPUClass >= 0 && mGPUClass < 6) { const char* class_table[] = { "Class0", "Class1", "Class2", - "Class3" + "Class3", + "Class4", + "Class5", }; LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL; diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index c9cb397fcc..6f9d2e49c6 100644 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -39,7 +39,9 @@ typedef enum EGPUClass GPU_CLASS_0 = 0, GPU_CLASS_1 = 1, GPU_CLASS_2 = 2, - GPU_CLASS_3 = 3 + GPU_CLASS_3 = 3, + GPU_CLASS_4 = 4, + GPU_CLASS_5 = 5 } EGPUClass; diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 9745bb6d64..f5bf900d0d 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -44,6 +44,8 @@ #include "llvoavatar.h" /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f; +std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList; +std::vector<S32> LLVolumeImplFlexible::sUpdateDelay; static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild"); static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update"); @@ -70,8 +72,58 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD { mVO->mDrawable->makeActive() ; } + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); + sUpdateDelay.push_back(0); }//----------------------------------------------- +LLVolumeImplFlexible::~LLVolumeImplFlexible() +{ + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx]; + } + + sInstanceList.pop_back(); + sUpdateDelay.pop_back(); +} + +//static +void LLVolumeImplFlexible::updateClass() +{ + // XXX stinson 11/13/2012 : This hack removes the optimization for limiting the number of flexi-prims + // updated. With the optimization, flexi-prims attached to the users avatar were not being + // animated correctly immediately following teleport. With the optimization removed, the bug went away. +#define XXX_STINSON_MAINT_1890_HACK_FIX 1 +#if XXX_STINSON_MAINT_1890_HACK_FIX + for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin(); + iter != sInstanceList.end(); + ++iter) + { + (*iter)->doIdleUpdate(); + } +#else // XXX_STINSON_MAINT_1890_HACK_FIX + std::vector<S32>::iterator delay_iter = sUpdateDelay.begin(); + + for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin(); + iter != sInstanceList.end(); + ++iter) + { + --(*delay_iter); + if (*delay_iter <= 0) + { + (*iter)->doIdleUpdate(); + } + ++delay_iter; + } +#endif // XXX_STINSON_MAINT_1890_HACK_FIX +} + LLVector3 LLVolumeImplFlexible::getFramePosition() const { return mVO->getRenderPosition(); @@ -296,22 +348,17 @@ void LLVolumeImplFlexible::updateRenderRes() // optimization similar to what Havok does for objects that are stationary. //--------------------------------------------------------------------------------- static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies"); -void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVolumeImplFlexible::doIdleUpdate() { LLDrawable* drawablep = mVO->mDrawable; if (drawablep) { //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); - - //flexible objects never go static - drawablep->mQuietCount = 0; - if (!drawablep->isRoot()) - { - LLViewerObject* parent = (LLViewerObject*) mVO->getParent(); - parent->mDrawable->mQuietCount = 0; - } - + + //ensure drawable is active + drawablep->makeActive(); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { bool visible = drawablep->isVisible(); @@ -321,31 +368,45 @@ void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 updateRenderRes(); gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); } - else if (visible && - !drawablep->isState(LLDrawable::IN_REBUILD_Q1) && - mVO->getPixelArea() > 256.f) + else { - U32 id; F32 pixel_area = mVO->getPixelArea(); - if (mVO->isRootEdit()) + U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; + + if (visible) { - id = mID; + if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) && + mVO->getPixelArea() > 256.f) + { + U32 id; + + if (mVO->isRootEdit()) + { + id = mID; + } + else + { + LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); + id = parent->getVolumeInterfaceID(); + } + + if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) + { + sUpdateDelay[mInstanceIndex] = (S32) update_period-1; + + updateRenderRes(); + + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + } + } } else { - LLVOVolume* parent = (LLVOVolume*) mVO->getParent(); - id = parent->getVolumeInterfaceID(); - } - - U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; - - if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) - { - updateRenderRes(); - gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); + sUpdateDelay[mInstanceIndex] = (S32) update_period; } } + } } } @@ -370,7 +431,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() { BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE; - doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0); + doIdleUpdate(); if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE)) { @@ -383,6 +444,15 @@ void LLVolumeImplFlexible::doFlexibleUpdate() //the object is not visible return ; } + + // stinson 11/12/2012: Need to check with davep on the following. + // Skipping the flexible update if render res is negative. If we were to continue with a negative value, + // the subsequent S32 num_render_sections = 1<<mRenderRes; code will specify a really large number of + // render sections which will then create a length exception in the std::vector::resize() method. + if (mRenderRes < 0) + { + return; + } S32 num_sections = 1 << mSimulateRes; diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index 56d579d86f..beb281a906 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -70,8 +70,16 @@ struct LLFlexibleObjectSection //--------------------------------------------------------- class LLVolumeImplFlexible : public LLVolumeInterface { +private: + static std::vector<LLVolumeImplFlexible*> sInstanceList; + static std::vector<S32> sUpdateDelay; + S32 mInstanceIndex; + public: + static void updateClass(); + LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes); + ~LLVolumeImplFlexible(); // Implements LLVolumeInterface U32 getID() const { return mID; } @@ -79,7 +87,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface LLQuaternion getFrameRotation() const; LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; } void updateRenderRes(); - void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void doIdleUpdate(); BOOL doUpdateGeometry(LLDrawable *drawable); LLVector3 getPivotPosition() const; void onSetVolume(const LLVolumeParams &volume_params, const S32 detail); diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index fa0ad20fdb..62848586cd 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -422,13 +422,14 @@ void LLFloaterBvhPreview::resetMotion() LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); BOOL paused = avatarp->areAnimationsPaused(); - // *TODO: Fix awful casting hack - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - // Set emotion - std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString(); - motionp->setEmote(mIDList[emote]); - + LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*>(avatarp->findMotion(mMotionID)); + if( motionp ) + { + // Set emotion + std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString(); + motionp->setEmote(mIDList[emote]); + } + LLUUID base_id = mIDList[getChild<LLUICtrl>("preview_base_anim")->getValue().asString()]; avatarp->deactivateAllMotions(); avatarp->startMotion(mMotionID, 0.0f); @@ -438,8 +439,12 @@ void LLFloaterBvhPreview::resetMotion() // Set pose std::string handpose = getChild<LLUICtrl>("hand_pose_combo")->getValue().asString(); avatarp->startMotion( ANIM_AGENT_HAND_MOTION, 0.0f ); - motionp->setHandPose(LLHandMotion::getHandPose(handpose)); + if( motionp ) + { + motionp->setHandPose(LLHandMotion::getHandPose(handpose)); + } + if (paused) { mPauseRequest = avatarp->requestPause(); diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp index fd9c37ae73..4cb632bd6a 100644 --- a/indra/newview/llfloaterhelpbrowser.cpp +++ b/indra/newview/llfloaterhelpbrowser.cpp @@ -77,15 +77,7 @@ void LLFloaterHelpBrowser::onOpen(const LLSD& key) gSavedSettings.setBOOL("HelpFloaterOpen", TRUE); std::string topic = key.asString(); - - if (topic == "__local") - { - mBrowser->navigateToLocalPage( "help-offline" , "index.html" ); - } - else - { - mBrowser->navigateTo(LLViewerHelp::instance().getURL(topic)); - } + mBrowser->navigateTo(LLViewerHelp::instance().getURL(topic)); } //virtual diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index df8ecb6fd9..55f3d548ec 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2362,12 +2362,6 @@ LLPanelLandAccess::~LLPanelLandAccess() void LLPanelLandAccess::refresh() { LLFloater* parent_floater = gFloaterView->getParentFloater(this); - - if (mListAccess) - mListAccess->deleteAllItems(); - if (mListBanned) - mListBanned->deleteAllItems(); - LLParcel *parcel = mParcel->getParcel(); // Display options @@ -2385,7 +2379,11 @@ void LLPanelLandAccess::refresh() getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name ); // Allow list + if (mListAccess) { + // Clear the sort order so we don't re-sort on every add. + mListAccess->clearSortOrder(); + mListAccess->deleteAllItems(); S32 count = parcel->mAccessList.size(); getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); @@ -2420,13 +2418,17 @@ void LLPanelLandAccess::refresh() } suffix.append(" " + parent_floater->getString("Remaining") + ")"); } - if (mListAccess) - mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); + mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } + mListAccess->sortByName(TRUE); } // Ban List + if(mListBanned) { + // Clear the sort order so we don't re-sort on every add. + mListBanned->clearSortOrder(); + mListBanned->deleteAllItems(); S32 count = parcel->mBanList.size(); getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); @@ -2464,6 +2466,7 @@ void LLPanelLandAccess::refresh() } mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } + mListBanned->sortByName(TRUE); } if(parcel->getRegionDenyAnonymousOverride()) @@ -2599,13 +2602,13 @@ void LLPanelLandAccess::refresh_ui() getChildView("AccessList")->setEnabled(can_manage_allowed); S32 allowed_list_count = parcel->mAccessList.size(); getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST); - BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0; + BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0); getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected); getChildView("BannedList")->setEnabled(can_manage_banned); S32 banned_list_count = parcel->mBanList.size(); getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST); - has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0; + has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0); getChildView("remove_banned")->setEnabled(can_manage_banned && has_selected); } } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5752f839ce..542e96cf16 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -750,7 +750,10 @@ void LLFloaterPreference::onClose(bool app_quitting) { gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex()); LLPanelLogin::setAlwaysRefresh(false); - cancel(); + if (!app_quitting) + { + cancel(); + } } void LLFloaterPreference::onOpenHardwareSettings() diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 17850ff35d..fe29bb38c7 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -287,8 +287,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) //dispatch the message dispatch.dispatch(request, invoice, strings); - LLViewerRegion* region = gAgent.getRegion(); - panel->updateControls(region); + panel->updateControls(gAgent.getRegion()); } @@ -1924,10 +1923,18 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) BOOL manager = (region && region->isEstateManager()); setCtrlsEnabled(god || owner || manager); + BOOL has_allowed_avatar = getChild<LLNameListCtrl>("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_allowed_group = getChild<LLNameListCtrl>("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_banned_agent = getChild<LLNameListCtrl>("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_estate_manager = getChild<LLNameListCtrl>("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; + getChildView("add_allowed_avatar_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_avatar_btn")->setEnabled(god || owner || manager); + getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && (god || owner || manager)); + getChildView("allowed_avatar_name_list")->setEnabled(god || owner || manager); + getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_group_btn")->setEnabled(god || owner || manager); + getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && (god || owner || manager) ); + getChildView("allowed_group_name_list")->setEnabled(god || owner || manager); // Can't ban people from mainland, orientation islands, etc. because this // creates much network traffic and server load. @@ -1935,14 +1942,15 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) bool linden_estate = isLindenEstate(); bool enable_ban = (god || owner || manager) && !linden_estate; getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban); + getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); + getChildView("banned_avatar_name_list")->setEnabled(god || owner || manager); getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); // estate managers can't add estate managers getChildView("add_estate_manager_btn")->setEnabled(god || owner); - getChildView("remove_estate_manager_btn")->setEnabled(god || owner); + getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); getChildView("estate_manager_name_list")->setEnabled(god || owner); refresh(); @@ -1979,10 +1987,8 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) { - if (checkRemovalButton(child_ctrl->getName())) - { - // do nothing - } + // Ensure appropriate state of the management ui. + updateControls(gAgent.getRegion()); } bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) @@ -2080,23 +2086,8 @@ void LLPanelEstateInfo::refreshFromEstate() getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous()); getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified()); - // If visible from mainland, disable the access allowed - // UI, as anyone can teleport there. - // However, gods need to be able to edit the access list for - // linden estates, regardless of visibility, to allow object - // and L$ transfers. - { - bool visible_from_mainland = estate_info.getIsExternallyVisible(); - bool god = gAgent.isGodlike(); - bool linden_estate = isLindenEstate(); - - bool enable_agent = (!visible_from_mainland || (god && linden_estate)); - bool enable_group = enable_agent; - bool enable_ban = !linden_estate; - - setAccessAllowedEnabled(enable_agent, enable_group, enable_ban); - } - + // Ensure appriopriate state of the management UI + updateControls(gAgent.getRegion()); refresh(); } @@ -2225,47 +2216,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name) getChild<LLUICtrl>("estate_owner")->setValue(LLSD(name)); } -void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, - bool enable_group, - bool enable_ban) -{ - getChildView("allow_resident_label")->setEnabled(enable_agent); - getChildView("allowed_avatar_name_list")->setEnabled(enable_agent); - getChildView("allowed_avatar_name_list")->setVisible( enable_agent); - getChildView("add_allowed_avatar_btn")->setEnabled(enable_agent); - getChildView("remove_allowed_avatar_btn")->setEnabled(enable_agent); - - // Groups - getChildView("allow_group_label")->setEnabled(enable_group); - getChildView("allowed_group_name_list")->setEnabled(enable_group); - getChildView("allowed_group_name_list")->setVisible( enable_group); - getChildView("add_allowed_group_btn")->setEnabled(enable_group); - getChildView("remove_allowed_group_btn")->setEnabled(enable_group); - - // Ban - getChildView("ban_resident_label")->setEnabled(enable_ban); - getChildView("banned_avatar_name_list")->setEnabled(enable_ban); - getChildView("banned_avatar_name_list")->setVisible( enable_ban); - getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban); - - // Update removal buttons if needed - if (enable_agent) - { - checkRemovalButton("allowed_avatar_name_list"); - } - - if (enable_group) - { - checkRemovalButton("allowed_group_name_list"); - } - - if (enable_ban) - { - checkRemovalButton("banned_avatar_name_list"); - } -} - void LLPanelEstateInfo::clearAccessLists() { LLNameListCtrl* name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list"); @@ -2279,39 +2229,7 @@ void LLPanelEstateInfo::clearAccessLists() { name_list->deleteAllItems(); } -} - -// enables/disables the "remove" button for the various allow/ban lists -BOOL LLPanelEstateInfo::checkRemovalButton(std::string name) -{ - std::string btn_name = ""; - if (name == "allowed_avatar_name_list") - { - btn_name = "remove_allowed_avatar_btn"; - } - else if (name == "allowed_group_name_list") - { - btn_name = "remove_allowed_group_btn"; - } - else if (name == "banned_avatar_name_list") - { - btn_name = "remove_banned_avatar_btn"; - } - else if (name == "estate_manager_name_list") - { - //ONLY OWNER CAN ADD /DELET ESTATE MANAGER - LLViewerRegion* region = gAgent.getRegion(); - if (region && (region->getOwner() == gAgent.getID())) - { - btn_name = "remove_estate_manager_btn"; - } - } - - // enable the remove button if something is selected - LLNameListCtrl* name_list = getChild<LLNameListCtrl>(name); - getChildView(btn_name)->setEnabled(name_list && name_list->getFirstSelected() ? TRUE : FALSE); - - return (btn_name != ""); + updateControls(gAgent.getRegion()); } // static @@ -2792,15 +2710,15 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_agent_name_list) { - //allowed_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + allowed_agent_name_list->clearSortOrder(); for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ allowed_agent_name_list->addNameItem(id); } - panel->getChildView("remove_allowed_avatar_btn")->setEnabled(allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_agent_name_list->sortByColumnIndex(0, TRUE); + allowed_agent_name_list->sortByName(TRUE); } } @@ -2817,6 +2735,8 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_group_name_list) { + // Don't sort these as we add them, sort them when we are done. + allowed_group_name_list->clearSortOrder(); allowed_group_name_list->deleteAllItems(); for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) { @@ -2824,8 +2744,7 @@ bool LLDispatchSetEstateAccess::operator()( memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ allowed_group_name_list->addGroupNameItem(id); } - panel->getChildView("remove_allowed_group_btn")->setEnabled(allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_group_name_list->sortByColumnIndex(0, TRUE); + allowed_group_name_list->sortByName(TRUE); } } @@ -2849,15 +2768,16 @@ bool LLDispatchSetEstateAccess::operator()( if (banned_agent_name_list) { - //banned_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + banned_agent_name_list->clearSortOrder(); + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ banned_agent_name_list->addNameItem(id); } - panel->getChildView("remove_banned_avatar_btn")->setEnabled(banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); - banned_agent_name_list->sortByColumnIndex(0, TRUE); + banned_agent_name_list->sortByName(TRUE); } } @@ -2872,6 +2792,9 @@ bool LLDispatchSetEstateAccess::operator()( panel->getChild<LLNameListCtrl>("estate_manager_name_list"); if (estate_manager_name_list) { + // Don't sort these as we add them, sort them when we are done. + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); // Clear existing entries // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't @@ -2883,11 +2806,13 @@ bool LLDispatchSetEstateAccess::operator()( memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ estate_manager_name_list->addNameItem(id); } - panel->getChildView("remove_estate_manager_btn")->setEnabled(estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); - estate_manager_name_list->sortByColumnIndex(0, TRUE); + estate_manager_name_list->sortByName(TRUE); } } + // Update the buttons which may change based on the list contents but also needs to account for general access features. + panel->updateControls(gAgent.getRegion()); + return true; } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index e36ef4604b..f0499f1903 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -312,9 +312,6 @@ public: const std::string getOwnerName() const; void setOwnerName(const std::string& name); - // If visible from mainland, allowed agent and allowed groups - // are ignored, so must disable UI. - void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban); protected: virtual BOOL sendUpdate(); // confirmation dialog callback @@ -324,7 +321,6 @@ protected: void commitEstateManagers(); void clearAccessLists(); - BOOL checkRemovalButton(std::string name); BOOL checkSunHourSlider(LLUICtrl* child_ctrl); U32 mEstateID; diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp index 2b34b72055..9157389187 100644 --- a/indra/newview/llfloatertexturefetchdebugger.cpp +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -59,12 +59,15 @@ LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key) mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this)); mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this)); + mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this)); } //---------------------------------------------- BOOL LLFloaterTextureFetchDebugger::postBuild(void) { mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); + mStartStatus = (S32)LLTextureFetchDebugger::IDLE; //set states for buttons mButtonStateMap["start_btn"] = true; @@ -76,8 +79,10 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void) mButtonStateMap["decode_btn"] = false; mButtonStateMap["gl_btn"] = false; - mButtonStateMap["refetchviscache_btn"] = true; - mButtonStateMap["refetchvishttp_btn"] = true; + mButtonStateMap["refetchviscache_btn"] = false; + mButtonStateMap["refetchvishttp_btn"] = false; + mButtonStateMap["refetchallcache_btn"] = false; + mButtonStateMap["refetchallhttp_btn"] = false; updateButtons(); @@ -89,7 +94,7 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void) LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger() { //stop everything - mDebugger->stopDebug(); + mDebugger->setStopDebug(); } void LLFloaterTextureFetchDebugger::updateButtons() @@ -118,47 +123,81 @@ void LLFloaterTextureFetchDebugger::disableButtons() childDisable("gl_btn"); childDisable("refetchviscache_btn"); childDisable("refetchvishttp_btn"); + childDisable("refetchallcache_btn"); + childDisable("refetchallhttp_btn"); +} +void LLFloaterTextureFetchDebugger::setStartStatus(S32 status) +{ + llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ; + mStartStatus = status; +} + +bool LLFloaterTextureFetchDebugger::idleStart() +{ + if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE) + { + mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus); + mStartStatus = (S32)LLTextureFetchDebugger::IDLE; + return true; + } + + return false; } void LLFloaterTextureFetchDebugger::idle() { - LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); - - if(mDebugger->update()) + if(idleStart()) + { + return; + } + + const F32 max_time = 0.005f; //5ms + LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); + if(mDebugger->update(max_time)) { switch(state) { case LLTextureFetchDebugger::IDLE: break; - case LLTextureFetchDebugger::READ_CACHE: - mButtonStateMap["cachewrite_btn"] = true; - mButtonStateMap["decode_btn"] = true; - updateButtons(); + case LLTextureFetchDebugger::START_DEBUG: + mButtonStateMap["cacheread_btn"] = true; + mButtonStateMap["http_btn"] = true; + mButtonStateMap["refetchviscache_btn"] = true; + mButtonStateMap["refetchvishttp_btn"] = true; + mButtonStateMap["refetchallcache_btn"] = true; + mButtonStateMap["refetchallhttp_btn"] = true; break; - case LLTextureFetchDebugger::WRITE_CACHE: - updateButtons(); + case LLTextureFetchDebugger::READ_CACHE: + mButtonStateMap["decode_btn"] = true; + break; + case LLTextureFetchDebugger::WRITE_CACHE: break; case LLTextureFetchDebugger::DECODING: - mButtonStateMap["gl_btn"] = true; - updateButtons(); + mButtonStateMap["gl_btn"] = true; break; case LLTextureFetchDebugger::HTTP_FETCHING: mButtonStateMap["cacheread_btn"] = true; mButtonStateMap["cachewrite_btn"] = true; - mButtonStateMap["decode_btn"] = true; - updateButtons(); + mButtonStateMap["decode_btn"] = true; break; - case LLTextureFetchDebugger::GL_TEX: - updateButtons(); + case LLTextureFetchDebugger::GL_TEX: break; - case LLTextureFetchDebugger::REFETCH_VIS_CACHE: - updateButtons(); - case LLTextureFetchDebugger::REFETCH_VIS_HTTP: - updateButtons(); + case LLTextureFetchDebugger::REFETCH_VIS_CACHE: + break; + case LLTextureFetchDebugger::REFETCH_VIS_HTTP: + break; + case LLTextureFetchDebugger::REFETCH_ALL_CACHE: + break; + case LLTextureFetchDebugger::REFETCH_ALL_HTTP: break; default: break; } + + if(state != LLTextureFetchDebugger::IDLE) + { + updateButtons(); + } } } @@ -172,11 +211,10 @@ void LLFloaterTextureFetchDebugger::onClickStart() { disableButtons(); - mDebugger->startDebug(); + setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG); mButtonStateMap["start_btn"] = false; - mButtonStateMap["cacheread_btn"] = true; - mButtonStateMap["http_btn"] = true; + updateButtons(); } @@ -185,7 +223,9 @@ void LLFloaterTextureFetchDebugger::onClickClose() setVisible(FALSE); //stop everything - mDebugger->stopDebug(); + mDebugger->setStopDebug(); + + delete this; } void LLFloaterTextureFetchDebugger::onClickClear() @@ -203,7 +243,7 @@ void LLFloaterTextureFetchDebugger::onClickClear() updateButtons(); //stop everything - mDebugger->stopDebug(); + mDebugger->setStopDebug(); mDebugger->clearHistory(); } @@ -211,49 +251,63 @@ void LLFloaterTextureFetchDebugger::onClickCacheRead() { disableButtons(); - mDebugger->debugCacheRead(); + setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE); } void LLFloaterTextureFetchDebugger::onClickCacheWrite() { disableButtons(); - mDebugger->debugCacheWrite(); + setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE); } void LLFloaterTextureFetchDebugger::onClickHTTPLoad() { disableButtons(); - mDebugger->debugHTTP(); + setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING); } void LLFloaterTextureFetchDebugger::onClickDecode() { disableButtons(); - mDebugger->debugDecoder(); + setStartStatus((S32)LLTextureFetchDebugger::DECODING); } void LLFloaterTextureFetchDebugger::onClickGLTexture() { disableButtons(); - mDebugger->debugGLTextureCreation(); + setStartStatus((S32)LLTextureFetchDebugger::GL_TEX); } void LLFloaterTextureFetchDebugger::onClickRefetchVisCache() { disableButtons(); - mDebugger->debugRefetchVisibleFromCache(); + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE); } void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP() { disableButtons(); - mDebugger->debugRefetchVisibleFromHTTP(); + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllCache() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP() +{ + disableButtons(); + + setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP); } void LLFloaterTextureFetchDebugger::draw() @@ -368,8 +422,22 @@ void LLFloaterTextureFetchDebugger::draw() else { getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); - getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); - getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); + } + + //total time on refetching all textures from cache + if(mDebugger->getRefetchAllCacheTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime())); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); } //total time on refetching visible textures from http @@ -382,8 +450,22 @@ void LLFloaterTextureFetchDebugger::draw() else { getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); - getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); - getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); + } + + //total time on refetching all textures from http + if(mDebugger->getRefetchAllHTTPTime() < 0.f) + { + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----")); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----")); + } + else + { + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime())); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); + getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); } LLFloater::draw(); diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h index 33012c6a3d..096ad88e07 100644 --- a/indra/newview/llfloatertexturefetchdebugger.h +++ b/indra/newview/llfloatertexturefetchdebugger.h @@ -53,6 +53,8 @@ public: void onClickRefetchVisCache(); void onClickRefetchVisHTTP(); + void onClickRefetchAllCache(); + void onClickRefetchAllHTTP(); public: void idle() ; @@ -63,9 +65,12 @@ private: void updateButtons(); void disableButtons(); + void setStartStatus(S32 status); + bool idleStart(); private: LLTextureFetchDebugger* mDebugger; std::map<std::string, bool> mButtonStateMap; + S32 mStartStatus; }; #endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 87d048c15b..2d91a61b54 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -82,6 +82,7 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this)); mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this)); mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); + mCommitCallbackRegistrar.add("TopObjects.GetByParcelName", boost::bind(&LLFloaterTopObjects::onGetByParcelName, this)); mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this)); } @@ -99,21 +100,6 @@ BOOL LLFloaterTopObjects::postBuild() setDefaultBtn("show_beacon_btn"); - /* - LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor"); - if (line_editor) - { - line_editor->setCommitOnFocusLost(FALSE); - line_editor->setCommitCallback(onGetByOwnerName, this); - } - - line_editor = getChild<LLLineEditor>("object_name_editor"); - if (line_editor) - { - line_editor->setCommitOnFocusLost(FALSE); - line_editor->setCommitCallback(onGetByObjectName, this); - }*/ - mCurrentMode = STAT_REPORT_TOP_SCRIPTS; mFlags = 0; mFilter.clear(); @@ -168,9 +154,11 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) F32 score; std::string name_buf; std::string owner_buf; + std::string parcel_buf("unknown"); F32 mono_score = 0.f; bool have_extended_data = false; S32 public_urls = 0; + F32 script_memory = 0.f; msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block); msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block); @@ -180,12 +168,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block); msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block); msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block); + if(msg->has("DataExtended")) { have_extended_data = true; msg->getU32("DataExtended", "TimeStamp", time_stamp, block); msg->getF32("DataExtended", "MonoScore", mono_score, block); msg->getS32("DataExtended", "PublicURLs", public_urls, block); + if (msg->getSize("DataExtended", "ParcelName") > 0) + { + msg->getString("DataExtended", "ParcelName", parcel_buf, block); + msg->getF32("DataExtended", "Size", script_memory, block); + } } LLSD element; @@ -193,13 +187,14 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) element["id"] = task_id; LLSD columns; - columns[0]["column"] = "score"; - columns[0]["value"] = llformat("%0.3f", score); - columns[0]["font"] = "SANSSERIF"; + S32 column_num = 0; + columns[column_num]["column"] = "score"; + columns[column_num]["value"] = llformat("%0.3f", score); + columns[column_num++]["font"] = "SANSSERIF"; - columns[1]["column"] = "name"; - columns[1]["value"] = name_buf; - columns[1]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "name"; + columns[column_num]["value"] = name_buf; + columns[column_num++]["font"] = "SANSSERIF"; // Owner names can have trailing spaces sent from server LLStringUtil::trim(owner_buf); @@ -215,28 +210,33 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) // ...just strip out legacy "Resident" name owner_buf = LLCacheName::cleanFullName(owner_buf); } - columns[2]["column"] = "owner"; - columns[2]["value"] = owner_buf; - columns[2]["font"] = "SANSSERIF"; - - columns[3]["column"] = "location"; - columns[3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); - columns[3]["font"] = "SANSSERIF"; - columns[4]["column"] = "time"; - columns[4]["type"] = "date"; - columns[4]["value"] = LLDate((time_t)time_stamp); - columns[4]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "owner"; + columns[column_num]["value"] = owner_buf; + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "location"; + columns[column_num]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "parcel"; + columns[column_num]["value"] = parcel_buf; + columns[column_num++]["font"] = "SANSSERIF"; + + columns[column_num]["column"] = "time"; + columns[column_num]["type"] = "date"; + columns[column_num]["value"] = LLDate((time_t)time_stamp); + columns[column_num++]["font"] = "SANSSERIF"; if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS && have_extended_data) { - columns[5]["column"] = "mono_time"; - columns[5]["value"] = llformat("%0.3f", mono_score); - columns[5]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "memory"; + columns[column_num]["value"] = llformat("%0.0f", (script_memory / 1000.f)); + columns[column_num++]["font"] = "SANSSERIF"; - columns[6]["column"] = "URLs"; - columns[6]["value"] = llformat("%d", public_urls); - columns[6]["font"] = "SANSSERIF"; + columns[column_num]["column"] = "URLs"; + columns[column_num]["value"] = llformat("%d", public_urls); + columns[column_num++]["font"] = "SANSSERIF"; } element["columns"] = columns; list->addElement(element); @@ -260,18 +260,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { setTitle(getString("top_scripts_title")); list->setColumnLabel("score", getString("scripts_score_label")); - list->setColumnLabel("mono_time", getString("scripts_mono_time_label")); LLUIString format = getString("top_scripts_text"); format.setArg("[COUNT]", llformat("%d", total_count)); - format.setArg("[TIME]", llformat("%0.1f", mtotalScore)); + format.setArg("[TIME]", llformat("%0.3f", mtotalScore)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); } else { setTitle(getString("top_colliders_title")); list->setColumnLabel("score", getString("colliders_score_label")); - list->setColumnLabel("mono_time", ""); + list->setColumnLabel("URLs", ""); + list->setColumnLabel("memory", ""); LLUIString format = getString("top_colliders_text"); format.setArg("[COUNT]", llformat("%d", total_count)); getChild<LLUICtrl>("title_text")->setValue(LLSD(format)); @@ -301,6 +301,7 @@ void LLFloaterTopObjects::updateSelectionInfo() { getChild<LLUICtrl>("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString()); getChild<LLUICtrl>("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString()); + getChild<LLUICtrl>("parcel_name_editor")->setValue(sli->getColumn(4)->getValue().asString()); } } @@ -480,6 +481,15 @@ void LLFloaterTopObjects::onGetByOwnerName() onRefresh(); } + +void LLFloaterTopObjects::onGetByParcelName() +{ + mFlags = STAT_FILTER_BY_PARCEL_NAME; + mFilter = getChild<LLUICtrl>("parcel_name_editor")->getValue().asString(); + onRefresh(); +} + + void LLFloaterTopObjects::showBeacon() { LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list"); diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index a608ca20f1..6edc46cf79 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -73,9 +73,7 @@ private: void onGetByOwnerName(); void onGetByObjectName(); - -// static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); }; -// static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); }; + void onGetByParcelName(); void showBeacon(); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index d741b5b133..15e0b89f6c 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -137,7 +137,7 @@ public: virtual ~LLFloaterUIPreview(); std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu - void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update + void displayFloater(BOOL click, S32 ID); // needs to be public so live file can call it when it finds an update /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); @@ -291,7 +291,8 @@ LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater { mSavedLocalization = LLUI::sSettingGroups["config"]->getString("Language"); // save current localization setting LLUI::sSettingGroups["config"]->setString("Language", floater->getLocStr(ID));// hack language to be the one we want to preview floaters in - LLUI::setupPaths(); // forcibly reset XUI paths with this new language + // forcibly reset XUI paths with this new language + gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), floater->getLocStr(ID)); } // Actually reset in destructor @@ -299,7 +300,8 @@ LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater LLLocalizationResetForcer::~LLLocalizationResetForcer() { LLUI::sSettingGroups["config"]->setString("Language", mSavedLocalization); // reset language to what it was before we changed it - LLUI::setupPaths(); // forcibly reset XUI paths with this new language + // forcibly reset XUI paths with this new language + gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), mSavedLocalization); } // Live file constructor @@ -488,7 +490,7 @@ BOOL LLFloaterUIPreview::postBuild() { if((found = iter.next(language_directory))) // get next directory { - std::string full_path = xui_dir + language_directory; + std::string full_path = gDirUtilp->add(xui_dir, language_directory); if(LLFile::isfile(full_path.c_str())) // if it's not a directory, skip it { continue; @@ -773,7 +775,8 @@ void LLFloaterUIPreview::onClickDisplayFloater(S32 caller_id) // Saves the current floater/panel void LLFloaterUIPreview::onClickSaveFloater(S32 caller_id) { - displayFloater(TRUE, caller_id, true); + displayFloater(TRUE, caller_id); + popupAndPrintWarning("Save-floater functionality removed, use XML schema to clean up XUI files"); } // Saves all floater/panels @@ -784,25 +787,15 @@ void LLFloaterUIPreview::onClickSaveAll(S32 caller_id) for (int index = 0; index < listSize; index++) { mFileList->selectNthItem(index); - displayFloater(TRUE, caller_id, true); + displayFloater(TRUE, caller_id); } -} - -// Given path to floater or panel XML file "filename.xml", -// returns "filename_new.xml" -static std::string append_new_to_xml_filename(const std::string& path) -{ - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), path); - std::string::size_type extension_pos = full_filename.rfind(".xml"); - full_filename.resize(extension_pos); - full_filename += "_new.xml"; - return full_filename; + popupAndPrintWarning("Save-floater functionality removed, use XML schema to clean up XUI files"); } // Actually display the floater // Only set up a new live file if this came from a click (at which point there should be no existing live file), rather than from the live file's update itself; // otherwise, we get an infinite loop as the live file keeps recreating itself. That means this function is generally called twice. -void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) +void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID) { // Convince UI that we're in a different language (the one selected on the drop-down menu) LLLocalizationResetForcer reset_forcer(this, ID); // save old language in reset forcer object (to be reset upon destruction when it falls out of scope) @@ -843,48 +836,13 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) if(!strncmp(path.c_str(),"floater_",8) || !strncmp(path.c_str(), "inspect_", 8)) // if it's a floater { - if (save) - { - LLXMLNodePtr floater_write = new LLXMLNode(); - (*floaterp)->buildFromFile(path, floater_write); // just build it - - if (!floater_write->isNull()) - { - std::string full_filename = append_new_to_xml_filename(path); - LLFILE* floater_temp = LLFile::fopen(full_filename.c_str(), "w"); - LLXMLNode::writeHeaderToFile(floater_temp); - const bool use_type_decorations = false; - floater_write->writeToFile(floater_temp, std::string(), use_type_decorations); - fclose(floater_temp); - } - } - else - { - (*floaterp)->buildFromFile(path); // just build it - (*floaterp)->openFloater((*floaterp)->getKey()); - (*floaterp)->setCanResize((*floaterp)->isResizable()); - } - + (*floaterp)->buildFromFile(path); // just build it + (*floaterp)->openFloater((*floaterp)->getKey()); + (*floaterp)->setCanResize((*floaterp)->isResizable()); } else if (!strncmp(path.c_str(),"menu_",5)) // if it's a menu { - if (save) - { - LLXMLNodePtr menu_write = new LLXMLNode(); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(path, gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance(), menu_write); - - if (!menu_write->isNull()) - { - std::string full_filename = append_new_to_xml_filename(path); - LLFILE* menu_temp = LLFile::fopen(full_filename.c_str(), "w"); - LLXMLNode::writeHeaderToFile(menu_temp); - const bool use_type_decorations = false; - menu_write->writeToFile(menu_temp, std::string(), use_type_decorations); - fclose(menu_temp); - } - - delete menu; - } + // former 'save' processing excised } else // if it is a panel... { @@ -896,39 +854,21 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) LLPanel::Params panel_params; LLPanel* panel = LLUICtrlFactory::create<LLPanel>(panel_params); // create a new panel - if (save) - { - LLXMLNodePtr panel_write = new LLXMLNode(); - panel->buildFromFile(path, panel_write); // build it - - if (!panel_write->isNull()) - { - std::string full_filename = append_new_to_xml_filename(path); - LLFILE* panel_temp = LLFile::fopen(full_filename.c_str(), "w"); - LLXMLNode::writeHeaderToFile(panel_temp); - const bool use_type_decorations = false; - panel_write->writeToFile(panel_temp, std::string(), use_type_decorations); - fclose(panel_temp); - } - } - else - { - panel->buildFromFile(path); // build it - LLRect new_size = panel->getRect(); // get its rectangle - panel->setOrigin(2,2); // reset its origin point so it's not offset by -left or other XUI attributes - (*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute - panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements) - panel->updateBoundingRect(); // update bounding rect - LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect - LLRect new_rect = panel->getRect(); // get the panel's rect - new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible - LLRect floater_rect = new_rect; - floater_rect.stretch(4, 4); - (*floaterp)->reshape(floater_rect.getWidth(), floater_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions - panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed) - (*floaterp)->addChild(panel); // add panel as child - (*floaterp)->openFloater(); // open floater (needed?) - } + panel->buildFromFile(path); // build it + LLRect new_size = panel->getRect(); // get its rectangle + panel->setOrigin(2,2); // reset its origin point so it's not offset by -left or other XUI attributes + (*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute + panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements) + panel->updateBoundingRect(); // update bounding rect + LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect + LLRect new_rect = panel->getRect(); // get the panel's rect + new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible + LLRect floater_rect = new_rect; + floater_rect.stretch(4, 4); + (*floaterp)->reshape(floater_rect.getWidth(), floater_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions + panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed) + (*floaterp)->addChild(panel); // add panel as child + (*floaterp)->openFloater(); // open floater (needed?) } if(ID == 1) @@ -964,7 +904,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save) (*floaterp)->center(); addDependentFloater(*floaterp); - if(click && ID == 1 && !save) + if(click && ID == 1) { // set up live file to track it if(mLiveFile) diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index efffd0f98e..81eb1d397e 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -36,6 +36,7 @@ #include <vector> #include <algorithm> +#include "llappviewer.h" #include "llagent.h" #include "llui.h" #include "message.h" @@ -63,7 +64,7 @@ #pragma warning(pop) // Restore all warnings to the previous state #endif -const U32 MAX_CACHED_GROUPS = 10; +const U32 MAX_CACHED_GROUPS = 20; // // LLRoleActionSet @@ -234,8 +235,15 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) : mRoleDataComplete(FALSE), mRoleMemberDataComplete(FALSE), mGroupPropertiesDataComplete(FALSE), - mPendingRoleMemberRequest(FALSE) + mPendingRoleMemberRequest(FALSE), + mAccessTime(0.0f) { + mMemberVersion.generate(); +} + +void LLGroupMgrGroupData::setAccessed() +{ + mAccessTime = (F32)LLFrameTimer::getTotalSeconds(); } BOOL LLGroupMgrGroupData::getRoleData(const LLUUID& role_id, LLRoleData& role_data) @@ -311,14 +319,14 @@ void LLGroupMgrGroupData::setRoleData(const LLUUID& role_id, LLRoleData role_dat role_data.mChangeType = RC_UPDATE_DATA; } else - { + { role_data.mChangeType = RC_UPDATE_POWERS; } mRoleChanges[role_id] = role_data; } else - { + { llwarns << "Change being made to non-existant role " << role_id << llendl; } } @@ -417,6 +425,7 @@ void LLGroupMgrGroupData::removeMemberData() } mMembers.clear(); mMemberDataComplete = FALSE; + mMemberVersion.generate(); } void LLGroupMgrGroupData::removeRoleData() @@ -739,6 +748,7 @@ void LLGroupMgrGroupData::cancelRoleChanges() LLGroupMgr::LLGroupMgr() { + mLastGroupMembersRequestFrame = 0; } LLGroupMgr::~LLGroupMgr() @@ -937,6 +947,8 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) } } + group_datap->mMemberVersion.generate(); + if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount) { group_datap->mMemberDataComplete = TRUE; @@ -1360,7 +1372,7 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data) LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id) { - LLGroupMgrGroupData* group_datap; + LLGroupMgrGroupData* group_datap = NULL; group_map_t::iterator existing_group = LLGroupMgr::getInstance()->mGroups.find(id); if (existing_group == LLGroupMgr::getInstance()->mGroups.end()) @@ -1373,6 +1385,11 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id) group_datap = existing_group->second; } + if (group_datap) + { + group_datap->setAccessed(); + } + return group_datap; } @@ -1413,25 +1430,41 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc) void LLGroupMgr::addGroup(LLGroupMgrGroupData* group_datap) { - if (mGroups.size() > MAX_CACHED_GROUPS) + while (mGroups.size() >= MAX_CACHED_GROUPS) { - // get rid of groups that aren't observed - for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end() && mGroups.size() > MAX_CACHED_GROUPS / 2; ) + // LRU: Remove the oldest un-observed group from cache until group size is small enough + + F32 oldest_access = LLFrameTimer::getTotalSeconds(); + group_map_t::iterator oldest_gi = mGroups.end(); + + for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi ) { observer_multimap_t::iterator oi = mObservers.find(gi->first); if (oi == mObservers.end()) { - // not observed - LLGroupMgrGroupData* unobserved_groupp = gi->second; - delete unobserved_groupp; - mGroups.erase(gi++); - } - else - { - ++gi; + if (gi->second + && (gi->second->getAccessTime() < oldest_access)) + { + oldest_access = gi->second->getAccessTime(); + oldest_gi = gi; + } } } + + if (oldest_gi != mGroups.end()) + { + delete oldest_gi->second; + mGroups.erase(oldest_gi); + } + else + { + // All groups must be currently open, none to remove. + // Just add the new group anyway, but get out of this loop as it + // will never drop below max_cached_groups. + break; + } } + mGroups[group_datap->getID()] = group_datap; } @@ -1473,6 +1506,7 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id) } } + void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id) { lldebugs << "LLGroupMgr::sendGroupRoleDataRequest" << llendl; @@ -1741,8 +1775,6 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, bool start_message = true; LLMessageSystem* msg = gMessageSystem; - - LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); if (!group_datap) return; @@ -1803,8 +1835,193 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, { gAgent.sendReliableMessage(); } + + group_datap->mMemberVersion.generate(); +} + + +// Responder class for capability group management +class GroupMemberDataResponder : public LLHTTPClient::Responder +{ +public: + GroupMemberDataResponder() {} + virtual ~GroupMemberDataResponder() {} + virtual void result(const LLSD& pContent); + virtual void error(U32 pStatus, const std::string& pReason); +private: + LLSD mMemberData; +}; + +void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason) +{ + LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL; } +void GroupMemberDataResponder::result(const LLSD& content) +{ + LLGroupMgr::processCapGroupMembersRequest(content); +} + + +// static +void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) +{ + // Have we requested the information already this frame? + if(mLastGroupMembersRequestFrame == gFrameCount) + return; + + LLViewerRegion* currentRegion = gAgent.getRegion(); + // Thank you FS:Ansariel! + if(!currentRegion) + { + LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL; + return; + } + + // Check to make sure we have our capabilities + if(!currentRegion->capabilitiesReceived()) + { + LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL; + return; + } + + // Get our capability + std::string cap_url = currentRegion->getCapability("GroupMemberData"); + + // Thank you FS:Ansariel! + if(cap_url.empty()) + { + LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability. Falling back to UDP fetch." << LL_ENDL; + sendGroupMembersRequest(group_id); + return; + } + + // Post to our service. Add a body containing the group_id. + LLSD body = LLSD::emptyMap(); + body["group_id"] = group_id; + + LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder(); + + // This could take a while to finish, timeout after 5 minutes. + LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 300); + + mLastGroupMembersRequestFrame = gFrameCount; +} + + +// static +void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) +{ + // Did we get anything in content? + if(!content.size()) + { + LL_DEBUGS("GrpMgr") << "No group member data received." << LL_ENDL; + return; + } + + // If we have no members, there's no reason to do anything else + S32 num_members = content["member_count"]; + if(num_members < 1) + return; + + LLUUID group_id = content["group_id"].asUUID(); + + LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); + if(!group_datap) + { + LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL; + return; + } + + group_datap->mMemberCount = num_members; + + LLSD member_list = content["members"]; + LLSD titles = content["titles"]; + LLSD defaults = content["defaults"]; + + std::string online_status; + std::string title; + S32 contribution; + U64 member_powers; + // If this is changed to a bool, make sure to change the LLGroupMemberData constructor + BOOL is_owner; + + // Compute this once, rather than every time. + U64 default_powers = llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16); + + LLSD::map_const_iterator member_iter_start = member_list.beginMap(); + LLSD::map_const_iterator member_iter_end = member_list.endMap(); + for( ; member_iter_start != member_iter_end; ++member_iter_start) + { + // Reset defaults + online_status = "unknown"; + title = titles[0].asString(); + contribution = 0; + member_powers = default_powers; + is_owner = false; + + const LLUUID member_id(member_iter_start->first); + LLSD member_info = member_iter_start->second; + + if(member_info.has("last_login")) + { + online_status = member_info["last_login"].asString(); + if(online_status == "Online") + online_status = LLTrans::getString("group_member_status_online"); + else + formatDateString(online_status); + } + + if(member_info.has("title")) + title = titles[member_info["title"].asInteger()].asString(); + + if(member_info.has("powers")) + member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16); + + if(member_info.has("donated_square_meters")) + contribution = member_info["donated_square_meters"]; + + if(member_info.has("owner")) + is_owner = true; + + LLGroupMemberData* data = new LLGroupMemberData(member_id, + contribution, + member_powers, + title, + online_status, + is_owner); + + group_datap->mMembers[member_id] = data; + } + + group_datap->mMemberVersion.generate(); + + // Technically, we have this data, but to prevent completely overhauling + // this entire system (it would be nice, but I don't have the time), + // I'm going to be dumb and just call services I most likely don't need + // with the thought being that the system might need it to be done. + // + // TODO: + // Refactor to reduce multiple calls for data we already have. + if(group_datap->mTitles.size() < 1) + LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); + + + group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberRequestID.setNull(); + // Make the role-member data request + if (group_datap->mPendingRoleMemberRequest) + { + group_datap->mPendingRoleMemberRequest = FALSE; + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id); + } + + group_datap->mChanged = TRUE; + LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); + +} + + void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id) { lldebugs << "LLGroupMgr::sendGroupRoleChanges" << llendl; diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index faf0531c10..d8c1ab7ef5 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -86,7 +86,7 @@ public: BOOL isInRole(const LLUUID& role_id) { return (mRolesList.find(role_id) != mRolesList.end()); } -protected: +private: LLUUID mID; S32 mContribution; U64 mAgentPowers; @@ -233,6 +233,11 @@ public: BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; } BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + F32 getAccessTime() const { return mAccessTime; } + void setAccessed(); + + const LLUUID& getMemberVersion() const { return mMemberVersion; } + public: typedef std::map<LLUUID,LLGroupMemberData*> member_list_t; typedef std::map<LLUUID,LLGroupRoleData*> role_list_t; @@ -280,6 +285,10 @@ private: BOOL mGroupPropertiesDataComplete; BOOL mPendingRoleMemberRequest; + F32 mAccessTime; + + // Generate a new ID every time mMembers + LLUUID mMemberVersion; }; struct LLRoleAction @@ -336,6 +345,10 @@ public: static void sendGroupMemberEjects(const LLUUID& group_id, uuid_vec_t& member_ids); + // BAKER + void sendCapGroupMembersRequest(const LLUUID& group_id); + static void processCapGroupMembersRequest(const LLSD& content); + void cancelGroupRoleChanges(const LLUUID& group_id); static void processGroupPropertiesReply(LLMessageSystem* msg, void** data); @@ -371,6 +384,8 @@ private: typedef std::set<LLParticularGroupObserver*> observer_set_t; typedef std::map<LLUUID,observer_set_t> observer_map_t; observer_map_t mParticularObservers; + + S32 mLastGroupMembersRequestFrame; }; diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp index e15862e2a4..197408b40e 100644 --- a/indra/newview/llhints.cpp +++ b/indra/newview/llhints.cpp @@ -171,12 +171,12 @@ LLHintPopup::LLHintPopup(const LLHintPopup::Params& p) } if (p.hint_image.isProvided()) { - buildFromFile("panel_hint_image.xml", NULL, p); + buildFromFile("panel_hint_image.xml", p); getChild<LLIconCtrl>("hint_image")->setImage(p.hint_image()); } else { - buildFromFile( "panel_hint.xml", NULL, p); + buildFromFile( "panel_hint.xml", p); } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b819100b9b..14a228df1c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -71,6 +71,9 @@ #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llwearablelist.h" +#include "lllandmarkactions.h" + +void copy_slurl_to_clipboard_callback_inv(const std::string& slurl); // Marketplace outbox current disabled #define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1 @@ -1399,6 +1402,29 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false); copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId()); } + else if ("copy_slurl" == action) + { + LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem()); + if(item) + { + LLUUID asset_id = item->getAssetUUID(); + LLLandmark* landmark = gLandmarkList.getAsset(asset_id); + if (landmark) + { + LLVector3d global_pos; + landmark->getGlobalPos(global_pos); + LLLandmarkActions::getSLURLfromPosGlobal(global_pos, ©_slurl_to_clipboard_callback_inv, true); + } + } + } +} + +void copy_slurl_to_clipboard_callback_inv(const std::string& slurl) +{ + gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl)); + LLSD args; + args["SLURL"] = slurl; + LLNotificationsUtil::add("CopySLURL", args); } void LLItemBridge::selectItem() @@ -2551,14 +2577,23 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer) LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(*current_folder, cat_array, item_array); - S32 item_count = item_array->count(); - S32 cat_count = cat_array->count(); - + S32 item_count(0); + if( item_array ) + { + item_count = item_array->count(); + } + + S32 cat_count(0); + if( cat_array ) + { + cat_count = cat_array->count(); + } + // Move to next if current folder empty if ((item_count == 0) && (cat_count == 0)) - { + { continue; - } + } uuid_vec_t ids; LLRightClickInventoryFetchObserver* outfit = NULL; @@ -4403,6 +4438,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } items.push_back(std::string("Landmark Separator")); + items.push_back(std::string("url_copy")); items.push_back(std::string("About Landmark")); } @@ -4411,6 +4447,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // info panel can be shown at a time. if ((flags & FIRST_SELECTED_ITEM) == 0) { + disabled_items.push_back(std::string("url_copy")); disabled_items.push_back(std::string("About Landmark")); } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index dc9e88d54d..118430efe1 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -197,6 +197,8 @@ public: const LLUUID& uuid) : LLInvFVBridge(inventory, root, uuid) {} + typedef boost::function<void(std::string& slurl)> slurl_callback_t; + virtual void performAction(LLInventoryModel* model, std::string action); virtual void selectItem(); virtual void restoreItem(); @@ -214,7 +216,6 @@ public: virtual BOOL isItemCopyable() const; virtual BOOL hasChildren() const { return FALSE; } virtual BOOL isUpToDate() const { return TRUE; } - /*virtual*/ void clearDisplayName() { mDisplayName.clear(); } LLViewerInventoryItem* getItem() const; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ab5b082915..e98d3f88a6 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -440,7 +440,7 @@ void show_item_original(const LLUUID& item_uuid) //sidetray inventory panel LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - bool reset_inventory_filter = !floater_inventory->isInVisibleChain(); + bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain(); LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(); if (!active_panel) @@ -460,37 +460,49 @@ void show_item_original(const LLUUID& item_uuid) } active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_NO); - if(reset_inventory_filter) + if(do_reset_inventory_filter) { - //inventory floater - bool floater_inventory_visible = false; + reset_inventory_filter(); + } +} + - LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); - for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) +void reset_inventory_filter() +{ + //inventory floater + bool floater_inventory_visible = false; + + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterInventory* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter); + if (floater_inventory) { - LLFloaterInventory* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter); - if (floater_inventory) - { - LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel(); + LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel(); - main_inventory->onFilterEdit(""); + main_inventory->onFilterEdit(""); - if(floater_inventory->getVisible()) - { - floater_inventory_visible = true; - } + if(floater_inventory->getVisible()) + { + floater_inventory_visible = true; } } - if(sidepanel_inventory && !floater_inventory_visible) + } + + if(!floater_inventory_visible) + { + LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + if (sidepanel_inventory) { LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); - - main_inventory->onFilterEdit(""); + if (main_inventory) + { + main_inventory->onFilterEdit(""); + } } } } - void open_outbox() { LLFloaterReg::showInstance("outbox"); diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 5cf9c528b0..909f7fd10b 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -56,6 +56,7 @@ void show_item_profile(const LLUUID& item_uuid); void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id); void show_item_original(const LLUUID& item_uuid); +void reset_inventory_filter(); void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 71dd963f28..05c81957c6 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -966,6 +966,7 @@ void LLInventoryPanel::doToSelected(const LLSD& userdata) void LLInventoryPanel::doCreate(const LLSD& userdata) { + reset_inventory_filter(); menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata); } diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp index 778693876e..cd6473921d 100644 --- a/indra/newview/llmachineid.cpp +++ b/indra/newview/llmachineid.cpp @@ -252,12 +252,20 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) if (has_static_unique_id) { memcpy ( unique_id, &static_unique_id, len); - LL_DEBUGS("AppInit") << "UniqueID: " << unique_id[0] << unique_id[1]<< unique_id[2] << unique_id[3] << unique_id[4] << unique_id [5] << LL_ENDL; + LL_DEBUGS("AppInit") << "UniqueID: 0x"; + // Code between here and LL_ENDL is not executed unless the LL_DEBUGS + // actually produces output + for (size_t i = 0; i < len; ++i) + { + // Copy each char to unsigned int to hexify. Sending an unsigned + // char to a std::ostream tries to represent it as a char, not + // what we want here. + unsigned byte = unique_id[i]; + LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte; + } + // Reset default output formatting to avoid nasty surprises! + LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL; return 1; } return 0; } - - - - diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 10608463b4..362308c176 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1755,6 +1755,11 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, shader->bind(); } + if (shader) + { + shader->bind(); + } + //draw volume/plane intersections { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 7650fe9229..99b4707158 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -564,32 +564,13 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type) // void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in ) { - std::string language = LLUI::getLanguage(); - std::string delim = gDirUtilp->getDirDelimiter(); - std::string filename; + std::string filename(gDirUtilp->add(subdir, filename_in)); + std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename); - filename += subdir; - filename += delim; - filename += filename_in; - - std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename); - - if (! gDirUtilp->fileExists(expanded_filename)) + if (expanded_filename.empty()) { - if (language != "en") - { - expanded_filename = gDirUtilp->findSkinnedFilename("html", "en", filename); - if (! gDirUtilp->fileExists(expanded_filename)) - { - llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; - return; - } - } - else - { - llwarns << "File " << subdir << delim << filename_in << "not found" << llendl; - return; - } + llwarns << "File " << filename << "not found" << llendl; + return; } if (ensureMediaSourceExists()) { @@ -597,7 +578,6 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str mMediaSource->setSize(mTextureWidth, mTextureHeight); mMediaSource->navigateTo(expanded_filename, "text/html", false); } - } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index bc7f522848..ba0a590910 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1097,11 +1097,13 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat mMeshHeader[mesh_id] = header; } + + LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. + //check for pending requests pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); if (iter != mPendingLOD.end()) { - LLMutexLock lock(mMutex); for (U32 i = 0; i < iter->second.size(); ++i) { LODRequest req(mesh_params, iter->second[i]); @@ -1796,7 +1798,12 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1851,6 +1858,12 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1905,6 +1918,11 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1959,6 +1977,12 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -2013,6 +2037,12 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + if (status < 200 || status > 400) { //llwarns diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index a7059eb519..54522bb7f6 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -44,6 +44,8 @@ #include "llmutelist.h" +#include "pipeline.h" + #include <boost/tokenizer.hpp> #include "lldispatcher.h" @@ -192,6 +194,23 @@ BOOL LLMuteList::isLinden(const std::string& name) const return last_name == "Linden"; } +static LLVOAvatar* find_avatar(const LLUUID& id) +{ + LLViewerObject *obj = gObjectList.findObject(id); + while (obj && obj->isAttachment()) + { + obj = (LLViewerObject *)obj->getParent(); + } + + if (obj && obj->isAvatar()) + { + return (LLVOAvatar*)obj; + } + else + { + return NULL; + } +} BOOL LLMuteList::add(const LLMute& mute, U32 flags) { @@ -288,6 +307,12 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID); } } + //mute local lights that are attached to the avatar + LLVOAvatar *avatarp = find_avatar(localmute.mID); + if (avatarp) + { + LLPipeline::removeMutedAVsLights(avatarp); + } return TRUE; } } diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 4e28d1f526..b0fbad33b0 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -68,7 +68,7 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p) {} // public -void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, +LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, BOOL enabled, const std::string& suffix) { //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; @@ -78,7 +78,7 @@ void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, item.enabled = enabled; item.target = INDIVIDUAL; - addNameItemRow(item, pos, suffix); + return addNameItemRow(item, pos, suffix); } // virtual, public @@ -204,7 +204,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; S32 column_index = getColumnIndexFromOffset(x); - LLScrollListItem* hit_item = hitItem(x, y); + LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y)); if (hit_item && column_index == mNameColumnIndex) { @@ -228,7 +228,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 ); // Should we show a group or an avatar inspector? - bool is_group = hit_item->getValue()["is_group"].asBoolean(); + bool is_group = hit_item->isGroup(); LLToolTip::Params params; params.background_visible( false ); @@ -271,10 +271,10 @@ void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPositi addNameItemRow(item, pos); } -void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) +LLScrollListItem* LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { item.target = INDIVIDUAL; - addNameItemRow(item, pos); + return addNameItemRow(item, pos); } LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata) @@ -293,19 +293,12 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( const std::string& suffix) { LLUUID id = name_item.value().asUUID(); - LLNameListItem* item = NULL; - - // Store item type so that we can invoke the proper inspector. - // *TODO Vadim: Is there a more proper way of storing additional item data? - { - LLNameListCtrl::NameItem item_p(name_item); - item_p.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP); - item = new LLNameListItem(item_p); - LLScrollListCtrl::addRow(item, item_p, pos); - } + LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP); if (!item) return NULL; + LLScrollListCtrl::addRow(item, name_item, pos); + // use supplied name by default std::string fullname = name_item.name; switch(name_item.target) @@ -336,7 +329,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( // ...schedule a callback LLAvatarNameCache::get(id, boost::bind(&LLNameListCtrl::onAvatarNameCache, - this, _1, _2)); + this, _1, _2, item->getHandle())); } break; } @@ -392,7 +385,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) } void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) + const LLAvatarName& av_name, + LLHandle<LLNameListItem> item) { std::string name; if (mShortNames) @@ -400,20 +394,17 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, else name = av_name.getCompleteName(); - item_list::iterator iter; - for (iter = getItemList().begin(); iter != getItemList().end(); iter++) + LLNameListItem* list_item = item.get(); + if (list_item && list_item->getUUID() == agent_id) { - LLScrollListItem* item = *iter; - if (item->getUUID() == agent_id) + LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); + if (cell) { - LLScrollListCell* cell = item->getColumn(mNameColumnIndex); - if (cell) - { - cell->setValue(name); - } + cell->setValue(name); + setNeedsSort(); } } - + dirtyColumns(); } @@ -431,3 +422,8 @@ void LLNameListCtrl::updateColumns() } } } + +void LLNameListCtrl::sortByName(BOOL ascending) +{ + sortByColumnIndex(mNameColumnIndex,ascending); +} diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index ca9956dc53..3ac0565761 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -33,6 +33,36 @@ class LLAvatarName; +/** + * LLNameListCtrl item + * + * We don't use LLScrollListItem to be able to override getUUID(), which is needed + * because the name list item value is not simply an UUID but a map (uuid, is_group). + */ +class LLNameListItem : public LLScrollListItem, public LLHandleProvider<LLNameListItem> +{ +public: + bool isGroup() const { return mIsGroup; } + void setIsGroup(bool is_group) { mIsGroup = is_group; } + +protected: + friend class LLNameListCtrl; + + LLNameListItem( const LLScrollListItem::Params& p ) + : LLScrollListItem(p), mIsGroup(false) + { + } + + LLNameListItem( const LLScrollListItem::Params& p, bool is_group ) + : LLScrollListItem(p), mIsGroup(is_group) + { + } + +private: + bool mIsGroup; +}; + + class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl> { @@ -85,9 +115,9 @@ protected: public: // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. - void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, + LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null); - void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); + LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null); @@ -110,12 +140,14 @@ public: void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; } + void sortByName(BOOL ascending); + /*virtual*/ void updateColumns(); /*virtual*/ void mouseOverHighlightNthItem( S32 index ); private: void showInspector(const LLUUID& avatar_id, bool is_group); - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle<LLNameListItem> item); private: S32 mNameColumnIndex; @@ -124,24 +156,5 @@ private: bool mShortNames; // display name only, no SLID }; -/** - * LLNameListCtrl item - * - * We don't use LLScrollListItem to be able to override getUUID(), which is needed - * because the name list item value is not simply an UUID but a map (uuid, is_group). - */ -class LLNameListItem : public LLScrollListItem -{ -public: - LLUUID getUUID() const { return getValue()["uuid"].asUUID(); } - -protected: - friend class LLNameListCtrl; - - LLNameListItem( const LLScrollListItem::Params& p ) - : LLScrollListItem(p) - { - } -}; #endif diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index f792f53ac5..3d8150eed3 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -97,6 +97,13 @@ bool LLNotificationManager::onNotification(const LLSD& notify) { LLSysHandler* handle = NULL; + // Don't bother if we're going down. + // Otherwise we might crash when trying to use handlers that are already dead. + if( LLApp::isExiting() ) + { + return false; + } + if (LLNotifications::destroyed()) return false; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index d58d6d536c..d42056ef9d 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -835,11 +835,11 @@ BOOL LLPanelEditWearable::isDirty() const BOOL isDirty = FALSE; if (mWearablePtr) { - if (mWearablePtr->isDirty() || - mWearableItem->getName().compare(mNameEditor->getText()) != 0) - { - isDirty = TRUE; - } + if (mWearablePtr->isDirty() || + ( mWearableItem && mNameEditor && mWearableItem->getName().compare(mNameEditor->getText()) != 0 )) + { + isDirty = TRUE; + } } return isDirty; } diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index b494c7d403..0e6f5b8924 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -33,7 +33,7 @@ class LLOfferInfo; -const S32 UPDATE_MEMBERS_PER_FRAME = 500; +const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005; // 5ms // Forward declares class LLPanelGroupTab; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index bc594b5517..993ffb7825 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -28,8 +28,10 @@ #include "llpanelgroupgeneral.h" -#include "lluictrlfactory.h" +#include "llavatarnamecache.h" #include "llagent.h" +#include "llsdparam.h" +#include "lluictrlfactory.h" #include "roles_constants.h" // UI elements @@ -313,11 +315,10 @@ void LLPanelGroupGeneral::activate() { LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID); LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); - if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } mFirstUse = FALSE; @@ -697,76 +698,45 @@ void LLPanelGroupGeneral::updateMembers() LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); - if (!mListVisibleMembers || !gdatap + if (!mListVisibleMembers + || !gdatap || !gdatap->isMemberDataComplete() || gdatap->mMembers.empty()) { return; } - static LLTimer all_timer; - static LLTimer sd_timer; - static LLTimer element_timer; + LLTimer update_time; + update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME); - all_timer.reset(); - S32 i = 0; + LLAvatarName av_name; - for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME; - ++mMemberProgress, ++i) + for( ; mMemberProgress != gdatap->mMembers.end() && !update_time.hasExpired(); + ++mMemberProgress) { - //llinfos << "Adding " << iter->first << ", " << iter->second->getTitle() << llendl; LLGroupMemberData* member = mMemberProgress->second; if (!member) { continue; } - // Owners show up in bold. - std::string style = "NORMAL"; - sd_timer.reset(); - LLSD row; - row["id"] = member->getID(); - - row["columns"][0]["column"] = "name"; - row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL"; - row["columns"][0]["font"]["style"] = style; - // value is filled in by name list control - - row["columns"][1]["column"] = "title"; - row["columns"][1]["value"] = member->getTitle(); - row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL"; - row["columns"][1]["font"]["style"] = style; - - std::string status = member->getOnlineStatus(); - - row["columns"][2]["column"] = "status"; - row["columns"][2]["value"] = status; - row["columns"][2]["font"]["name"] = "SANSSERIF_SMALL"; - row["columns"][2]["font"]["style"] = style; - sSDTime += sd_timer.getElapsedTimeF32(); - - element_timer.reset(); - LLScrollListItem* member_row = mListVisibleMembers->addElement(row); - - if ( member->isOwner() ) + if (LLAvatarNameCache::get(mMemberProgress->first, &av_name)) + { + addMember(mMemberProgress->second); + } + else { - LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0)); - if (name_textp) - name_textp->setFontStyle(LLFontGL::BOLD); + // If name is not cached, onNameCache() should be called when it is cached and add this member to list. + LLAvatarNameCache::get(mMemberProgress->first, + boost::bind(&LLPanelGroupGeneral::onNameCache, + this, gdatap->getMemberVersion(), member, _2)); } - sElementTime += element_timer.getElapsedTimeF32(); } - sAllTime += all_timer.getElapsedTimeF32(); - llinfos << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl; if (mMemberProgress == gdatap->mMembers.end()) { - llinfos << " member list completed." << llendl; + lldebugs << " member list completed." << llendl; mListVisibleMembers->setEnabled(TRUE); - - llinfos << "All Time: " << sAllTime << llendl; - llinfos << "SD Time: " << sSDTime << llendl; - llinfos << "Element Time: " << sElementTime << llendl; } else { @@ -775,6 +745,43 @@ void LLPanelGroupGeneral::updateMembers() } } +void LLPanelGroupGeneral::addMember(LLGroupMemberData* member) +{ + LLNameListCtrl::NameItem item_params; + item_params.value = member->getID(); + + LLScrollListCell::Params column; + item_params.columns.add().column("name").font.name("SANSSERIF_SMALL"); + + item_params.columns.add().column("title").value(member->getTitle()).font.name("SANSSERIF_SMALL"); + + item_params.columns.add().column("status").value(member->getOnlineStatus()).font.name("SANSSERIF_SMALL"); + + LLScrollListItem* member_row = mListVisibleMembers->addNameItemRow(item_params); + + if ( member->isOwner() ) + { + LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0)); + if (name_textp) + name_textp->setFontStyle(LLFontGL::BOLD); + } +} + +void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name) +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + + if (!gdatap + || !gdatap->isMemberDataComplete() + || gdatap->getMemberVersion() != update_id) + { + // Stale data + return; + } + + addMember(member); +} + void LLPanelGroupGeneral::updateChanged() { // List all the controls we want to check for changes... diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index 88c092c461..1b4e8e2645 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -38,6 +38,7 @@ class LLNameListCtrl; class LLCheckBoxCtrl; class LLComboBox; class LLSpinCtrl; +class LLAvatarName; class LLPanelGroupGeneral : public LLPanelGroupTab { @@ -62,6 +63,7 @@ public: virtual void setupCtrls (LLPanel* parent); + void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name); private: void reset(); @@ -75,7 +77,8 @@ private: static void onReceiveNotices(LLUICtrl* ctrl, void* data); static void openProfile(void* data); - S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*); + S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*); + void addMember(LLGroupMemberData* member); static bool joinDlgCB(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 7a15d93181..b9b347d4be 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -83,6 +83,7 @@ public: LLTextBox *mGroupName; std::string mOwnerWarning; std::string mAlreadyInGroup; + std::string mTooManySelected; bool mConfirmedOwnerInvite; void (*mCloseCallback)(void* data); @@ -185,6 +186,17 @@ void LLPanelGroupInvite::impl::submitInvitations() role_member_pairs[item->getUUID()] = role_id; } + const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap. + if (role_member_pairs.size() > MAX_GROUP_INVITES) + { + // Fail! + LLSD msg; + msg["MESSAGE"] = mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + (*mCloseCallback)(mCloseCallbackUserData); + return; + } + LLGroupMgr::getInstance()->sendGroupMemberInvites(mGroupID, role_member_pairs); if(already_in_group) @@ -455,10 +467,11 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) //so we need to do this additional search in avatar tracker, see EXT-4732 if (LLAvatarTracker::instance().isBuddy(agent_id)) { - if (!gCacheName->getFullName(agent_id, fullname)) + LLAvatarName av_name; + if (!LLAvatarNameCache::get(agent_id, &av_name)) { // actually it should happen, just in case - gCacheName->get(LLUUID(agent_id), false, boost::bind( + LLAvatarNameCache::get(LLUUID(agent_id), boost::bind( &LLPanelGroupInvite::addUserCallback, this, _1, _2)); // for this special case! //when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence @@ -467,7 +480,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) } else { - names.push_back(fullname); + names.push_back(av_name.getLegacyName()); } } } @@ -475,12 +488,12 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) mImplementation->addUsers(names, agent_ids); } -void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& full_name) +void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) { std::vector<std::string> names; uuid_vec_t agent_ids; agent_ids.push_back(id); - names.push_back(full_name); + names.push_back(av_name.getLegacyName()); mImplementation->addUsers(names, agent_ids); } @@ -558,8 +571,8 @@ void LLPanelGroupInvite::updateLists() if (!mPendingUpdate) { LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); - LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } mPendingUpdate = TRUE; } @@ -621,6 +634,7 @@ BOOL LLPanelGroupInvite::postBuild() mImplementation->mOwnerWarning = getString("confirm_invite_owner_str"); mImplementation->mAlreadyInGroup = getString("already_in_group"); + mImplementation->mTooManySelected = getString("invite_selection_too_large"); update(); diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h index a7bfd2226e..9f7b5ae9be 100644 --- a/indra/newview/llpanelgroupinvite.h +++ b/indra/newview/llpanelgroupinvite.h @@ -29,6 +29,8 @@ #include "llpanel.h" #include "lluuid.h" +class LLAvatarName; + class LLPanelGroupInvite : public LLPanel { @@ -40,7 +42,7 @@ public: /** * this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers(). */ - void addUserCallback(const LLUUID& id, const std::string& full_name); + void addUserCallback(const LLUUID& id, const LLAvatarName& av_name); void clear(); void update(); diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 363443646d..37755fb851 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -517,7 +517,7 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg) row["columns"][3]["column"] = "type"; row["columns"][3]["value"] = land_type; - row["columns"][3]["font"] = "SANSSERIFSMALL"; + row["columns"][3]["font"] = "SANSSERIF_SMALL"; // hidden is always last column row["columns"][4]["column"] = "hidden"; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index f825ee3215..ff106882f4 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -29,6 +29,7 @@ #include "llcheckboxctrl.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llbutton.h" #include "llfiltereditor.h" #include "llfloatergroupinvite.h" @@ -356,7 +357,7 @@ void LLPanelGroupRoles::activate() if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } // Check role data. @@ -744,7 +745,6 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab() mHasMatch(FALSE), mNumOwnerAdditions(0) { - mUdpateSessionID = LLUUID::null; } LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab() @@ -1426,13 +1426,20 @@ U64 LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges(const LLUUID& ag return GP_NO_POWERS; } - LLGroupMemberData* member_data = gdatap->mMembers[agent_id]; - if ( !member_data ) + LLGroupMgrGroupData::member_list_t::iterator iter = gdatap->mMembers.find(agent_id); + if ( iter == gdatap->mMembers.end() ) { llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No member data for member with UUID " << agent_id << llendl; return GP_NO_POWERS; } + LLGroupMemberData* member_data = (*iter).second; + if (!member_data) + { + llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- Null member data for member with UUID " << agent_id << llendl; + return GP_NO_POWERS; + } + //see if there are unsaved role changes for this agent role_change_data_map_t* role_change_datap = NULL; member_role_changes_map_t::iterator member = mMemberRoleChangeData.find(agent_id); @@ -1547,10 +1554,6 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) mMemberProgress = gdatap->mMembers.begin(); mPendingMemberUpdate = TRUE; mHasMatch = FALSE; - // Generate unique ID for current updateMembers()- see onNameCache for details. - // Using unique UUID is perhaps an overkill but this way we are perfectly safe - // from coincidences. - mUdpateSessionID.generate(); } else { @@ -1578,55 +1581,41 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) } } -void LLPanelGroupMembersSubTab::addMemberToList(LLUUID id, LLGroupMemberData* data) +void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data) { if (!data) return; LLUIString donated = getString("donation_area"); donated.setArg("[AREA]", llformat("%d", data->getContribution())); - LLSD row; - row["id"] = id; + LLNameListCtrl::NameItem item_params; + item_params.value = data->getID(); - row["columns"][0]["column"] = "name"; - // value is filled in by name list control - - row["columns"][1]["column"] = "donated"; - row["columns"][1]["value"] = donated.getString(); + item_params.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL"); - row["columns"][2]["column"] = "online"; - row["columns"][2]["value"] = data->getOnlineStatus(); - row["columns"][2]["font"] = "SANSSERIF_SMALL"; + item_params.columns.add().column("donated").value(donated.getString()) + .font.name("SANSSERIF_SMALL").style("NORMAL"); - mMembersList->addElement(row); + item_params.columns.add().column("online").value(data->getOnlineStatus()) + .font.name("SANSSERIF_SMALL").style("NORMAL"); + mMembersList->addNameItemRow(item_params); mHasMatch = TRUE; } -void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, const LLUUID& id) +void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name) { - // Update ID is used to determine whether member whose id is passed - // into onNameCache() was passed after current or previous user-initiated update. - // This is needed to avoid probable duplication of members in list after changing filter - // or adding of members of another group if gets for their names were called on - // previous update. If this id is from get() called from older update, - // we do nothing. - if (mUdpateSessionID != update_id) return; - LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); - if (!gdatap) + if (!gdatap + || gdatap->getMemberVersion() != update_id + || !member) { - llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl; return; } - std::string fullname; - gCacheName->getFullName(id, fullname); - - LLGroupMemberData* data; // trying to avoid unnecessary hash lookups - if (matchesSearchFilter(fullname) && ((data = gdatap->mMembers[id]) != NULL)) + if (matchesSearchFilter(av_name.getLegacyName())) { - addMemberToList(id, data); + addMemberToList(member); if(!mMembersList->getEnabled()) { mMembersList->setEnabled(TRUE); @@ -1665,27 +1654,29 @@ void LLPanelGroupMembersSubTab::updateMembers() LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); - - S32 i = 0; - for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME; - ++mMemberProgress, ++i) + + LLTimer update_time; + update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME); + + for( ; mMemberProgress != end && !update_time.hasExpired(); ++mMemberProgress) { if (!mMemberProgress->second) continue; + // Do filtering on name if it is already in the cache. - std::string fullname; - if (gCacheName->getFullName(mMemberProgress->first, fullname)) + LLAvatarName av_name; + if (LLAvatarNameCache::get(mMemberProgress->first, &av_name)) { - if (matchesSearchFilter(fullname)) + if (matchesSearchFilter(av_name.getLegacyName())) { - addMemberToList(mMemberProgress->first, mMemberProgress->second); + addMemberToList(mMemberProgress->second); } } else { // If name is not cached, onNameCache() should be called when it is cached and add this member to list. - gCacheName->get(mMemberProgress->first, FALSE, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, - this, mUdpateSessionID, _1)); + LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, + this, gdatap->getMemberVersion(), mMemberProgress->second, _2)); } } @@ -1987,7 +1978,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) if (!gdatap || !gdatap->isMemberDataComplete()) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (!gdatap || !gdatap->isRoleMemberDataComplete()) @@ -2580,7 +2571,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect() } else { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (gdatap->isRoleDataComplete()) @@ -2604,6 +2595,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect() LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); } } + void LLPanelGroupRoles::setGroupID(const LLUUID& id) { LLPanelGroupTab::setGroupID(id); diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index a55e264150..bead8bd85b 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -187,8 +187,8 @@ public: virtual void setGroupID(const LLUUID& id); - void addMemberToList(LLUUID id, LLGroupMemberData* data); - void onNameCache(const LLUUID& update_id, const LLUUID& id); + void addMemberToList(LLGroupMemberData* data); + void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name); protected: typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t; @@ -210,9 +210,6 @@ protected: BOOL mPendingMemberUpdate; BOOL mHasMatch; - // This id is generated after each user initiated member list update(opening Roles or changing filter) - LLUUID mUdpateSessionID; - member_role_changes_map_t mMemberRoleChangeData; U32 mNumOwnerAdditions; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 44ff62e290..bcb90bcb56 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llpanellogin.h" +#include "lllayoutstack.h" #include "indra_constants.h" // for key and mask constants #include "llfloaterreg.h" @@ -138,14 +139,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, mLogoImage = LLUI::getUIImage("startup_logo"); buildFromFile( "panel_login.xml"); - + reshape(rect.getWidth(), rect.getHeight()); - getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this); + LLLineEditor* password_edit(getChild<LLLineEditor>("password_edit")); + password_edit->setKeystrokeCallback(onPassKey, this); + // STEAM-14: When user presses Enter with this field in focus, initiate login + password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); // change z sort of clickable text to be behind buttons sendChildToBack(getChildView("forgot_password_text")); - + LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo"); updateLocationSelectorsVisibility(); // separate so that it can be called from preferences location_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); @@ -201,7 +205,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, childSetAction("connect_btn", onClickConnect, this); - getChild<LLPanel>("login")->setDefaultBtn("connect_btn"); + getChild<LLPanel>("links_login_panel")->setDefaultBtn("connect_btn"); std::string channel = LLVersionInfo::getChannel(); std::string version = llformat("%s (%d)", @@ -211,8 +215,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text"); forgot_password_text->setClickedCallback(onClickForgotPassword, NULL); - LLTextBox* create_new_account_text = getChild<LLTextBox>("create_new_account_text"); - create_new_account_text->setClickedCallback(onClickNewAccount, NULL); + childSetAction("create_new_account_btn", onClickNewAccount, NULL); LLTextBox* need_help_text = getChild<LLTextBox>("login_help"); need_help_text->setClickedCallback(onClickHelp, NULL); @@ -220,14 +223,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, // get the web browser control LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); web_browser->addObserver(this); - + reshapeBrowser(); loadLoginPage(); - + // Show last logged in user favorites in "Start at" combo. addUsersWithFavoritesToUsername(); - getChild<LLComboBox>("username_combo")->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this)); + LLComboBox* username_combo(getChild<LLComboBox>("username_combo")); + username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this)); + // STEAM-14: When user presses Enter with this field in focus, initiate login + username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); } void LLPanelLogin::addUsersWithFavoritesToUsername() @@ -636,12 +642,10 @@ void LLPanelLogin::updateLocationSelectorsVisibility() if (sInstance) { BOOL show_start = gSavedSettings.getBOOL("ShowStartLocation"); - sInstance->getChildView("start_location_combo")->setVisible(show_start); - sInstance->getChildView("start_location_text")->setVisible(show_start); + sInstance->getChild<LLLayoutPanel>("start_location_panel")->setVisible(show_start); BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid"); - LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo"); - server_choice_combo->setVisible( show_server ); + sInstance->getChild<LLLayoutPanel>("grid_panel")->setVisible(show_server); } } @@ -746,63 +750,48 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh) void LLPanelLogin::loadLoginPage() { if (!sInstance) return; - - std::ostringstream oStr; - std::string login_page = LLGridManager::getInstance()->getLoginPage(); + LLURI login_page = LLURI(LLGridManager::getInstance()->getLoginPage()); + LLSD params(login_page.queryMap()); - oStr << login_page; - - // Use the right delimeter depending on how LLURI parses the URL - LLURI login_page_uri = LLURI(login_page); - - std::string first_query_delimiter = "&"; - if (login_page_uri.queryMap().size() == 0) - { - first_query_delimiter = "?"; - } + LL_DEBUGS("AppInit") << "login_page: " << login_page << LL_ENDL; // Language - std::string language = LLUI::getLanguage(); - oStr << first_query_delimiter<<"lang=" << language; - + params["lang"] = LLUI::getLanguage(); + // First Login? if (gSavedSettings.getBOOL("FirstLoginThisInstall")) { - oStr << "&firstlogin=TRUE"; + params["firstlogin"] = "TRUE"; // not bool: server expects string TRUE } // Channel and Version - std::string version = llformat("%s (%d)", - LLVersionInfo::getShortVersion().c_str(), - LLVersionInfo::getBuild()); + params["version"] = llformat("%s (%d)", + LLVersionInfo::getShortVersion().c_str(), + LLVersionInfo::getBuild()); + params["channel"] = LLVersionInfo::getChannel(); - char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); - char* curl_version = curl_escape(version.c_str(), 0); + // Grid + params["grid"] = LLGridManager::getInstance()->getGridId(); - oStr << "&channel=" << curl_channel; - oStr << "&version=" << curl_version; + // add OS info + params["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple(); - curl_free(curl_channel); - curl_free(curl_version); + // sourceid + params["sourceid"] = gSavedSettings.getString("sourceid"); + + // Make an LLURI with this augmented info + LLURI login_uri(LLURI::buildHTTP(login_page.authority(), + login_page.path(), + params)); - // Grid - char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridId().c_str(), 0); - oStr << "&grid=" << curl_grid; - curl_free(curl_grid); - - // add OS info - char * os_info = curl_escape(LLAppViewer::instance()->getOSInfo().getOSStringSimple().c_str(), 0); - oStr << "&os=" << os_info; - curl_free(os_info); - gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid()); - + LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); - if (web_browser->getCurrentNavUrl() != oStr.str()) + if (web_browser->getCurrentNavUrl() != login_uri.asString()) { - LL_DEBUGS("AppInit")<<oStr.str()<<LL_ENDL; - web_browser->navigateTo( oStr.str(), "text/html" ); + LL_DEBUGS("AppInit") << "loading: " << login_uri << LL_ENDL; + web_browser->navigateTo( login_uri.asString(), "text/html" ); } } @@ -886,7 +875,7 @@ void LLPanelLogin::onClickNewAccount(void*) { if (sInstance) { - LLWeb::loadURLExternal(sInstance->getString("create_account_url")); + LLWeb::loadURLExternal(LLTrans::getString("create_account_url")); } } @@ -946,9 +935,11 @@ void LLPanelLogin::updateServer() // update the login panel links bool system_grid = LLGridManager::getInstance()->isSystemGrid(); - - sInstance->getChildView("create_new_account_text")->setVisible( system_grid); - sInstance->getChildView("forgot_password_text")->setVisible( system_grid); + + // Want to vanish not only create_new_account_btn, but also the + // title text over it, so turn on/off the whole layout_panel element. + sInstance->getChild<LLLayoutPanel>("links")->setVisible(system_grid); + sInstance->getChildView("forgot_password_text")->setVisible(system_grid); // grid changed so show new splash screen (possibly) loadLoginPage(); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index c11597f532..9f3273da2d 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -306,6 +306,7 @@ void LLPanelMainInventory::newWindow() void LLPanelMainInventory::doCreate(const LLSD& userdata) { + reset_inventory_filter(); menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata); } diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index c6b9aaae4b..9902d047e4 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -240,6 +240,7 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices ) mBaseCoords[i].clear(); mBaseNormals[i].clear(); mBaseBinormals[i].clear(); + mTexCoords[i].clear(); mWeights[i] = 0.f; } mNumVertices = numVertices; diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 18626e3273..04934b13f1 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -464,7 +464,9 @@ LLMultiPreview::LLMultiPreview() void LLMultiPreview::onOpen(const LLSD& key) { - LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel()); + if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) { frontmost_preview->loadAsset(); @@ -477,8 +479,13 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user) { if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()) { - LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); - if (frontmost_preview) frontmost_preview->userResized(); + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel()); + + if (frontmost_preview) + { + frontmost_preview->userResized(); + } } LLFloater::handleReshape(new_rect, by_user); } @@ -486,7 +493,9 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user) void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click) { - LLPreview* opened_preview = (LLPreview*)opened_floater; + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* opened_preview = dynamic_cast<LLPreview*>(opened_floater); + if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) { opened_preview->loadAsset(); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 88727bf59b..9c25e69db0 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -815,7 +815,7 @@ void LLScriptEdCore::onBtnDynamicHelp() if (!live_help_floater) { live_help_floater = new LLFloater(LLSD()); - live_help_floater->buildFromFile("floater_lsl_guide.xml", NULL); + live_help_floater->buildFromFile("floater_lsl_guide.xml"); LLFloater* parent = dynamic_cast<LLFloater*>(getParent()); llassert(parent); if (parent) diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index d340b304ca..d2280ea089 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -571,9 +571,13 @@ void LLScreenChannel::showToastsBottom() LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get()); - for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + // Use a local variable instead of mToastList. + // mToastList can be modified during recursive calls and then all iteratos will be invalidated. + std::vector<ToastElem> vToastList( mToastList ); + + for(it = vToastList.rbegin(); it != vToastList.rend(); ++it) { - if(it != mToastList.rbegin()) + if(it != vToastList.rbegin()) { LLToast* toast = (it-1)->getToast(); if (!toast) @@ -601,7 +605,7 @@ void LLScreenChannel::showToastsBottom() if(floater && floater->overlapsScreenChannel()) { - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { // move first toast above docked floater S32 shift = floater->getRect().getHeight(); @@ -624,7 +628,7 @@ void LLScreenChannel::showToastsBottom() if(!stop_showing_toasts) { - if( it != mToastList.rend()-1) + if( it != vToastList.rend()-1) { S32 toast_top = toast->getRect().mTop + gSavedSettings.getS32("ToastGap"); stop_showing_toasts = toast_top > getRect().mTop; @@ -632,7 +636,8 @@ void LLScreenChannel::showToastsBottom() } // at least one toast should be visible - if(it == mToastList.rbegin()) + + if(it == vToastList.rbegin()) { stop_showing_toasts = false; } @@ -655,10 +660,11 @@ void LLScreenChannel::showToastsBottom() } // Dismiss toasts we don't have space for (STORM-391). - if(it != mToastList.rend()) + if(it != vToastList.rend()) { mHiddenToastsNum = 0; - for(; it != mToastList.rend(); it++) + + for(; it != vToastList.rend(); it++) { LLToast* toast = it->getToast(); if (toast) @@ -714,9 +720,13 @@ void LLScreenChannel::showToastsTop() LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get()); - for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + // Use a local variable instead of mToastList. + // mToastList can be modified during recursive calls and then all iteratos will be invalidated. + std::vector<ToastElem> vToastList( mToastList ); + + for(it = vToastList.rbegin(); it != vToastList.rend(); ++it) { - if(it != mToastList.rbegin()) + if(it != vToastList.rbegin()) { LLToast* toast = (it-1)->getToast(); if (!toast) @@ -744,7 +754,7 @@ void LLScreenChannel::showToastsTop() if(floater && floater->overlapsScreenChannel()) { - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { // move first toast above docked floater S32 shift = -floater->getRect().getHeight(); @@ -767,7 +777,7 @@ void LLScreenChannel::showToastsTop() if(!stop_showing_toasts) { - if( it != mToastList.rend()-1) + if( it != vToastList.rend()-1) { S32 toast_bottom = toast->getRect().mBottom - gSavedSettings.getS32("ToastGap"); stop_showing_toasts = toast_bottom < channel_rect.mBottom; @@ -775,7 +785,7 @@ void LLScreenChannel::showToastsTop() } // at least one toast should be visible - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { stop_showing_toasts = false; } @@ -799,10 +809,12 @@ void LLScreenChannel::showToastsTop() // Dismiss toasts we don't have space for (STORM-391). std::vector<LLToast*> toasts_to_hide; - if(it != mToastList.rend()) + + if(it != vToastList.rend()) { mHiddenToastsNum = 0; - for(; it != mToastList.rend(); it++) + + for(; it != vToastList.rend(); it++) { LLToast* toast = it->getToast(); if (toast) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 3b52dd552f..c3c37141ed 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -390,7 +390,7 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, // don't include an avatar. LLViewerObject* root = obj; - while(!root->isAvatar() && root->getParent() && !root->isJointChild()) + while(!root->isAvatar() && root->getParent()) { LLViewerObject* parent = (LLViewerObject*)root->getParent(); if (parent->isAvatar()) @@ -684,7 +684,7 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s // don't include an avatar. LLViewerObject* root = object; - while(!root->isAvatar() && root->getParent() && !root->isJointChild()) + while(!root->isAvatar() && root->getParent()) { LLViewerObject* parent = (LLViewerObject*)root->getParent(); if (parent->isAvatar()) @@ -1397,7 +1397,7 @@ void LLSelectMgr::promoteSelectionToRoot() } LLViewerObject* parentp = object; - while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild())) + while(parentp->getParent() && !(parentp->isRootEdit())) { parentp = (LLViewerObject*)parentp->getParent(); } @@ -4474,8 +4474,7 @@ struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor virtual bool apply(LLViewerObject* object) { if ( object->permModify() && // preemptive permissions check - object->isRoot() && // don't send for child objects - !object->isJointChild()) + object->isRoot()) // don't send for child objects { object->setFlags( mFlags, mState); } @@ -6330,8 +6329,6 @@ void LLSelectMgr::updateSelectionCenter() // matches the root prim's (affecting the orientation of the manipulators). bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() ); - std::vector < LLViewerObject *> jointed_objects; - for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); iter != mSelectedObjects->end(); iter++) { @@ -6349,11 +6346,6 @@ void LLSelectMgr::updateSelectionCenter() } bbox.addBBoxAgent( object->getBoundingBoxAgent() ); - - if (object->isJointChild()) - { - jointed_objects.push_back(object); - } } LLVector3 bbox_center_agent = bbox.getCenterAgent(); @@ -6643,19 +6635,19 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) bool LLObjectSelection::is_root::operator()(LLSelectNode *node) { LLViewerObject* object = node->getObject(); - return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); + return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit()); } bool LLObjectSelection::is_valid_root::operator()(LLSelectNode *node) { LLViewerObject* object = node->getObject(); - return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); + return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit()); } bool LLObjectSelection::is_root_object::operator()(LLSelectNode *node) { LLViewerObject* object = node->getObject(); - return (object != NULL) && (object->isRootEdit() || object->isJointChild()); + return (object != NULL) && (object->isRootEdit()); } LLObjectSelection::LLObjectSelection() : diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 3bb8e60787..2083afdcf5 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3500,6 +3500,8 @@ void renderPhysicsShapes(LLSpatialGroup* group) LLViewerObject* object = drawable->getVObj(); if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) { + gGL.pushMatrix(); + gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix); //push face vertices for terrain for (S32 i = 0; i < drawable->getNumFaces(); ++i) { @@ -3521,6 +3523,7 @@ void renderPhysicsShapes(LLSpatialGroup* group) } } } + gGL.popMatrix(); } } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 218c35029e..3d1fd74ba6 100644..100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -362,6 +362,15 @@ bool idle_startup() if ( STATE_FIRST == LLStartUp::getStartupState() ) { + static bool first_call = true; + if (first_call) + { + // Other phases get handled when startup state changes, + // need to capture the initial state as well. + LLStartUp::getPhases().startPhase(LLStartUp::getStartupStateString()); + first_call = false; + } + gViewerWindow->showCursor(); gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT); @@ -721,12 +730,14 @@ bool idle_startup() if (STATE_LOGIN_SHOW == LLStartUp::getStartupState()) { - LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL; + LL_DEBUGS("AppInit") << "Initializing Window, show_connect_box = " + << show_connect_box << LL_ENDL; // if we've gone backwards in the login state machine, to this state where we show the UI // AND the debug setting to exit in this case is true, then go ahead and bail quickly if ( mLoginStatePastUI && gSavedSettings.getBOOL("QuitOnLoginActivated") ) { + LL_DEBUGS("AppInit") << "taking QuitOnLoginActivated exit" << LL_ENDL; // no requirement for notification here - just exit LLAppViewer::instance()->earlyExitNoNotify(); } @@ -739,6 +750,7 @@ bool idle_startup() // this startup phase more than once. if (gLoginMenuBarView == NULL) { + LL_DEBUGS("AppInit") << "initializing menu bar" << LL_ENDL; display_startup(); initialize_edit_menu(); initialize_spellcheck_menu(); @@ -749,11 +761,13 @@ bool idle_startup() if (show_connect_box) { + LL_DEBUGS("AppInit") << "show_connect_box on" << LL_ENDL; // 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. if (gUserCredential.isNull()) { + LL_DEBUGS("AppInit") << "loading credentials from gLoginHandler" << LL_ENDL; display_startup(); gUserCredential = gLoginHandler.initializeLoginInfo(); display_startup(); @@ -770,17 +784,28 @@ bool idle_startup() login_show(); display_startup(); // connect dialog is already shown, so fill in the names - if (gUserCredential.notNull()) - { - LLPanelLogin::setFields( gUserCredential, gRememberPassword); - } + if (gUserCredential.notNull()) + { + LLPanelLogin::setFields( gUserCredential, gRememberPassword); + } display_startup(); LLPanelLogin::giveFocus(); + if (gSavedSettings.getBOOL("FirstLoginThisInstall")) + { + LL_INFOS("AppInit") << "FirstLoginThisInstall, calling show_first_run_dialog()" << LL_ENDL; + show_first_run_dialog(); + } + else + { + LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL; + } + LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input } else { + LL_DEBUGS("AppInit") << "show_connect_box off, skipping to STATE_LOGIN_CLEANUP" << LL_ENDL; // skip directly to message template verification LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); } @@ -2704,9 +2729,10 @@ void LLStartUp::setStartupState( EStartupState state ) getStartupStateString() << " to " << startupStateToString(state) << LL_ENDL; - sPhases->stopPhase(getStartupStateString()); + getPhases().stopPhase(getStartupStateString()); gStartupState = state; - sPhases->startPhase(getStartupStateString()); + getPhases().startPhase(getStartupStateString()); + postStartupState(); } @@ -3281,11 +3307,8 @@ bool process_login_success_response() { // replace the default help URL format gSavedSettings.setString("HelpURLFormat",text); - - // don't fall back to Standalone's pre-connection static help - gSavedSettings.setBOOL("HelpUseLocal", false); } - + std::string home_location = response["home"]; if(!home_location.empty()) { diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 760e38890b..760e38890b 100644..100755 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 89240c982f..ff69c6e9fd 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -469,7 +469,7 @@ void LLStatusBar::onMouseEnterVolume() LLRect vol_btn_rect = volbtn->getRect(); LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect(); volume_pulldown_rect.setLeftTopAndSize(vol_btn_rect.mLeft - - (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth())/2, + (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth()), vol_btn_rect.mBottom, volume_pulldown_rect.getWidth(), volume_pulldown_rect.getHeight()); diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 0cb6c85012..2002647fef 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -242,7 +242,7 @@ LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) : LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent) { - buildFromFile( "panel_activeim_row.xml", NULL); + buildFromFile( "panel_activeim_row.xml"); // Choose which of the pre-created chiclets (IM/group) to use. // The other one gets hidden. @@ -356,7 +356,7 @@ LLIMWellWindow::ObjectRowPanel::ObjectRowPanel(const LLUUID& notification_id, bo : LLPanel() , mChiclet(NULL) { - buildFromFile( "panel_active_object_row.xml", NULL); + buildFromFile( "panel_active_object_row.xml"); initChiclet(notification_id); diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 8632890bbb..305f6fca0f 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -50,6 +50,8 @@ const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024; const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) +const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level +const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD; class LLTextureCacheWorker : public LLWorkerClass { @@ -283,9 +285,12 @@ public: LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id, U8* data, S32 datasize, S32 offset, S32 imagesize, // for writes + LLPointer<LLImageRaw> raw, S32 discardlevel, LLTextureCache::Responder* responder) : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), - mState(INIT) + mState(INIT), + mRawImage(raw), + mRawDiscardLevel(discardlevel) { } @@ -303,6 +308,8 @@ private: }; e_state mState; + LLPointer<LLImageRaw> mRawImage; + S32 mRawDiscardLevel; }; @@ -559,6 +566,11 @@ bool LLTextureCacheRemoteWorker::doWrite() if(idx < 0) { idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry. + if(idx >= 0) + { + //write to the fast cache. + llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)); + } } else { @@ -658,6 +670,7 @@ bool LLTextureCacheRemoteWorker::doWrite() // Nothing else to do at that point... done = true; } + mRawImage = NULL; // Clean up and exit return done; @@ -744,10 +757,14 @@ LLTextureCache::LLTextureCache(bool threaded) mWorkersMutex(NULL), mHeaderMutex(NULL), mListMutex(NULL), + mFastCacheMutex(NULL), mHeaderAPRFile(NULL), mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called. mTexturesSizeTotal(0), - mDoPurge(FALSE) + mDoPurge(FALSE), + mFastCachep(NULL), + mFastCachePoolp(NULL), + mFastCachePadBuffer(NULL) { } @@ -755,6 +772,9 @@ LLTextureCache::~LLTextureCache() { clearDeleteList() ; writeUpdatedEntries() ; + delete mFastCachep; + delete mFastCachePoolp; + FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer); } ////////////////////////////////////////////////////////////////////////////// @@ -879,15 +899,15 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id) ////////////////////////////////////////////////////////////////////////////// //static -const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB -F32 LLTextureCache::sHeaderCacheVersion = 1.4f; -U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE; +F32 LLTextureCache::sHeaderCacheVersion = 1.7f; +U32 LLTextureCache::sCacheMaxEntries = 1024 * 1024; //~1 million textures. S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit const char* entries_filename = "texture.entries"; const char* cache_filename = "texture.cache"; const char* old_textures_dirname = "textures"; //change the location of the texture cache to prevent from being deleted by old version viewers. const char* textures_dirname = "texturecache"; +const char* fast_cache_filename = "FastCache.cache"; void LLTextureCache::setDirNames(ELLPath location) { @@ -896,6 +916,7 @@ void LLTextureCache::setDirNames(ELLPath location) mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, entries_filename); mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, cache_filename); mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname); + mFastCacheFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename); } void LLTextureCache::purgeCache(ELLPath location) @@ -938,8 +959,8 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache { llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. - S64 header_size = (max_size * 2) / 10; - S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE; + S64 header_size = (max_size / 100) * 36; //0.36 * max_size + S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE); sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries)); header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE; max_size -= header_size; @@ -981,6 +1002,7 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. + openFastCache(true); return max_size; // unused cache space } @@ -1751,7 +1773,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri LLMutexLock lock(&mWorkersMutex); LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, NULL, size, offset, - 0, responder); + 0, NULL, 0, responder); handle_t handle = worker->read(); mReaders[handle] = worker; return handle; @@ -1789,6 +1811,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort) LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, + LLPointer<LLImageRaw> rawimage, S32 discardlevel, WriteResponder* responder) { if (mReadOnly) @@ -1807,12 +1830,174 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio LLMutexLock lock(&mWorkersMutex); LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, data, datasize, 0, - imagesize, responder); + imagesize, rawimage, discardlevel, responder); handle_t handle = worker->write(); mWriters[handle] = worker; return handle; } +//called in the main thread +LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& discardlevel) +{ + U32 offset; + { + LLMutexLock lock(&mHeaderMutex); + id_map_t::const_iterator iter = mHeaderIDMap.find(id); + if(iter == mHeaderIDMap.end()) + { + return NULL; //not in the cache + } + + offset = iter->second; + } + offset *= TEXTURE_FAST_CACHE_ENTRY_SIZE; + + U8* data; + S32 head[4]; + { + LLMutexLock lock(&mFastCacheMutex); + + openFastCache(); + + mFastCachep->seek(APR_SET, offset); + + if(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) != TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) + { + //cache corrupted or under thread race condition + closeFastCache(); + return NULL; + } + + S32 image_size = head[0] * head[1] * head[2]; + if(!image_size) //invalid + { + closeFastCache(); + return NULL; + } + discardlevel = head[3]; + + data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size); + if(mFastCachep->read(data, image_size) != image_size) + { + FREE_MEM(LLImageBase::getPrivatePool(), data); + closeFastCache(); + return NULL; + } + + closeFastCache(); + } + LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true); + + return raw; +} + +//return the fast cache location +bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel) +{ + //rescale image if needed + S32 w, h, c; + w = raw->getWidth(); + h = raw->getHeight(); + c = raw->getComponents(); + S32 i = 0 ; + + while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) + { + ++i ; + } + + if(i) + { + w >>= i; + h >>= i; + if(w * h *c > 0) //valid + { + LLPointer<LLImageRaw> newraw = new LLImageRaw(raw->getData(), raw->getWidth(), raw->getHeight(), raw->getComponents()); + newraw->scale(w, h) ; + raw = newraw; + + discardlevel += i ; + } + } + + //copy data + memcpy(mFastCachePadBuffer, &w, sizeof(S32)); + memcpy(mFastCachePadBuffer + sizeof(S32), &h, sizeof(S32)); + memcpy(mFastCachePadBuffer + sizeof(S32) * 2, &c, sizeof(S32)); + memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32)); + if(w * h * c > 0) //valid + { + memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), w * h * c); + } + S32 offset = id * TEXTURE_FAST_CACHE_ENTRY_SIZE; + + { + LLMutexLock lock(&mFastCacheMutex); + + openFastCache(); + + mFastCachep->seek(APR_SET, offset); + + //no need to do this assertion check. When it fails, let it fail quietly. + //this failure could happen because other viewer removes the fast cache file when clearing cache. + //--> llassert_always(mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE) == TEXTURE_FAST_CACHE_ENTRY_SIZE); + mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE); + + closeFastCache(true); + } + + return true; +} + +void LLTextureCache::openFastCache(bool first_time) +{ + if(!mFastCachep) + { + if(first_time) + { + if(!mFastCachePadBuffer) + { + mFastCachePadBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_FAST_CACHE_ENTRY_SIZE); + } + mFastCachePoolp = new LLVolatileAPRPool(); + if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp)) + { + mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; + } + else + { + mFastCachep = new LLAPRFile(mFastCacheFileName, APR_CREATE|APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; + } + } + else + { + mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; + } + + mFastCacheTimer.reset(); + } + return; +} + +void LLTextureCache::closeFastCache(bool forced) +{ + static const F32 timeout = 10.f ; //seconds + + if(!mFastCachep) + { + return ; + } + + if(!forced && mFastCacheTimer.getElapsedTimeF32() < timeout) + { + return ; + } + + delete mFastCachep; + mFastCachep = NULL; + return; +} + bool LLTextureCache::writeComplete(handle_t handle, bool abort) { lockWorkers(); diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index dd0cc9b4bd..e3fc957fd2 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -36,6 +36,7 @@ class LLImageFormatted; class LLTextureCacheWorker; +class LLImageRaw; class LLTextureCache : public LLWorkerThread { @@ -113,8 +114,9 @@ public: handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size, ReadResponder* responder); bool readComplete(handle_t handle, bool abort); - handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, + handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel, WriteResponder* responder); + LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel); bool writeComplete(handle_t handle, bool abort = false); void prioritizeWrite(handle_t handle); @@ -171,12 +173,18 @@ private: void lockHeaders() { mHeaderMutex.lock(); } void unlockHeaders() { mHeaderMutex.unlock(); } + void openFastCache(bool first_time = false); + void closeFastCache(bool forced = false); + bool writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel); + private: // Internal LLMutex mWorkersMutex; LLMutex mHeaderMutex; LLMutex mListMutex; + LLMutex mFastCacheMutex; LLAPRFile* mHeaderAPRFile; + LLVolatileAPRPool* mFastCachePoolp; typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t; handle_map_t mReaders; @@ -193,12 +201,17 @@ private: // HEADERS (Include first mip) std::string mHeaderEntriesFileName; std::string mHeaderDataFileName; + std::string mFastCacheFileName; EntriesInfo mHeaderEntriesInfo; std::set<S32> mFreeList; // deleted entries std::set<LLUUID> mLRU; - typedef std::map<LLUUID,S32> id_map_t; + typedef std::map<LLUUID, S32> id_map_t; id_map_t mHeaderIDMap; + LLAPRFile* mFastCachep; + LLFrameTimer mFastCacheTimer; + U8* mFastCachePadBuffer; + // BODIES (TEXTURES minus headers) std::string mTexturesDirName; typedef std::map<LLUUID,S32> size_map_t; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index a5eebf6c77..a2854dd6d8 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,12 +28,12 @@ #include <iostream> #include <map> +#include <algorithm> #include "llstl.h" #include "lltexturefetch.h" -#include "llcurl.h" #include "lldir.h" #include "llhttpclient.h" #include "llhttpstatuscodes.h" @@ -54,28 +54,214 @@ #include "llworld.h" #include "llsdutil.h" #include "llstartup.h" -#include "llviewerstats.h" +#include "llsdserialize.h" + +#include "httprequest.h" +#include "httphandler.h" +#include "httpresponse.h" +#include "bufferarray.h" +#include "bufferstream.h" bool LLTextureFetchDebugger::sDebuggerEnabled = false ; LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128); LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); + +////////////////////////////////////////////////////////////////////////////// +// +// Introduction +// +// This is an attempt to document what's going on in here after-the-fact. +// It's a sincere attempt to be accurate but there will be mistakes. +// +// +// Purpose +// +// What is this module trying to do? It accepts requests to load textures +// at a given priority and discard level and notifies the caller when done +// (successfully or not). Additional constraints are: +// +// * Support a local texture cache. Don't hit network when possible +// to avoid it. +// * Use UDP or HTTP as directed or as fallback. HTTP is tried when +// not disabled and a URL is available. UDP when a URL isn't +// available or HTTP attempts fail. +// * Asynchronous (using threads). Main thread is not to be blocked or +// burdened. +// * High concurrency. Many requests need to be in-flight and at various +// stages of completion. +// * Tolerate frequent re-prioritizations of requests. Priority is +// a reflection of a camera's viewpoint and as that viewpoint changes, +// objects and textures become more and less relevant and that is +// expressed at this level by priority changes and request cancelations. +// +// The caller interfaces that fall out of the above and shape the +// implementation are: +// * createRequest - Load j2c image via UDP or HTTP at given discard level and priority +// * deleteRequest - Request removal of prior request +// * getRequestFinished - Test if request is finished returning data to caller +// * updateRequestPriority - Change priority of existing request +// * getFetchState - Retrieve progress on existing request +// +// Everything else in here is mostly plumbing, metrics and debug. +// +// +// The Work Queue +// +// The two central classes are LLTextureFetch and LLTextureFetchWorker. +// LLTextureFetch combines threading with a priority queue of work +// requests. The priority queue is sorted by a U32 priority derived +// from the F32 priority in the APIs. The *only* work request that +// receives service time by this thread is the highest priority +// request. All others wait until it is complete or a dynamic priority +// change has re-ordered work. +// +// LLTextureFetchWorker implements the work request and is 1:1 with +// texture fetch requests. Embedded in each is a state machine that +// walks it through the cache, HTTP, UDP, image decode and retry +// steps of texture acquisition. +// +// +// Threads +// +// Several threads are actively invoking code in this module. They +// include: +// +// 1. Tmain Main thread of execution +// 2. Ttf LLTextureFetch's worker thread provided by LLQueuedThread +// 3. Tcurl LLCurl's worker thread (should disappear over time) +// 4. Ttc LLTextureCache's worker thread +// 5. Tid Image decoder's worker thread +// 6. Thl HTTP library's worker thread +// +// +// Mutexes/Condition Variables +// +// 1. Mt Mutex defined for LLThread's condition variable (base class of +// LLTextureFetch) +// 2. Ct Condition variable for LLThread and used by lock/unlockData(). +// 3. Mwtd Special LLWorkerThread mutex used for request deletion +// operations (base class of LLTextureFetch) +// 4. Mfq LLTextureFetch's mutex covering request and command queue +// data. +// 5. Mfnq LLTextureFetch's mutex covering udp and http request +// queue data. +// 6. Mwc Mutex covering LLWorkerClass's members (base class of +// LLTextureFetchWorker). One per request. +// 7. Mw LLTextureFetchWorker's mutex. One per request. +// +// +// Lock Ordering Rules +// +// Not an exhaustive list but shows the order of lock acquisition +// needed to prevent deadlocks. 'A < B' means acquire 'A' before +// acquiring 'B'. +// +// 1. Mw < Mfnq +// (there are many more...) +// +// +// Method and Member Definitions +// +// With the above, we'll try to document what threads can call what +// methods (using T* for any), what locks must be held on entry and +// are taken out during execution and what data is covered by which +// lock (if any). This latter category will be especially prone to +// error so be skeptical. +// +// A line like: "// Locks: M<xxx>" indicates a method that must +// be invoked by a caller holding the 'M<xxx>' lock. Similarly, +// "// Threads: T<xxx>" means that a caller should be running in +// the indicated thread. +// +// For data members, a trailing comment like "// M<xxx>" means that +// the data member is covered by the specified lock. Absence of a +// comment can mean the member is unlocked or that I didn't bother +// to do the archaeology. In the case of LLTextureFetchWorker, +// most data members added by the leaf class are actually covered +// by the Mw lock. You may also see "// T<xxx>" which means that +// the member's usage is restricted to one thread (except for +// perhaps construction and destruction) and so explicit locking +// isn't used. +// +// In code, a trailing comment like "// [-+]M<xxx>" indicates a +// lock acquision or release point. +// +// +// Worker Lifecycle +// +// The threading and responder model makes it very likely that +// other components are holding on to a pointer to a worker request. +// So, uncoordinated deletions of requests is a guarantee of memory +// corruption in a short time. So destroying a request involves +// invocations's of LLQueuedThread/LLWorkerThread's abort/stop +// logic that removes workers and puts them ona delete queue for +// 2-phase destruction. That second phase is deferrable by calls +// to deleteOK() which only allow final destruction (via dtor) +// once deleteOK has determined that the request is in a safe +// state. +// +// +// Worker State Machine +// +// (ASCII art needed) +// +// +// Priority Scheme +// +// [PRIORITY_LOW, PRIORITY_NORMAL) - for WAIT_HTTP_RESOURCE state +// and other wait states +// [PRIORITY_HIGH, PRIORITY_URGENT) - External event delivered, +// rapidly transitioning through states, +// no waiting allowed +// +// By itself, the above work queue model would fail the concurrency +// and liveness requirements of the interface. A high priority +// request could find itself on the head and stalled for external +// reasons (see VWR-28996). So a few additional constraints are +// required to keep things running: +// * Anything that can make forward progress must be kept at a +// higher priority than anything that can't. +// * On completion of external events, the associated request +// needs to be elevated beyond the normal range to handle +// any data delivery and release any external resource. +// +// This effort is made to keep higher-priority entities moving +// forward in their state machines at every possible step of +// processing. It's not entirely proven that this produces the +// experiencial benefits promised. +// + + +////////////////////////////////////////////////////////////////////////////// + +// Tuning/Parameterization Constants + +static const S32 HTTP_REQUESTS_IN_QUEUE_HIGH_WATER = 40; // Maximum requests to have active in HTTP +static const S32 HTTP_REQUESTS_IN_QUEUE_LOW_WATER = 20; // Active level at which to refill + + ////////////////////////////////////////////////////////////////////////////// -class LLTextureFetchWorker : public LLWorkerClass + +class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler + { friend class LLTextureFetch; - friend class HTTPGetResponder; friend class LLTextureFetchDebugger; private: class CacheReadResponder : public LLTextureCache::ReadResponder { public: + + // Threads: Ttf CacheReadResponder(LLTextureFetch* fetcher, const LLUUID& id, LLImageFormatted* image) : mFetcher(fetcher), mID(id) { setImage(image); } + + // Threads: Ttc virtual void completed(bool success) { LLTextureFetchWorker* worker = mFetcher->getWorker(mID); @@ -92,10 +278,14 @@ private: class CacheWriteResponder : public LLTextureCache::WriteResponder { public: + + // Threads: Ttf CacheWriteResponder(LLTextureFetch* fetcher, const LLUUID& id) : mFetcher(fetcher), mID(id) { } + + // Threads: Ttc virtual void completed(bool success) { LLTextureFetchWorker* worker = mFetcher->getWorker(mID); @@ -112,10 +302,14 @@ private: class DecodeResponder : public LLImageDecodeThread::Responder { public: + + // Threads: Ttf DecodeResponder(LLTextureFetch* fetcher, const LLUUID& id, LLTextureFetchWorker* worker) : mFetcher(fetcher), mID(id), mWorker(worker) { } + + // Threads: Tid virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) { LLTextureFetchWorker* worker = mFetcher->getWorker(mID); @@ -148,22 +342,35 @@ private: }; public: + + // Threads: Ttf /*virtual*/ bool doWork(S32 param); // Called from LLWorkerThread::processRequest() + + // Threads: Ttf /*virtual*/ void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD) - /*virtual*/ bool deleteOK(); // called from update() (WORK THREAD) + + // Threads: Tmain + /*virtual*/ bool deleteOK(); // called from update() ~LLTextureFetchWorker(); - // void relese() { --mActiveCount; } - S32 callbackHttpGet(const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer, - bool partial, bool success); + // Threads: Ttf + // Locks: Mw + S32 callbackHttpGet(LLCore::HttpResponse * response, + bool partial, bool success); + + // Threads: Ttc void callbackCacheRead(bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal); + + // Threads: Ttc void callbackCacheWrite(bool success); + + // Threads: Tid void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux); - void setGetStatus(U32 status, const std::string& reason) + // Threads: T* + void setGetStatus(LLCore::HttpStatus status, const std::string& reason) { LLMutexLock lock(&mWorkMutex); @@ -175,33 +382,93 @@ public: bool getCanUseHTTP() const { return mCanUseHTTP; } LLTextureFetch & getFetcher() { return *mFetcher; } + + // Inherited from LLCore::HttpHandler + // Threads: Ttf + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); protected: LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 discard, S32 size); private: + + // Threads: Tmain /*virtual*/ void startWork(S32 param); // called from addWork() (MAIN THREAD) + + // Threads: Tmain /*virtual*/ void endWork(S32 param, bool aborted); // called from doWork() (MAIN THREAD) + // Locks: Mw void resetFormattedData(); + // Locks: Mw void setImagePriority(F32 priority); + + // Locks: Mw (ctor invokes without lock) void setDesiredDiscard(S32 discard, S32 size); + + // Threads: T* + // Locks: Mw bool insertPacket(S32 index, U8* data, S32 size); + + // Locks: Mw void clearPackets(); + + // Locks: Mw void setupPacketData(); + + // Locks: Mw (ctor invokes without lock) U32 calcWorkPriority(); + + // Locks: Mw void removeFromCache(); + + // Threads: Ttf + // Locks: Mw bool processSimulatorPackets(); + + // Threads: Ttf bool writeToCacheComplete(); + // Threads: Ttf + void recordTextureStart(bool is_http); + + // Threads: Ttf + void recordTextureDone(bool is_http); + void lockWorkMutex() { mWorkMutex.lock(); } void unlockWorkMutex() { mWorkMutex.unlock(); } + // Threads: Ttf + // Locks: Mw + bool acquireHttpSemaphore() + { + llassert(! mHttpHasResource); + if (mFetcher->mHttpSemaphore <= 0) + { + return false; + } + mHttpHasResource = true; + mFetcher->mHttpSemaphore--; + return true; + } + + // Threads: Ttf + // Locks: Mw + void releaseHttpSemaphore() + { + llassert(mHttpHasResource); + mHttpHasResource = false; + mFetcher->mHttpSemaphore++; + } + private: enum e_state // mState { + // *NOTE: Do not change the order/value of state variables, some code + // depends upon specific ordering/adjacency. + // NOTE: Affects LLTextureBar::draw in lltextureview.cpp (debug hack) INVALID = 0, INIT, @@ -209,8 +476,10 @@ private: CACHE_POST, LOAD_FROM_NETWORK, LOAD_FROM_SIMULATOR, - SEND_HTTP_REQ, - WAIT_HTTP_REQ, + WAIT_HTTP_RESOURCE, // Waiting for HTTP resources + WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources + SEND_HTTP_REQ, // Commit to sending as HTTP + WAIT_HTTP_REQ, // Request sent, wait for completion DECODE_IMAGE, DECODE_IMAGE_UPDATE, WRITE_TO_CACHE, @@ -254,9 +523,8 @@ private: F32 mCacheReadTime; LLTextureCache::handle_t mCacheReadHandle; LLTextureCache::handle_t mCacheWriteHandle; - U8* mBuffer; - S32 mBufferSize; S32 mRequestedSize; + S32 mRequestedOffset; S32 mDesiredSize; S32 mFileSize; S32 mCachedSize; @@ -271,10 +539,9 @@ private: BOOL mInCache; bool mCanUseHTTP ; bool mCanUseNET ; //can get from asset server. - S32 mHTTPFailCount; S32 mRetryAttempt; S32 mActiveCount; - U32 mGetStatus; + LLCore::HttpStatus mGetStatus; std::string mGetReason; // Work Data @@ -294,105 +561,19 @@ private: U8 mImageCodec; LLViewerAssetStats::duration_t mMetricsStartTime; -}; - -////////////////////////////////////////////////////////////////////////////// -class HTTPGetResponder : public LLCurl::Responder -{ - LOG_CLASS(HTTPGetResponder); -public: - HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir) - : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir) - { - } - ~HTTPGetResponder() - { - } - - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog"); - static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator"); - static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ; - - if (log_to_viewer_log || log_to_sim) - { - mFetcher->mTextureInfo.setRequestStartTime(mID, mStartTime); - U64 timeNow = LLTimer::getTotalTime(); - mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP); - mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize); - mFetcher->mTextureInfo.setRequestOffset(mID, mOffset); - mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow); - } - - lldebugs << "HTTP COMPLETE: " << mID << llendl; - LLTextureFetchWorker* worker = mFetcher->getWorker(mID); - if (worker) - { - bool success = false; - bool partial = false; - if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES) - { - success = true; - if (HTTP_PARTIAL_CONTENT == status) // partial information - { - partial = true; - } - } - - if (!success) - { - worker->setGetStatus(status, reason); -// llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl; - } - - S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success); - - if(log_texture_traffic && data_size > 0) - { - LLViewerTexture* tex = LLViewerTextureManager::findTexture(mID) ; - if(tex) - { - gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ; - } - } - - mFetcher->removeFromHTTPQueue(mID, data_size); - - if (worker->mMetricsStartTime) - { - LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, - true, - LLImageBase::TYPE_AVATAR_BAKE == worker->mType, - LLViewerAssetStatsFF::get_timestamp() - worker->mMetricsStartTime); - worker->mMetricsStartTime = 0; - } - LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, - true, - LLImageBase::TYPE_AVATAR_BAKE == worker->mType); - } - else - { - mFetcher->removeFromHTTPQueue(mID); - llwarns << "Worker not found: " << mID << llendl; - } - } - - virtual bool followRedir() - { - return mFollowRedir; - } - -private: - LLTextureFetch* mFetcher; - LLUUID mID; - U64 mStartTime; - S32 mRequestedSize; - U32 mOffset; - bool mFollowRedir; + LLCore::HttpHandle mHttpHandle; // Handle of any active request + LLCore::BufferArray * mHttpBufferArray; // Refcounted pointer to response data + int mHttpPolicyClass; + bool mHttpActive; // Active request to http library + unsigned int mHttpReplySize; // Actual received data size + unsigned int mHttpReplyOffset; // Actual received data offset + bool mHttpHasResource; // Counts against Fetcher's mHttpSemaphore + + // State history + U32 mCacheReadCount; + U32 mCacheWriteCount; + U32 mResourceWaitCount; // Requests entering WAIT_HTTP_RESOURCE2 }; ////////////////////////////////////////////////////////////////////////////// @@ -628,13 +809,15 @@ const char* LLTextureFetchWorker::sStateDescs[] = { "CACHE_POST", "LOAD_FROM_NETWORK", "LOAD_FROM_SIMULATOR", + "WAIT_HTTP_RESOURCE", + "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", "WAIT_HTTP_REQ", "DECODE_IMAGE", "DECODE_IMAGE_UPDATE", "WRITE_TO_CACHE", "WAIT_ON_WRITE", - "DONE", + "DONE" }; // static @@ -650,6 +833,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, S32 discard, // Desired discard S32 size) // Desired size : LLWorkerClass(fetcher, "TextureFetch"), + LLCore::HttpHandler(), mState(INIT), mWriteToCacheState(NOT_WRITE), mFetcher(fetcher), @@ -667,9 +851,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mCacheReadTime(0.f), mCacheReadHandle(LLTextureCache::nullHandle()), mCacheWriteHandle(LLTextureCache::nullHandle()), - mBuffer(NULL), - mBufferSize(0), mRequestedSize(0), + mRequestedOffset(0), mDesiredSize(TEXTURE_CACHE_ENTRY_SIZE), mFileSize(0), mCachedSize(0), @@ -683,19 +866,27 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mInLocalCache(FALSE), mInCache(FALSE), mCanUseHTTP(true), - mHTTPFailCount(0), mRetryAttempt(0), mActiveCount(0), - mGetStatus(0), mWorkMutex(NULL), mFirstPacket(0), mLastPacket(-1), mTotalPackets(0), mImageCodec(IMG_CODEC_INVALID), - mMetricsStartTime(0) + mMetricsStartTime(0), + mHttpHandle(LLCORE_HTTP_HANDLE_INVALID), + mHttpBufferArray(NULL), + mHttpPolicyClass(mFetcher->mHttpPolicyClass), + mHttpActive(false), + mHttpReplySize(0U), + mHttpReplyOffset(0U), + mHttpHasResource(false), + mCacheReadCount(0U), + mCacheWriteCount(0U), + mResourceWaitCount(0U) { mCanUseNET = mUrl.empty() ; - + calcWorkPriority(); mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; // llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl; @@ -714,7 +905,20 @@ LLTextureFetchWorker::~LLTextureFetchWorker() // << " Requested=" << mRequestedDiscard // << " Desired=" << mDesiredDiscard << llendl; llassert_always(!haveWork()); - lockWorkMutex(); + + lockWorkMutex(); // +Mw (should be useless) + if (mHttpHasResource) + { + // Last-chance catchall to recover the resource. Using an + // atomic datatype solely because this can be running in + // another thread. + releaseHttpSemaphore(); + } + if (mHttpActive) + { + // Issue a cancel on a live request... + mFetcher->getHttpRequest().requestCancel(mHttpHandle, NULL); + } if (mCacheReadHandle != LLTextureCache::nullHandle() && mFetcher->mTextureCache) { mFetcher->mTextureCache->readComplete(mCacheReadHandle, true); @@ -725,10 +929,18 @@ LLTextureFetchWorker::~LLTextureFetchWorker() } mFormattedImage = NULL; clearPackets(); - unlockWorkMutex(); - mFetcher->removeFromHTTPQueue(mID); + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } + unlockWorkMutex(); // -Mw + mFetcher->removeFromHTTPQueue(mID, 0); + mFetcher->removeHttpWaiter(mID); + mFetcher->updateStateStats(mCacheReadCount, mCacheWriteCount, mResourceWaitCount); } +// Locks: Mw void LLTextureFetchWorker::clearPackets() { for_each(mPackets.begin(), mPackets.end(), DeletePointer()); @@ -738,6 +950,7 @@ void LLTextureFetchWorker::clearPackets() mFirstPacket = 0; } +// Locks: Mw void LLTextureFetchWorker::setupPacketData() { S32 data_size = 0; @@ -770,6 +983,7 @@ void LLTextureFetchWorker::setupPacketData() } } +// Locks: Mw (ctor invokes without lock) U32 LLTextureFetchWorker::calcWorkPriority() { //llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority()); @@ -779,7 +993,7 @@ U32 LLTextureFetchWorker::calcWorkPriority() return mWorkPriority; } -// mWorkMutex is locked +// Locks: Mw (ctor invokes without lock) void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) { bool prioritize = false; @@ -815,6 +1029,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) } } +// Locks: Mw void LLTextureFetchWorker::setImagePriority(F32 priority) { // llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority()); @@ -828,32 +1043,37 @@ void LLTextureFetchWorker::setImagePriority(F32 priority) } } +// Locks: Mw void LLTextureFetchWorker::resetFormattedData() { - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); - mBuffer = NULL; - mBufferSize = 0; + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } if (mFormattedImage.notNull()) { mFormattedImage->deleteData(); } + mHttpReplySize = 0; + mHttpReplyOffset = 0; mHaveAllData = FALSE; } -// Called from MAIN thread +// Threads: Tmain void LLTextureFetchWorker::startWork(S32 param) { llassert(mFormattedImage.isNull()); } -#include "llviewertexturelist.h" // debug - -// Called from LLWorkerThread::processRequest() +// Threads: Ttf bool LLTextureFetchWorker::doWork(S32 param) { - static const F32 FETCHING_TIMEOUT = 120.f;//seconds - - LLMutexLock lock(&mWorkMutex); + static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND); // 404 + static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE); // 503 + static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); // 416; + + LLMutexLock lock(&mWorkMutex); // +Mw if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) { @@ -897,15 +1117,20 @@ bool LLTextureFetchWorker::doWork(S32 param) mLoadedDiscard = -1; mDecodedDiscard = -1; mRequestedSize = 0; + mRequestedOffset = 0; mFileSize = 0; mCachedSize = 0; mLoaded = FALSE; mSentRequest = UNSENT; mDecoded = FALSE; mWritten = FALSE; - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); - mBuffer = NULL; - mBufferSize = 0; + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } + mHttpReplySize = 0; + mHttpReplyOffset = 0; mHaveAllData = FALSE; clearPackets(); // TODO: Shouldn't be necessary mCacheReadHandle = LLTextureCache::nullHandle(); @@ -938,22 +1163,24 @@ bool LLTextureFetchWorker::doWork(S32 param) setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it // read file from local disk + ++mCacheReadCount; std::string filename = mUrl.substr(7, std::string::npos); CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority, offset, size, responder); mCacheReadTimer.reset(); } - else if (mUrl.empty()) + else if (mUrl.empty() && mFetcher->canLoadFromCache()) { setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it + ++mCacheReadCount; CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage); mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, offset, size, responder); mCacheReadTimer.reset(); } - else if(mCanUseHTTP) + else if(!mUrl.empty() && mCanUseHTTP) { if (!(mUrl.compare(0, 7, "http://") == 0)) { @@ -961,7 +1188,7 @@ bool LLTextureFetchWorker::doWork(S32 param) llwarns << "Unknown URL Type: " << mUrl << llendl; } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - mState = SEND_HTTP_REQ; + mState = WAIT_HTTP_RESOURCE; } else { @@ -981,6 +1208,9 @@ bool LLTextureFetchWorker::doWork(S32 param) } else { + // + //This should never happen + // return false; } } @@ -1020,6 +1250,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL; mState = LOAD_FROM_NETWORK; } + // fall through LLTextureFetch::sCacheHitRate.addValue(0.f); } @@ -1060,7 +1291,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } if (mCanUseHTTP && !mUrl.empty()) { - mState = LLTextureFetchWorker::SEND_HTTP_REQ; + mState = WAIT_HTTP_RESOURCE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); if(mWriteToCacheState != NOT_WRITE) { @@ -1077,13 +1308,7 @@ bool LLTextureFetchWorker::doWork(S32 param) mRequestedDiscard = mDesiredDiscard; mSentRequest = QUEUED; mFetcher->addToNetworkQueue(this); - if (! mMetricsStartTime) - { - mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); - } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType); + recordTextureStart(false); setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return false; @@ -1094,12 +1319,7 @@ bool LLTextureFetchWorker::doWork(S32 param) //llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); // Make certain this is in the network queue //mFetcher->addToNetworkQueue(this); - //if (! mMetricsStartTime) - //{ - // mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); - //} - //LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, false, - // LLImageBase::TYPE_AVATAR_BAKE == mType); + //recordTextureStart(false); //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return false; } @@ -1124,196 +1344,250 @@ bool LLTextureFetchWorker::doWork(S32 param) setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); mState = DECODE_IMAGE; mWriteToCacheState = SHOULD_WRITE; - - if (mMetricsStartTime) - { - LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType, - LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); - mMetricsStartTime = 0; - } - LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType); + recordTextureDone(false); } else { mFetcher->addToNetworkQueue(this); // failsafe - if (! mMetricsStartTime) - { - mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); - } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, - false, - LLImageBase::TYPE_AVATAR_BAKE == mType); setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + recordTextureStart(false); } return false; } + if (mState == WAIT_HTTP_RESOURCE) + { + // NOTE: + // control the number of the http requests issued for: + // 1, not openning too many file descriptors at the same time; + // 2, control the traffic of http so udp gets bandwidth. + // + // If it looks like we're busy, keep this request here. + // Otherwise, advance into the HTTP states. + if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore()) + { + mState = WAIT_HTTP_RESOURCE2; + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + mFetcher->addHttpWaiter(this->mID); + ++mResourceWaitCount; + return false; + } + + mState = SEND_HTTP_REQ; + // *NOTE: You must invoke releaseHttpSemaphore() if you transition + // to a state other than SEND_HTTP_REQ or WAIT_HTTP_REQ or abort + // the request. + } + + if (mState == WAIT_HTTP_RESOURCE2) + { + // Just idle it if we make it to the head... + return false; + } + if (mState == SEND_HTTP_REQ) { - if(mCanUseHTTP) + if (! mCanUseHTTP) { - //NOTE: - //control the number of the http requests issued for: - //1, not openning too many file descriptors at the same time; - //2, control the traffic of http so udp gets bandwidth. - // - static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ; - if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE) - { - return false ; //wait. - } + releaseHttpSemaphore(); + return true; // abort + } - mFetcher->removeFromNetworkQueue(this, false); + mFetcher->removeFromNetworkQueue(this, false); - S32 cur_size = 0; - if (mFormattedImage.notNull()) + S32 cur_size = 0; + if (mFormattedImage.notNull()) + { + cur_size = mFormattedImage->getDataSize(); // amount of data we already have + if (mFormattedImage->getDiscardLevel() == 0) { - cur_size = mFormattedImage->getDataSize(); // amount of data we already have - if (mFormattedImage->getDiscardLevel() == 0) + if (cur_size > 0) { - if(cur_size > 0) - { - // We already have all the data, just decode it - mLoadedDiscard = mFormattedImage->getDiscardLevel(); - mState = DECODE_IMAGE; - return false; - } - else - { - return true ; //abort. - } + // We already have all the data, just decode it + mLoadedDiscard = mFormattedImage->getDiscardLevel(); + setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + mState = DECODE_IMAGE; + releaseHttpSemaphore(); + return false; } - } - mRequestedSize = mDesiredSize; - mRequestedDiscard = mDesiredDiscard; - mRequestedSize -= cur_size; - S32 offset = cur_size; - mBufferSize = cur_size; // This will get modified by callbackHttpGet() - - bool res = false; - if (!mUrl.empty()) - { - mRequestedTimer.reset(); - - mLoaded = FALSE; - mGetStatus = 0; - mGetReason.clear(); - LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << offset - << " Bytes: " << mRequestedSize - << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth - << LL_ENDL; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - mState = WAIT_HTTP_REQ; - - mFetcher->addToHTTPQueue(mID); - if (! mMetricsStartTime) + else { - mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); + releaseHttpSemaphore(); + return true; // abort. } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, - true, - LLImageBase::TYPE_AVATAR_BAKE == mType); - - // Will call callbackHttpGet when curl request completes - std::vector<std::string> headers; - headers.push_back("Accept: image/x-j2c"); - res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, - new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true)); - } - if (!res) - { - llwarns << "HTTP GET request failed for " << mID << llendl; - resetFormattedData(); - ++mHTTPFailCount; - return true; // failed } - // fall through } - else //can not use http fetch. + mRequestedSize = mDesiredSize; + mRequestedDiscard = mDesiredDiscard; + mRequestedSize -= cur_size; + mRequestedOffset = cur_size; + if (mRequestedOffset) + { + // Texture fetching often issues 'speculative' loads that + // start beyond the end of the actual asset. Some cache/web + // systems, e.g. Varnish, will respond to this not with a + // 416 but with a 200 and the entire asset in the response + // body. By ensuring that we always have a partially + // satisfiable Range request, we avoid that hit to the network. + // We just have to deal with the overlapping data which is made + // somewhat harder by the fact that grid services don't necessarily + // return the Content-Range header on 206 responses. *Sigh* + mRequestedOffset -= 1; + mRequestedSize += 1; + } + + mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; + if (!mUrl.empty()) + { + mRequestedTimer.reset(); + mLoaded = FALSE; + mGetStatus = LLCore::HttpStatus(); + mGetReason.clear(); + LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << mRequestedOffset + << " Bytes: " << mRequestedSize + << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth + << LL_ENDL; + + // Will call callbackHttpGet when curl request completes + mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass, + mWorkPriority, + mUrl, + mRequestedOffset, + mRequestedSize, + mFetcher->mHttpOptions, + mFetcher->mHttpHeaders, + this); + } + if (LLCORE_HTTP_HANDLE_INVALID == mHttpHandle) { - return true ; //abort + llwarns << "HTTP GET request failed for " << mID << llendl; + resetFormattedData(); + releaseHttpSemaphore(); + return true; // failed } + + mHttpActive = true; + mFetcher->addToHTTPQueue(mID); + recordTextureStart(true); + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + mState = WAIT_HTTP_REQ; + + // fall through } if (mState == WAIT_HTTP_REQ) { + // *NOTE: As stated above, all transitions out of this state should + // call releaseHttpSemaphore(). if (mLoaded) { S32 cur_size = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; if (mRequestedSize < 0) { - S32 max_attempts; - if (mGetStatus == HTTP_NOT_FOUND) + if (http_not_found == mGetStatus) { - mHTTPFailCount = max_attempts = 1; // Don't retry + if(mWriteToCacheState == NOT_WRITE) //map tiles + { + mState = DONE; + releaseHttpSemaphore(); + return true; // failed, means no map tile on the empty region. + } + llwarns << "Texture missing from server (404): " << mUrl << llendl; - //roll back to try UDP - if(mCanUseNET) + // roll back to try UDP + if (mCanUseNET) { - mState = INIT ; - mCanUseHTTP = false ; + mState = INIT; + mCanUseHTTP = false; + mUrl.clear(); setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - return false ; + releaseHttpSemaphore(); + return false; } } - else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE) + else if (http_service_unavail == mGetStatus) { - // *TODO: Should probably introduce a timer here to delay future HTTP requsts - // for a short time (~1s) to ease server load? Ideally the server would queue - // requests instead of returning 503... we already limit the number pending. - ++mHTTPFailCount; - max_attempts = mHTTPFailCount+1; // Keep retrying LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; } + else if (http_not_sat == mGetStatus) + { + // Allowed, we'll accept whatever data we have as complete. + mHaveAllData = TRUE; + } else { - const S32 HTTP_MAX_RETRY_COUNT = 3; - max_attempts = HTTP_MAX_RETRY_COUNT + 1; - ++mHTTPFailCount; llinfos << "HTTP GET failed for: " << mUrl - << " Status: " << mGetStatus << " Reason: '" << mGetReason << "'" - << " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl; + << " Status: " << mGetStatus.toHex() + << " Reason: '" << mGetReason << "'" + << llendl; } - if (mHTTPFailCount >= max_attempts) - { - if (cur_size > 0) - { - // Use available data - mLoadedDiscard = mFormattedImage->getDiscardLevel(); - mState = DECODE_IMAGE; - return false; - } - else - { - resetFormattedData(); - mState = DONE; - return true; // failed - } - } - else + mUrl.clear(); + if (cur_size > 0) { - mState = SEND_HTTP_REQ; - return false; // retry + // Use available data + mLoadedDiscard = mFormattedImage->getDiscardLevel(); + setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + mState = DECODE_IMAGE; + releaseHttpSemaphore(); + return false; } + + // Fail harder + resetFormattedData(); + mState = DONE; + releaseHttpSemaphore(); + return true; // failed + } + + // Clear the url since we're done with the fetch + // Note: mUrl is used to check is fetching is required so failure to clear it will force an http fetch + // next time the texture is requested, even if the data have already been fetched. + if(mWriteToCacheState != NOT_WRITE) + { + mUrl.clear(); } - llassert_always(mBufferSize == cur_size + mRequestedSize); - if(!mBufferSize)//no data received. + if (! mHttpBufferArray || ! mHttpBufferArray->size()) { - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); - mBuffer = NULL; + // no data received. + if (mHttpBufferArray) + { + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + } - //abort. + // abort. mState = DONE; + releaseHttpSemaphore(); return true; } + S32 append_size(mHttpBufferArray->size()); + S32 total_size(cur_size + append_size); + S32 src_offset(0); + llassert_always(append_size == mRequestedSize); + if (mHttpReplyOffset && mHttpReplyOffset != cur_size) + { + // In case of a partial response, our offset may + // not be trivially contiguous with the data we have. + // Get back into alignment. + if (mHttpReplyOffset > cur_size) + { + LL_WARNS("Texture") << "Partial HTTP response produces break in image data for texture " + << mID << ". Aborting load." << LL_ENDL; + mState = DONE; + releaseHttpSemaphore(); + return true; + } + src_offset = cur_size - mHttpReplyOffset; + append_size -= src_offset; + total_size -= src_offset; + mRequestedSize -= src_offset; // Make requested values reflect useful part + mRequestedOffset += src_offset; + } + if (mFormattedImage.isNull()) { // For now, create formatted image based on extension @@ -1325,44 +1599,49 @@ bool LLTextureFetchWorker::doWork(S32 param) } } - if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded. + if (mHaveAllData) //the image file is fully loaded. { - mFileSize = mBufferSize; + mFileSize = total_size; } else //the file size is unknown. { - mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded. + mFileSize = total_size + 1 ; //flag the file is not fully loaded. } - U8* buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mBufferSize); + U8 * buffer = (U8 *) ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_size); if (cur_size > 0) { memcpy(buffer, mFormattedImage->getData(), cur_size); } - memcpy(buffer + cur_size, mBuffer, mRequestedSize); // append + mHttpBufferArray->read(src_offset, (char *) buffer + cur_size, append_size); + // NOTE: setData releases current data and owns new data (buffer) - mFormattedImage->setData(buffer, mBufferSize); - // delete temp data - FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); // Note: not 'buffer' (assigned in setData()) - mBuffer = NULL; - mBufferSize = 0; + mFormattedImage->setData(buffer, total_size); + + // Done with buffer array + mHttpBufferArray->release(); + mHttpBufferArray = NULL; + mHttpReplySize = 0; + mHttpReplyOffset = 0; + mLoadedDiscard = mRequestedDiscard; mState = DECODE_IMAGE; - if(mWriteToCacheState != NOT_WRITE) + if (mWriteToCacheState != NOT_WRITE) { mWriteToCacheState = SHOULD_WRITE ; } setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + releaseHttpSemaphore(); return false; } else { - if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32()) - { - //timeout, abort. - mState = DONE; - return true; - } + // *HISTORY: There was a texture timeout test here originally that + // would cancel a request that was over 120 seconds old. That's + // probably not a good idea. Particularly rich regions can take + // an enormous amount of time to load textures. We'll revisit the + // various possible timeout components (total request time, connection + // time, I/O time, with and without retries, etc.) in the future. setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return false; @@ -1372,11 +1651,12 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mState == DECODE_IMAGE) { static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); - if(textures_decode_disabled) + + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it + if (textures_decode_disabled) { // for debug use, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } @@ -1384,7 +1664,6 @@ bool LLTextureFetchWorker::doWork(S32 param) { // We aborted, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } @@ -1394,7 +1673,6 @@ bool LLTextureFetchWorker::doWork(S32 param) //abort, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } if (mLoadedDiscard < 0) @@ -1403,10 +1681,9 @@ bool LLTextureFetchWorker::doWork(S32 param) //abort, don't decode mState = DONE; - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); return true; } - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it + mRawImage = NULL; mAuxImage = NULL; llassert_always(mFormattedImage.notNull()); @@ -1492,10 +1769,11 @@ bool LLTextureFetchWorker::doWork(S32 param) U32 cache_priority = mWorkPriority; mWritten = FALSE; mState = WAIT_ON_WRITE; + ++mCacheWriteCount; CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID); mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority, mFormattedImage->getData(), datasize, - mFileSize, responder); + mFileSize, mRawImage, mDecodedDiscard, responder); // fall through } @@ -1536,9 +1814,84 @@ bool LLTextureFetchWorker::doWork(S32 param) } return false; -} +} // -Mw -// Called from MAIN thread +// Threads: Ttf +// virtual +void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) +{ + static LLCachedControl<bool> log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog"); + static LLCachedControl<bool> log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator"); + static LLCachedControl<bool> log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic") ; + + LLMutexLock lock(&mWorkMutex); // +Mw + + mHttpActive = false; + + if (log_to_viewer_log || log_to_sim) + { + U64 timeNow = LLTimer::getTotalTime(); + mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime); + mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP); + mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize); + mFetcher->mTextureInfo.setRequestOffset(mID, mRequestedOffset); + mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow); + } + + bool success = true; + bool partial = false; + LLCore::HttpStatus status(response->getStatus()); + + lldebugs << "HTTP COMPLETE: " << mID + << " status: " << status.toHex() + << " '" << status.toString() << "'" + << llendl; +// unsigned int offset(0), length(0), full_length(0); +// response->getRange(&offset, &length, &full_length); +// llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle +// << " status: " << status.toULong() << " '" << status.toString() << "'" +// << " req offset: " << mRequestedOffset << " req length: " << mRequestedSize +// << " offset: " << offset << " length: " << length +// << llendl; + + if (! status) + { + success = false; + std::string reason(status.toString()); + setGetStatus(status, reason); + llwarns << "CURL GET FAILED, status: " << status.toHex() + << " reason: " << reason << llendl; + } + else + { + // A warning about partial (HTTP 206) data. Some grid services + // do *not* return a 'Content-Range' header in the response to + // Range requests with a 206 status. We're forced to assume + // we get what we asked for in these cases until we can fix + // the services. + static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT); + + partial = (par_status == status); + } + + S32 data_size = callbackHttpGet(response, partial, success); + + if (log_texture_traffic && data_size > 0) + { + LLViewerTexture* tex = LLViewerTextureManager::findTexture(mID); + if (tex) + { + gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ; + } + } + + mFetcher->removeFromHTTPQueue(mID, data_size); + + recordTextureDone(true); +} // -Mw + + +// Threads: Tmain void LLTextureFetchWorker::endWork(S32 param, bool aborted) { if (mDecodeHandle != 0) @@ -1551,6 +1904,8 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted) ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttf + // virtual void LLTextureFetchWorker::finishWork(S32 param, bool completed) { @@ -1567,10 +1922,37 @@ void LLTextureFetchWorker::finishWork(S32 param, bool completed) } } +// LLQueuedThread's update() method is asking if it's okay to +// delete this worker. You'll notice we're not locking in here +// which is a slight concern. Caller is expected to have made +// this request 'quiet' by whatever means... +// +// Threads: Tmain + // virtual bool LLTextureFetchWorker::deleteOK() { bool delete_ok = true; + + if (mHttpActive) + { + // HTTP library has a pointer to this worker + // and will dereference it to do notification. + delete_ok = false; + } + + if (WAIT_HTTP_RESOURCE2 == mState) + { + if (mFetcher->isHttpWaiter(mID)) + { + // Don't delete the worker out from under the releaseHttpWaiters() + // method. Keep the pointers valid, clean up after that method + // has recognized the cancelation and removed the UUID from the + // waiter list. + delete_ok = false; + } + } + // Allow any pending reads or writes to complete if (mCacheReadHandle != LLTextureCache::nullHandle()) { @@ -1605,6 +1987,7 @@ bool LLTextureFetchWorker::deleteOK() return delete_ok; } +// Threads: Ttf void LLTextureFetchWorker::removeFromCache() { if (!mInLocalCache) @@ -1616,6 +1999,8 @@ void LLTextureFetchWorker::removeFromCache() ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttf +// Locks: Mw bool LLTextureFetchWorker::processSimulatorPackets() { if (mFormattedImage.isNull() || mRequestedSize < 0) @@ -1676,14 +2061,13 @@ bool LLTextureFetchWorker::processSimulatorPackets() ////////////////////////////////////////////////////////////////////////////// -S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer, - bool partial, bool success) +// Threads: Ttf +// Locks: Mw +S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, + bool partial, bool success) { S32 data_size = 0 ; - LLMutexLock lock(&mWorkMutex); - if (mState != WAIT_HTTP_REQ) { llwarns << "callbackHttpGet for unrequested fetch worker: " << mID @@ -1698,27 +2082,68 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, if (success) { // get length of stream: - data_size = buffer->countAfter(channels.in(), NULL); - + LLCore::BufferArray * body(response->getBody()); + data_size = body ? body->size() : 0; + LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL; if (data_size > 0) { // *TODO: set the formatted image data here directly to avoid the copy - mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); - buffer->readAfter(channels.in(), NULL, mBuffer, data_size); - mBufferSize += data_size; - if (data_size < mRequestedSize && mRequestedDiscard == 0) + + // Hold on to body for later copy + llassert_always(NULL == mHttpBufferArray); + body->addRef(); + mHttpBufferArray = body; + + if (partial) + { + unsigned int offset(0), length(0), full_length(0); + response->getRange(&offset, &length, &full_length); + if (! offset && ! length) + { + // This is the case where we receive a 206 status but + // there wasn't a useful Content-Range header in the response. + // This could be because it was badly formatted but is more + // likely due to capabilities services which scrub headers + // from responses. Assume we got what we asked for... + mHttpReplySize = data_size; + mHttpReplyOffset = mRequestedOffset; + } + else + { + mHttpReplySize = length; + mHttpReplyOffset = offset; + } + } + + if (! partial) + { + // Response indicates this is the entire asset regardless + // of our asking for a byte range. Mark it so and drop + // any partial data we might have so that the current + // response body becomes the entire dataset. + if (data_size <= mRequestedOffset) + { + LL_WARNS("Texture") << "Fetched entire texture " << mID + << " when it was expected to be marked complete. mImageSize: " + << mFileSize << " datasize: " << mFormattedImage->getDataSize() + << LL_ENDL; + } + mHaveAllData = TRUE; + llassert_always(mDecodeHandle == 0); + mFormattedImage = NULL; // discard any previous data we had + } + else if (data_size < mRequestedSize) { mHaveAllData = TRUE; } else if (data_size > mRequestedSize) { - // *TODO: This shouldn't be happening any more + // *TODO: This shouldn't be happening any more (REALLY don't expect this anymore) llwarns << "data_size = " << data_size << " > requested: " << mRequestedSize << llendl; mHaveAllData = TRUE; llassert_always(mDecodeHandle == 0); mFormattedImage = NULL; // discard any previous data we had - mBufferSize = data_size; } } else @@ -1733,6 +2158,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, { mRequestedSize = -1; // error } + mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); @@ -1741,10 +2167,11 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttc void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal) { - LLMutexLock lock(&mWorkMutex); + LLMutexLock lock(&mWorkMutex); // +Mw if (mState != LOAD_FROM_TEXTURE_CACHE) { // llwarns << "Read callback for " << mID << " with state = " << mState << llendl; @@ -1764,11 +2191,12 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima } mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -} +} // -Mw +// Threads: Ttc void LLTextureFetchWorker::callbackCacheWrite(bool success) { - LLMutexLock lock(&mWorkMutex); + LLMutexLock lock(&mWorkMutex); // +Mw if (mState != WAIT_ON_WRITE) { // llwarns << "Write callback for " << mID << " with state = " << mState << llendl; @@ -1776,13 +2204,14 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success) } mWritten = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -} +} // -Mw ////////////////////////////////////////////////////////////////////////////// +// Threads: Tid void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux) { - LLMutexLock lock(&mWorkMutex); + LLMutexLock lock(&mWorkMutex); // +Mw if (mDecodeHandle == 0) { return; // aborted, ignore @@ -1815,10 +2244,11 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag // llinfos << mID << " : DECODE COMPLETE " << llendl; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); mCacheReadTime = mCacheReadTimer.getElapsedTimeF32(); -} +} // -Mw ////////////////////////////////////////////////////////////////////////////// +// Threads: Ttf bool LLTextureFetchWorker::writeToCacheComplete() { // Complete write to cache @@ -1841,6 +2271,36 @@ bool LLTextureFetchWorker::writeToCacheComplete() } +// Threads: Ttf +void LLTextureFetchWorker::recordTextureStart(bool is_http) +{ + if (! mMetricsStartTime) + { + mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); + } + LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, + is_http, + LLImageBase::TYPE_AVATAR_BAKE == mType); +} + + +// Threads: Ttf +void LLTextureFetchWorker::recordTextureDone(bool is_http) +{ + if (mMetricsStartTime) + { + LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, + is_http, + LLImageBase::TYPE_AVATAR_BAKE == mType, + LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); + mMetricsStartTime = 0; + } + LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, + is_http, + LLImageBase::TYPE_AVATAR_BAKE == mType); +} + + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // public @@ -1858,12 +2318,21 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mTextureBandwidth(0), mHTTPTextureBits(0), mTotalHTTPRequests(0), - mCurlGetRequest(NULL), mQAMode(qa_mode), + mHttpRequest(NULL), + mHttpOptions(NULL), + mHttpHeaders(NULL), + mHttpMetricsHeaders(NULL), + mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), + mHttpSemaphore(HTTP_REQUESTS_IN_QUEUE_HIGH_WATER), + mTotalCacheReadCount(0U), + mTotalCacheWriteCount(0U), + mTotalResourceWaitCount(0U), mFetchDebugger(NULL), + mFetchSource(LLTextureFetch::FROM_ALL), + mOriginFetchSource(LLTextureFetch::FROM_ALL), mFetcherLocked(FALSE) { - mCurlPOSTRequestCount = 0; mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); @@ -1871,12 +2340,27 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image if(LLTextureFetchDebugger::isEnabled()) { mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; + mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource"); + if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE) + { + mFetchSource = LLTextureFetch::FROM_ALL; + gSavedSettings.setS32("TextureFetchSource", 0); + } + mOriginFetchSource = mFetchSource; } + + mHttpRequest = new LLCore::HttpRequest; + mHttpOptions = new LLCore::HttpOptions; + mHttpHeaders = new LLCore::HttpHeaders; + mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c"); + mHttpMetricsHeaders = new LLCore::HttpHeaders; + mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml"); + mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault(); } LLTextureFetch::~LLTextureFetch() { - clearDeleteList() ; + clearDeleteList(); while (! mCommands.empty()) { @@ -1884,10 +2368,34 @@ LLTextureFetch::~LLTextureFetch() mCommands.erase(mCommands.begin()); delete req; } + + if (mHttpOptions) + { + mHttpOptions->release(); + mHttpOptions = NULL; + } + + if (mHttpHeaders) + { + mHttpHeaders->release(); + mHttpHeaders = NULL; + } + + if (mHttpMetricsHeaders) + { + mHttpMetricsHeaders->release(); + mHttpMetricsHeaders = NULL; + } + + mHttpWaitResource.clear(); - // ~LLQueuedThread() called here + delete mHttpRequest; + mHttpRequest = NULL; delete mFetchDebugger; + mFetchDebugger = NULL; + + // ~LLQueuedThread() called here } bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, @@ -1940,6 +2448,8 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con } else { + // If the requester knows nothing about the file, we fetch the smallest + // amount of data at the lowest resolution (highest discard level) possible. desired_size = TEXTURE_CACHE_ENTRY_SIZE; desired_discard = MAX_DISCARD_LEVEL; } @@ -1951,7 +2461,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con { return false; // need to wait for previous aborted request to complete } - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw worker->mActiveCount++; worker->mNeedsAux = needs_aux; worker->setImagePriority(priority); @@ -1960,41 +2470,44 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con if (!worker->haveWork()) { worker->mState = LLTextureFetchWorker::INIT; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); } else { - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } } else { worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size); - lockQueue() ; + lockQueue(); // +Mfq mRequestMap[id] = worker; - unlockQueue() ; + unlockQueue(); // -Mfq - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw worker->mActiveCount++; worker->mNeedsAux = needs_aux; worker->setCanUseHTTP(can_use_http) ; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } // llinfos << "REQUESTED: " << id << " Discard: " << desired_discard << llendl; return true; } + +// Threads: T* (but Ttf in practice) + // protected void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) { - lockQueue() ; + lockQueue(); // +Mfq bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ; - unlockQueue() ; + unlockQueue(); // -Mfq - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq if (in_request_map) { // only add to the queue if in the request map @@ -2006,44 +2519,52 @@ void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) { iter1->second.erase(worker->mID); } -} +} // -Mfnq +// Threads: T* void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel) { - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq size_t erased = mNetworkQueue.erase(worker->mID); if (cancel && erased > 0) { mCancelQueue[worker->mHost].insert(worker->mID); } -} +} // -Mfnq +// Threads: T* +// // protected void LLTextureFetch::addToHTTPQueue(const LLUUID& id) { - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq mHTTPTextureQueue.insert(id); mTotalHTTPRequests++; -} +} // -Mfnq +// Threads: T* void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size) { - LLMutexLock lock(&mNetworkQueueMutex); + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq mHTTPTextureQueue.erase(id); mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits -} +} // -Mfnq +// NB: If you change deleteRequest() you should probably make +// parallel changes in removeRequest(). They're functionally +// identical with only argument variations. +// +// Threads: T* void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) { - lockQueue() ; + lockQueue(); // +Mfq LLTextureFetchWorker* worker = getWorkerAfterLock(id); if (worker) { size_t erased_1 = mRequestMap.erase(worker->mID); - unlockQueue() ; + unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; @@ -2051,15 +2572,25 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) } else { - unlockQueue() ; + unlockQueue(); // -Mfq } } +// NB: If you change removeRequest() you should probably make +// parallel changes in deleteRequest(). They're functionally +// identical with only argument variations. +// +// Threads: T* void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) { - lockQueue() ; + if(!worker) + { + return; + } + + lockQueue(); // +Mfq size_t erased_1 = mRequestMap.erase(worker->mID); - unlockQueue() ; + unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; removeFromNetworkQueue(worker, cancel); @@ -2068,34 +2599,57 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) worker->scheduleDelete(); } +void LLTextureFetch::deleteAllRequests() +{ + while(1) + { + lockQueue(); + if(mRequestMap.empty()) + { + unlockQueue() ; + break; + } + + LLTextureFetchWorker* worker = mRequestMap.begin()->second; + unlockQueue() ; + + removeRequest(worker, true); + } +} + +// Threads: T* S32 LLTextureFetch::getNumRequests() { - lockQueue() ; + lockQueue(); // +Mfq S32 size = (S32)mRequestMap.size(); - unlockQueue() ; + unlockQueue(); // -Mfq - return size ; + return size; } +// Threads: T* S32 LLTextureFetch::getNumHTTPRequests() { - mNetworkQueueMutex.lock() ; + mNetworkQueueMutex.lock(); // +Mfq S32 size = (S32)mHTTPTextureQueue.size(); - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfq - return size ; + return size; } +// Threads: T* U32 LLTextureFetch::getTotalNumHTTPRequests() { - mNetworkQueueMutex.lock() ; - U32 size = mTotalHTTPRequests ; - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.lock(); // +Mfq + U32 size = mTotalHTTPRequests; + mNetworkQueueMutex.unlock(); // -Mfq - return size ; + return size; } // call lockQueue() first! +// Threads: T* +// Locks: Mfq LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id) { LLTextureFetchWorker* res = NULL; @@ -2107,14 +2661,16 @@ LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id) return res; } +// Threads: T* LLTextureFetchWorker* LLTextureFetch::getWorker(const LLUUID& id) { - LLMutexLock lock(&mQueueMutex) ; + LLMutexLock lock(&mQueueMutex); // +Mfq - return getWorkerAfterLock(id) ; -} + return getWorkerAfterLock(id); +} // -Mfq +// Threads: T* bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux) { @@ -2137,7 +2693,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, } else if (worker->checkWork()) { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw discard_level = worker->mDecodedDiscard; raw = worker->mRawImage; aux = worker->mAuxImage; @@ -2148,11 +2704,11 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, } res = true; LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } else { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw if ((worker->mDecodedDiscard >= 0) && (worker->mDecodedDiscard < discard_level || discard_level < 0) && (worker->mState >= LLTextureFetchWorker::WAIT_ON_WRITE)) @@ -2162,7 +2718,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, raw = worker->mRawImage; aux = worker->mAuxImage; } - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } } else @@ -2172,15 +2728,16 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, return res; } +// Threads: T* bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) { bool res = false; LLTextureFetchWorker* worker = getWorker(id); if (worker) { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw worker->setImagePriority(priority); - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw res = true; } return res; @@ -2195,24 +2752,24 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) // in step, at least until this can be refactored and // the redundancy eliminated. // -// May be called from any thread +// Threads: T* //virtual S32 LLTextureFetch::getPending() { S32 res; - lockData(); + lockData(); // +Ct { - LLMutexLock lock(&mQueueMutex); + LLMutexLock lock(&mQueueMutex); // +Mfq res = mRequestQueue.size(); - res += mCurlPOSTRequestCount; res += mCommands.size(); - } - unlockData(); + } // -Mfq + unlockData(); // -Ct return res; } +// Locks: Ct // virtual bool LLTextureFetch::runCondition() { @@ -2227,49 +2784,52 @@ bool LLTextureFetch::runCondition() bool have_no_commands(false); { - LLMutexLock lock(&mQueueMutex); + LLMutexLock lock(&mQueueMutex); // +Mfq have_no_commands = mCommands.empty(); - } - - bool have_no_curl_requests(0 == mCurlPOSTRequestCount); + } // -Mfq return ! (have_no_commands - && have_no_curl_requests && (mRequestQueue.empty() && mIdleThread)); // From base class } ////////////////////////////////////////////////////////////////////////////// -// MAIN THREAD (unthreaded envs), WORKER THREAD (threaded envs) +// Threads: Ttf void LLTextureFetch::commonUpdate() { + // Release waiters + releaseHttpWaiters(); + // Run a cross-thread command, if any. cmdDoWork(); - // Update Curl on same thread as mCurlGetRequest was constructed - S32 processed = mCurlGetRequest->process(); - if (processed > 0) + // Deliver all completion notifications + LLCore::HttpStatus status = mHttpRequest->update(0); + if (! status) { - lldebugs << "processed: " << processed << " messages." << llendl; + LL_INFOS_ONCE("Texture") << "Problem during HTTP servicing. Reason: " + << status.toString() + << LL_ENDL; } } -// MAIN THREAD +// Threads: Tmain + //virtual S32 LLTextureFetch::update(F32 max_time_ms) { static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS"); { - mNetworkQueueMutex.lock() ; - mMaxBandwidth = band_width ; + mNetworkQueueMutex.lock(); // +Mfnq + mMaxBandwidth = band_width; - gTextureList.sTextureBits += mHTTPTextureBits ; - mHTTPTextureBits = 0 ; + gTextureList.sTextureBits += mHTTPTextureBits; + mHTTPTextureBits = 0; - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfnq } S32 res = LLWorkerThread::update(max_time_ms); @@ -2281,7 +2841,7 @@ S32 LLTextureFetch::update(F32 max_time_ms) // won't work so don't bother trying if (LLStartUp::getStartupState() > STATE_AGENT_SEND) { - sendRequestListToSimulators(); + sendRequestListToSimulators(); } } @@ -2290,10 +2850,17 @@ S32 LLTextureFetch::update(F32 max_time_ms) commonUpdate(); } + if (mFetchDebugger) + { + mFetchDebugger->tryToStopDebug(); //check if need to stop debugger. + } + return res; } -//called in the MAIN thread after the TextureCacheThread shuts down. +// called in the MAIN thread after the TextureCacheThread shuts down. +// +// Threads: Tmain void LLTextureFetch::shutDownTextureCacheThread() { if(mTextureCache) @@ -2303,7 +2870,9 @@ void LLTextureFetch::shutDownTextureCacheThread() } } -//called in the MAIN thread after the ImageDecodeThread shuts down. +// called in the MAIN thread after the ImageDecodeThread shuts down. +// +// Threads: Tmain void LLTextureFetch::shutDownImageDecodeThread() { if(mImageDecodeThread) @@ -2313,35 +2882,27 @@ void LLTextureFetch::shutDownImageDecodeThread() } } -// WORKER THREAD +// Threads: Ttf void LLTextureFetch::startThread() { - // Construct mCurlGetRequest from Worker Thread - mCurlGetRequest = new LLCurlRequest(); - - if(mFetchDebugger) - { - mFetchDebugger->setCurlGetRequest(mCurlGetRequest); - } } -// WORKER THREAD +// Threads: Ttf void LLTextureFetch::endThread() { - // Destroy mCurlGetRequest from Worker Thread - delete mCurlGetRequest; - mCurlGetRequest = NULL; - if(mFetchDebugger) - { - mFetchDebugger->setCurlGetRequest(NULL); - } + LL_INFOS("Texture") << "CacheReads: " << mTotalCacheReadCount + << ", CacheWrites: " << mTotalCacheWriteCount + << ", ResWaits: " << mTotalResourceWaitCount + << ", TotalHTTPReq: " << getTotalNumHTTPRequests() + << LL_ENDL; } -// WORKER THREAD +// Threads: Ttf void LLTextureFetch::threadedUpdate() { - llassert_always(mCurlGetRequest); - + llassert_always(mHttpRequest); + +#if 0 // Limit update frequency const F32 PROCESS_TIME = 0.05f; static LLFrameTimer process_timer; @@ -2350,9 +2911,10 @@ void LLTextureFetch::threadedUpdate() return; } process_timer.reset(); +#endif commonUpdate(); - + #if 0 const F32 INFO_TIME = 1.0f; static LLFrameTimer info_timer; @@ -2366,11 +2928,11 @@ void LLTextureFetch::threadedUpdate() } } #endif - } ////////////////////////////////////////////////////////////////////////////// +// Threads: Tmain void LLTextureFetch::sendRequestListToSimulators() { // All requests @@ -2396,48 +2958,48 @@ void LLTextureFetch::sendRequestListToSimulators() typedef std::map< LLHost, request_list_t > work_request_map_t; work_request_map_t requests; { - LLMutexLock lock2(&mNetworkQueueMutex); - for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); ) - { - queue_t::iterator curiter = iter++; - LLTextureFetchWorker* req = getWorker(*curiter); - if (!req) - { - mNetworkQueue.erase(curiter); - continue; // paranoia - } - if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && - (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) - { - // We already received our URL, remove from the queue - llwarns << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << llendl; - mNetworkQueue.erase(curiter); - continue; - } - if (req->mID == mDebugID) + LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq + for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); ) { - mDebugCount++; // for setting breakpoints - } - if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM && - req->mTotalPackets > 0 && - req->mLastPacket >= req->mTotalPackets-1) - { - // We have all the packets... make sure this is high priority + queue_t::iterator curiter = iter++; + LLTextureFetchWorker* req = getWorker(*curiter); + if (!req) + { + mNetworkQueue.erase(curiter); + continue; // paranoia + } + if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && + (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) + { + // We already received our URL, remove from the queue + llwarns << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << llendl; + mNetworkQueue.erase(curiter); + continue; + } + if (req->mID == mDebugID) + { + mDebugCount++; // for setting breakpoints + } + if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM && + req->mTotalPackets > 0 && + req->mLastPacket >= req->mTotalPackets-1) + { + // We have all the packets... make sure this is high priority // req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority); - continue; - } - F32 elapsed = req->mRequestedTimer.getElapsedTimeF32(); - { - F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority); - if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || - (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) || - (elapsed >= SIM_LAZY_FLUSH_TIMEOUT)) + continue; + } + F32 elapsed = req->mRequestedTimer.getElapsedTimeF32(); { - requests[req->mHost].insert(req); + F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority); + if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || + (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) || + (elapsed >= SIM_LAZY_FLUSH_TIMEOUT)) + { + requests[req->mHost].insert(req); + } } } - } - } + } // -Mfnq for (work_request_map_t::iterator iter1 = requests.begin(); iter1 != requests.end(); ++iter1) @@ -2460,9 +3022,9 @@ void LLTextureFetch::sendRequestListToSimulators() if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM) { // Initialize packet data based on data read from cache - req->lockWorkMutex(); + req->lockWorkMutex(); // +Mw req->setupPacketData(); - req->unlockWorkMutex(); + req->unlockWorkMutex(); // -Mw } if (0 == sim_request_count) { @@ -2491,12 +3053,12 @@ void LLTextureFetch::sendRequestListToSimulators() mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP); } - req->lockWorkMutex(); + req->lockWorkMutex(); // +Mw req->mSentRequest = LLTextureFetchWorker::SENT_SIM; req->mSimRequestedDiscard = req->mDesiredDiscard; req->mRequestedPriority = req->mImagePriority; req->mRequestedTimer.reset(); - req->unlockWorkMutex(); + req->unlockWorkMutex(); // -Mw sim_request_count++; if (sim_request_count >= IMAGES_PER_REQUEST) { @@ -2517,55 +3079,57 @@ void LLTextureFetch::sendRequestListToSimulators() // Send cancelations { - LLMutexLock lock2(&mNetworkQueueMutex); - if (gMessageSystem && !mCancelQueue.empty()) - { - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) + LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq + if (gMessageSystem && !mCancelQueue.empty()) { - LLHost host = iter1->first; - if (host == LLHost::invalid) + for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); + iter1 != mCancelQueue.end(); ++iter1) { - host = gAgent.getRegionHost(); - } - S32 request_count = 0; - for (queue_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) - { - if (0 == request_count) + LLHost host = iter1->first; + if (host == LLHost::invalid) { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + host = gAgent.getRegionHost(); } - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); - gMessageSystem->addU32Fast(_PREHASH_Packet, 0); - gMessageSystem->addU8Fast(_PREHASH_Type, 0); + S32 request_count = 0; + for (queue_t::iterator iter2 = iter1->second.begin(); + iter2 != iter1->second.end(); ++iter2) + { + if (0 == request_count) + { + gMessageSystem->newMessageFast(_PREHASH_RequestImage); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + } + gMessageSystem->nextBlockFast(_PREHASH_RequestImage); + gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2); + gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1); + gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); + gMessageSystem->addU32Fast(_PREHASH_Packet, 0); + gMessageSystem->addU8Fast(_PREHASH_Type, 0); // llinfos << "CANCELING IMAGE REQUEST: " << (*iter2) << llendl; - request_count++; - if (request_count >= IMAGES_PER_REQUEST) + request_count++; + if (request_count >= IMAGES_PER_REQUEST) + { + gMessageSystem->sendSemiReliable(host, NULL, NULL); + request_count = 0; + } + } + if (request_count > 0 && request_count < IMAGES_PER_REQUEST) { gMessageSystem->sendSemiReliable(host, NULL, NULL); - request_count = 0; } } - if (request_count > 0 && request_count < IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - } + mCancelQueue.clear(); } - mCancelQueue.clear(); - } - } + } // -Mfnq } ////////////////////////////////////////////////////////////////////////////// +// Threads: T* +// Locks: Mw bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) { mRequestedTimer.reset(); @@ -2598,6 +3162,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) return true; } +// Threads: T* bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data) { @@ -2632,14 +3197,14 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 } if (!res) { + mNetworkQueueMutex.lock(); // +Mfnq ++mBadPacketCount; - mNetworkQueueMutex.lock() ; mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfnq return false; } - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw // Copy header data into image object worker->mImageCodec = codec; @@ -2650,10 +3215,12 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 res = worker->insertPacket(0, data, data_size); worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw return res; } + +// Threads: T* bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data) { LLTextureFetchWorker* worker = getWorker(id); @@ -2678,14 +3245,14 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 } if (!res) { + mNetworkQueueMutex.lock(); // +Mfnq ++mBadPacketCount; - mNetworkQueueMutex.lock() ; mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock() ; + mNetworkQueueMutex.unlock(); // -Mfnq return false; } - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw res = worker->insertPacket(packet_num, data, data_size); @@ -2702,7 +3269,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 removeFromNetworkQueue(worker, true); // failsafe } - if(packet_num >= (worker->mTotalPackets - 1)) + if (packet_num >= (worker->mTotalPackets - 1)) { static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog"); static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator"); @@ -2714,12 +3281,14 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 mTextureInfo.setRequestCompleteTimeAndLog(id, timeNow); } } - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw return res; } ////////////////////////////////////////////////////////////////////////////// + +// Threads: T* BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id) { BOOL from_cache = FALSE ; @@ -2727,14 +3296,15 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id) LLTextureFetchWorker* worker = getWorker(id); if (worker) { - worker->lockWorkMutex() ; - from_cache = worker->mInLocalCache ; - worker->unlockWorkMutex() ; + worker->lockWorkMutex(); // +Mw + from_cache = worker->mInLocalCache; + worker->unlockWorkMutex(); // -Mw } return from_cache ; } +// Threads: T* S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p, U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http) { @@ -2748,7 +3318,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r LLTextureFetchWorker* worker = getWorker(id); if (worker && worker->haveWork()) { - worker->lockWorkMutex(); + worker->lockWorkMutex(); // +Mw state = worker->mState; fetch_dtime = worker->mFetchTimer.getElapsedTimeF32(); request_dtime = worker->mRequestedTimer.getElapsedTimeF32(); @@ -2775,7 +3345,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r } fetch_priority = worker->getPriority(); can_use_http = worker->getCanUseHTTP() ; - worker->unlockWorkMutex(); + worker->unlockWorkMutex(); // -Mw } data_progress_p = data_progress; requested_priority_p = requested_priority; @@ -2799,12 +3369,219 @@ void LLTextureFetch::dump() << " STATE: " << worker->sStateDescs[worker->mState] << llendl; } + + llinfos << "LLTextureFetch ACTIVE_HTTP:" << llendl; + for (queue_t::const_iterator iter(mHTTPTextureQueue.begin()); + mHTTPTextureQueue.end() != iter; + ++iter) + { + llinfos << " ID: " << (*iter) << llendl; + } + + llinfos << "LLTextureFetch WAIT_HTTP_RESOURCE:" << llendl; + for (wait_http_res_queue_t::const_iterator iter(mHttpWaitResource.begin()); + mHttpWaitResource.end() != iter; + ++iter) + { + llinfos << " ID: " << (*iter) << llendl; + } +} + +////////////////////////////////////////////////////////////////////////////// + +// HTTP Resource Waiting Methods + +// Threads: Ttf +void LLTextureFetch::addHttpWaiter(const LLUUID & tid) +{ + mNetworkQueueMutex.lock(); // +Mfnq + mHttpWaitResource.insert(tid); + mNetworkQueueMutex.unlock(); // -Mfnq +} + +// Threads: Ttf +void LLTextureFetch::removeHttpWaiter(const LLUUID & tid) +{ + mNetworkQueueMutex.lock(); // +Mfnq + wait_http_res_queue_t::iterator iter(mHttpWaitResource.find(tid)); + if (mHttpWaitResource.end() != iter) + { + mHttpWaitResource.erase(iter); + } + mNetworkQueueMutex.unlock(); // -Mfnq +} + +// Threads: T* +bool LLTextureFetch::isHttpWaiter(const LLUUID & tid) +{ + mNetworkQueueMutex.lock(); // +Mfnq + wait_http_res_queue_t::iterator iter(mHttpWaitResource.find(tid)); + const bool ret(mHttpWaitResource.end() != iter); + mNetworkQueueMutex.unlock(); // -Mfnq + return ret; +} + +// Release as many requests as permitted from the WAIT_HTTP_RESOURCE2 +// state to the SEND_HTTP_REQ state based on their current priority. +// +// This data structures and code associated with this looks a bit +// indirect and naive but it's done in the name of safety. An +// ordered container may become invalid from time to time due to +// priority changes caused by actions in other threads. State itself +// could also suffer the same fate with canceled operations. Even +// done this way, I'm not fully trusting we're truly safe. This +// module is due for a major refactoring and we'll deal with it then. +// +// Threads: Ttf +// Locks: -Mw (must not hold any worker when called) +void LLTextureFetch::releaseHttpWaiters() +{ + // Use mHttpSemaphore rather than mHTTPTextureQueue.size() + // to avoid a lock. + if (mHttpSemaphore < (HTTP_REQUESTS_IN_QUEUE_HIGH_WATER - HTTP_REQUESTS_IN_QUEUE_LOW_WATER)) + return; + + // Quickly make a copy of all the LLUIDs. Get off the + // mutex as early as possible. + typedef std::vector<LLUUID> uuid_vec_t; + uuid_vec_t tids; + + { + LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq + + if (mHttpWaitResource.empty()) + return; + tids.reserve(mHttpWaitResource.size()); + tids.assign(mHttpWaitResource.begin(), mHttpWaitResource.end()); + } // -Mfnq + + // Now lookup the UUUIDs to find valid requests and sort + // them in priority order, highest to lowest. We're going + // to modify priority later as a side-effect of releasing + // these objects. That, in turn, would violate the partial + // ordering assumption of std::set, std::map, etc. so we + // don't use those containers. We use a vector and an explicit + // sort to keep the containers valid later. + typedef std::vector<LLTextureFetchWorker *> worker_list_t; + worker_list_t tids2; + + tids2.reserve(tids.size()); + for (uuid_vec_t::iterator iter(tids.begin()); + tids.end() != iter; + ++iter) + { + LLTextureFetchWorker * worker(getWorker(* iter)); + if (worker) + { + tids2.push_back(worker); + } + else + { + // If worker isn't found, this should be due to a request + // for deletion. We signal our recognition that this + // uuid shouldn't be used for resource waiting anymore by + // erasing it from the resource waiter list. That allows + // deleteOK to do final deletion on the worker. + removeHttpWaiter(* iter); + } + } + tids.clear(); + + // Sort into priority order, if necessary and only as much as needed + if (tids2.size() > mHttpSemaphore) + { + LLTextureFetchWorker::Compare compare; + std::partial_sort(tids2.begin(), tids2.begin() + mHttpSemaphore, tids2.end(), compare); + } + + // Release workers up to the high water mark. Since we aren't + // holding any locks at this point, we can be in competition + // with other callers. Do defensive things like getting + // refreshed counts of requests and checking if someone else + // has moved any worker state around.... + for (worker_list_t::iterator iter2(tids2.begin()); tids2.end() != iter2; ++iter2) + { + LLTextureFetchWorker * worker(* iter2); + + worker->lockWorkMutex(); // +Mw + if (LLTextureFetchWorker::WAIT_HTTP_RESOURCE2 != worker->mState) + { + // Not in expected state, remove it, try the next one + worker->unlockWorkMutex(); // -Mw + LL_WARNS("Texture") << "Resource-waited texture " << worker->mID + << " in unexpected state: " << worker->mState + << ". Removing from wait list." + << LL_ENDL; + removeHttpWaiter(worker->mID); + continue; + } + + if (! worker->acquireHttpSemaphore()) + { + // Out of active slots, quit + worker->unlockWorkMutex(); // -Mw + break; + } + + worker->mState = LLTextureFetchWorker::SEND_HTTP_REQ; + worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); + worker->unlockWorkMutex(); // -Mw + + removeHttpWaiter(worker->mID); + } +} + +// Threads: T* +void LLTextureFetch::cancelHttpWaiters() +{ + mNetworkQueueMutex.lock(); // +Mfnq + mHttpWaitResource.clear(); + mNetworkQueueMutex.unlock(); // -Mfnq +} + +// Threads: T* +int LLTextureFetch::getHttpWaitersCount() +{ + mNetworkQueueMutex.lock(); // +Mfnq + int ret(mHttpWaitResource.size()); + mNetworkQueueMutex.unlock(); // -Mfnq + return ret; +} + + +// Threads: T* +void LLTextureFetch::updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait) +{ + LLMutexLock lock(&mQueueMutex); // +Mfq + + mTotalCacheReadCount += cache_read; + mTotalCacheWriteCount += cache_write; + mTotalResourceWaitCount += res_wait; +} // -Mfq + + +// Threads: T* +void LLTextureFetch::getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait) +{ + U32 ret1(0U), ret2(0U), ret3(0U); + + { + LLMutexLock lock(&mQueueMutex); // +Mfq + ret1 = mTotalCacheReadCount; + ret2 = mTotalCacheWriteCount; + ret3 = mTotalResourceWaitCount; + } // -Mfq + + *cache_read = ret1; + *cache_write = ret2; + *res_wait = ret3; } ////////////////////////////////////////////////////////////////////////////// // cross-thread command methods +// Threads: T* void LLTextureFetch::commandSetRegion(U64 region_handle) { TFReqSetRegion * req = new TFReqSetRegion(region_handle); @@ -2812,6 +3589,7 @@ void LLTextureFetch::commandSetRegion(U64 region_handle) cmdEnqueue(req); } +// Threads: T* void LLTextureFetch::commandSendMetrics(const std::string & caps_url, const LLUUID & session_id, const LLUUID & agent_id, @@ -2822,6 +3600,7 @@ void LLTextureFetch::commandSendMetrics(const std::string & caps_url, cmdEnqueue(req); } +// Threads: T* void LLTextureFetch::commandDataBreak() { // The pedantically correct way to implement this is to create a command @@ -2832,30 +3611,33 @@ void LLTextureFetch::commandDataBreak() LLTextureFetch::svMetricsDataBreak = true; } +// Threads: T* void LLTextureFetch::cmdEnqueue(TFRequest * req) { - lockQueue(); + lockQueue(); // +Mfq mCommands.push_back(req); - unlockQueue(); + unlockQueue(); // -Mfq unpause(); } +// Threads: T* LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue() { TFRequest * ret = 0; - lockQueue(); + lockQueue(); // +Mfq if (! mCommands.empty()) { ret = mCommands.front(); mCommands.erase(mCommands.begin()); } - unlockQueue(); + unlockQueue(); // -Mfq return ret; } +// Threads: Ttf void LLTextureFetch::cmdDoWork() { if (mDebugPause) @@ -2879,6 +3661,37 @@ void LLTextureFetch::cmdDoWork() namespace { + +// Example of a simple notification handler for metrics +// delivery notification. Earlier versions of the code used +// a Responder that tried harder to detect delivery breaks +// but it really isn't that important. If someone wants to +// revisit that effort, here is a place to start. +class AssetReportHandler : public LLCore::HttpHandler +{ +public: + + // Threads: Ttf + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) + { + LLCore::HttpStatus status(response->getStatus()); + + if (status) + { + LL_WARNS("Texture") << "Successfully delivered asset metrics to grid." + << LL_ENDL; + } + else + { + LL_WARNS("Texture") << "Error delivering asset metrics to grid. Reason: " + << status.toString() << LL_ENDL; + } + } +}; // end class AssetReportHandler + +AssetReportHandler stats_handler; + + /** * Implements the 'Set Region' command. * @@ -2909,75 +3722,8 @@ TFReqSendMetrics::~TFReqSendMetrics() bool TFReqSendMetrics::doWork(LLTextureFetch * fetcher) { - /* - * HTTP POST responder. Doesn't do much but tries to - * detect simple breaks in recording the metrics stream. - * - * The 'volatile' modifiers don't indicate signals, - * mmap'd memory or threads, really. They indicate that - * the referenced data is part of a pseudo-closure for - * this responder rather than being required for correct - * operation. - * - * We don't try very hard with the POST request. We give - * it one shot and that's more-or-less it. With a proper - * refactoring of the LLQueuedThread usage, these POSTs - * could be put in a request object and made more reliable. - */ - class lcl_responder : public LLCurl::Responder - { - public: - lcl_responder(LLTextureFetch * fetcher, - S32 expected_sequence, - volatile const S32 & live_sequence, - volatile bool & reporting_break, - volatile bool & reporting_started) - : LLCurl::Responder(), - mFetcher(fetcher), - mExpectedSequence(expected_sequence), - mLiveSequence(live_sequence), - mReportingBreak(reporting_break), - mReportingStarted(reporting_started) - { - mFetcher->incrCurlPOSTCount(); - } - - ~lcl_responder() - { - LL_CHECK_MEMORY - mFetcher->decrCurlPOSTCount(); - LL_CHECK_MEMORY - } - - // virtual - void error(U32 status_num, const std::string & reason) - { - if (mLiveSequence == mExpectedSequence) - { - mReportingBreak = true; - } - LL_WARNS("Texture") << "Break in metrics stream due to POST failure to metrics collection service. Reason: " - << reason << LL_ENDL; - } - - // virtual - void result(const LLSD & content) - { - if (mLiveSequence == mExpectedSequence) - { - mReportingBreak = false; - mReportingStarted = true; - } - } - - private: - LLTextureFetch * mFetcher; - S32 mExpectedSequence; - volatile const S32 & mLiveSequence; - volatile bool & mReportingBreak; - volatile bool & mReportingStarted; - - }; // class lcl_responder + static const U32 report_priority(1); + static LLCore::HttpHandler * const handler(fetcher->isQAMode() || true ? &stats_handler : NULL); if (! gViewerAssetStatsThread1) return true; @@ -3005,21 +3751,26 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) // Update sequence number if (S32_MAX == ++report_sequence) report_sequence = 0; - + reporting_started = true; + // Limit the size of the stats report if necessary. merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd); if (! mCapsURL.empty()) { - LLCurlRequest::headers_t headers; - fetcher->getCurlRequest().post(mCapsURL, - headers, - merged_llsd, - new lcl_responder(fetcher, - report_sequence, - report_sequence, - LLTextureFetch::svMetricsDataBreak, - reporting_started)); + LLCore::BufferArray * ba = new LLCore::BufferArray; + LLCore::BufferArrayStream bas(ba); + LLSDSerialize::toXML(merged_llsd, bas); + + fetcher->getHttpRequest().requestPost(fetcher->getPolicyClass(), + report_priority, + mCapsURL, + ba, + NULL, + fetcher->getMetricsHeaders(), + handler); + ba->release(); + LLTextureFetch::svMetricsDataBreak = false; } else { @@ -3077,6 +3828,7 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics) } // end of anonymous namespace + /////////////////////////////////////////////////////////////////////////////////////////// //Start LLTextureFetchDebugger /////////////////////////////////////////////////////////////////////////////////////////// @@ -3130,47 +3882,13 @@ private: S32 mID; }; -class LLDebuggerHTTPResponder : public LLCurl::Responder -{ -public: - LLDebuggerHTTPResponder(LLTextureFetchDebugger* debugger, S32 index) - : mDebugger(debugger), mIndex(index) - { - } - virtual void completedRaw(U32 status, const std::string& reason, - const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) - { - bool success = false; - bool partial = false; - if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES) - { - success = true; - if (HTTP_PARTIAL_CONTENT == status) // partial information - { - partial = true; - } - } - if (!success) - { - llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl; - } - mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success); - } - virtual bool followRedir() - { - return true; - } -private: - LLTextureFetchDebugger* mDebugger; - S32 mIndex; -}; LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : mFetcher(fetcher), mTextureCache(cache), mImageDecodeThread(imagedecodethread), - mCurlGetRequest(NULL) + mHttpHeaders(NULL), + mHttpPolicyClass(fetcher->getPolicyClass()) { init(); } @@ -3178,7 +3896,13 @@ LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextur LLTextureFetchDebugger::~LLTextureFetchDebugger() { mFetchingHistory.clear(); - stopDebug(); + mStopDebug = TRUE; + tryToStopDebug(); + if (mHttpHeaders) + { + mHttpHeaders->release(); + mHttpHeaders = NULL; + } } void LLTextureFetchDebugger::init() @@ -3193,6 +3917,8 @@ void LLTextureFetchDebugger::init() mTotalFetchingTime = 0.f; mRefetchVisCacheTime = -1.f; mRefetchVisHTTPTime = -1.f; + mRefetchAllCacheTime = -1.f; + mRefetchAllHTTPTime = -1.f; mNumFetchedTextures = 0; mNumCacheHits = 0; @@ -3206,10 +3932,62 @@ void LLTextureFetchDebugger::init() mRenderedDecodedData = 0; mFetchedPixels = 0; mRenderedPixels = 0; - mRefetchedData = 0; - mRefetchedPixels = 0; + mRefetchedVisData = 0; + mRefetchedVisPixels = 0; + mRefetchedAllData = 0; + mRefetchedAllPixels = 0; mFreezeHistory = FALSE; + mStopDebug = FALSE; + mClearHistory = FALSE; + + if (! mHttpHeaders) + { + mHttpHeaders = new LLCore::HttpHeaders; + mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c"); + } +} + +void LLTextureFetchDebugger::startWork(e_debug_state state) +{ + switch(state) + { + case IDLE: + break; + case START_DEBUG: + startDebug(); + break; + case READ_CACHE: + debugCacheRead(); + break; + case WRITE_CACHE: + debugCacheWrite(); + break; + case DECODING: + debugDecoder(); + break; + case HTTP_FETCHING: + debugHTTP(); + break; + case GL_TEX: + debugGLTextureCreation(); + break; + case REFETCH_VIS_CACHE: + debugRefetchVisibleFromCache(); + break; + case REFETCH_VIS_HTTP: + debugRefetchVisibleFromHTTP(); + break; + case REFETCH_ALL_CACHE: + debugRefetchAllFromCache(); + break; + case REFETCH_ALL_HTTP: + debugRefetchAllFromHTTP(); + break; + default: + break; + } + return; } void LLTextureFetchDebugger::startDebug() @@ -3217,10 +3995,18 @@ void LLTextureFetchDebugger::startDebug() //lock the fetcher mFetcher->lockFetcher(true); mFreezeHistory = TRUE; + mFetcher->resetLoadSource(); //clear the current fetching queue gTextureList.clearFetchingRequests(); + mState = START_DEBUG; +} + +bool LLTextureFetchDebugger::processStartDebug(F32 max_time) +{ + mTimer.reset(); + //wait for all works to be done while(1) { @@ -3232,6 +4018,11 @@ void LLTextureFetchDebugger::startDebug() { break; } + + if(mTimer.getElapsedTimeF32() > max_time) + { + return false; + } } //collect statistics @@ -3270,10 +4061,17 @@ void LLTextureFetchDebugger::startDebug() } mNumFetchedTextures = fetched_textures.size(); + + return true; } -void LLTextureFetchDebugger::stopDebug() +void LLTextureFetchDebugger::tryToStopDebug() { + if(!mStopDebug) + { + return; + } + //clear the current debug work S32 size = mFetchingHistory.size(); switch(mState) @@ -3285,7 +4083,7 @@ void LLTextureFetchDebugger::stopDebug() { mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true); } - } + } break; case WRITE_CACHE: for(S32 i = 0 ; i < size; i++) @@ -3302,37 +4100,72 @@ void LLTextureFetchDebugger::stopDebug() break; case GL_TEX: break; + case REFETCH_VIS_CACHE: + break; + case REFETCH_VIS_HTTP: + break; + case REFETCH_ALL_CACHE: + mRefetchList.clear(); + break; + case REFETCH_ALL_HTTP: + mRefetchList.clear(); + break; default: break; } - while(1) + if(update(0.005f)) { - if(update()) + //unlock the fetcher + mFetcher->lockFetcher(false); + mFetcher->resetLoadSource(); + mFreezeHistory = FALSE; + mStopDebug = FALSE; + + if(mClearHistory) { - break; + mFetchingHistory.clear(); + mHandleToFetchIndex.clear(); + init(); + mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset } } - - //unlock the fetcher - mFetcher->lockFetcher(false); - mFreezeHistory = FALSE; - mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset } //called in the main thread and when the fetching queue is empty void LLTextureFetchDebugger::clearHistory() { - mFetchingHistory.clear(); - init(); + mClearHistory = TRUE; } void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) { + if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull()) + { + return; + } + if(mFreezeHistory) { - mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); - mRefetchedData += worker->mFormattedImage->getDataSize(); + if(mState == REFETCH_VIS_CACHE || mState == REFETCH_VIS_HTTP) + { + mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + mRefetchedVisData += worker->mFormattedImage->getDataSize(); + } + else + { + mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); + mRefetchedAllData += worker->mFormattedImage->getDataSize(); + + LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID); + if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end()) + { + if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) + { + mRefetchList[tex].erase(mRefetchList[tex].begin()); + } + } + } return; } @@ -3344,9 +4177,8 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) mDecodedData += worker->mRawImage->getDataSize(); mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); - mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); - //mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mHaveAllData ? 0 : worker->mLoadedDiscard, worker->mFormattedImage->getComponents(), - //worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); + mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, + worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); } void LLTextureFetchDebugger::lockCache() @@ -3363,6 +4195,7 @@ void LLTextureFetchDebugger::debugCacheRead() llassert_always(mState == IDLE); mTimer.reset(); mState = READ_CACHE; + mCacheReadTime = -1.f; S32 size = mFetchingHistory.size(); for(S32 i = 0 ; i < size ; i++) @@ -3398,6 +4231,7 @@ void LLTextureFetchDebugger::debugCacheWrite() llassert_always(mState == IDLE); mTimer.reset(); mState = WRITE_CACHE; + mCacheWriteTime = -1.f; S32 size = mFetchingHistory.size(); for(S32 i = 0 ; i < size ; i++) @@ -3407,7 +4241,7 @@ void LLTextureFetchDebugger::debugCacheWrite() mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1, - new LLDebuggerCacheWriteResponder(this, i)); + NULL, 0, new LLDebuggerCacheWriteResponder(this, i)); } } } @@ -3426,6 +4260,7 @@ void LLTextureFetchDebugger::debugDecoder() llassert_always(mState == IDLE); mTimer.reset(); mState = DECODING; + mDecodingTime = -1.f; S32 size = mFetchingHistory.size(); for(S32 i = 0 ; i < size ; i++) @@ -3461,6 +4296,7 @@ void LLTextureFetchDebugger::debugHTTP() mTimer.reset(); mState = HTTP_FETCHING; + mHTTPTime = -1.f; S32 size = mFetchingHistory.size(); for (S32 i = 0 ; i < size ; i++) @@ -3468,6 +4304,7 @@ void LLTextureFetchDebugger::debugHTTP() mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; mFetchingHistory[i].mCurlReceivedSize = 0; mFetchingHistory[i].mHTTPFailCount = 0; + mFetchingHistory[i].mFormattedImage = NULL; } mNbCurlRequests = 0; mNbCurlCompleted = 0; @@ -3477,30 +4314,51 @@ void LLTextureFetchDebugger::debugHTTP() S32 LLTextureFetchDebugger::fillCurlQueue() { - if (mNbCurlRequests == 24) + if(mStopDebug) //stop + { + mNbCurlCompleted = mFetchingHistory.size(); + return 0; + } + if (mNbCurlRequests > HTTP_REQUESTS_IN_QUEUE_LOW_WATER) + { return mNbCurlRequests; + } S32 size = mFetchingHistory.size(); for (S32 i = 0 ; i < size ; i++) { + mNbCurlRequests++; + if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) + { continue; + } std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str(); S32 requestedSize = mFetchingHistory[i].mRequestedSize; // We request the whole file if the size was not set. requestedSize = llmax(0,requestedSize); // We request the whole file if the size was set to an absurdly high value (meaning all file) requestedSize = (requestedSize == 33554432 ? 0 : requestedSize); - std::vector<std::string> headers; - headers.push_back("Accept: image/x-j2c"); - bool res = mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, new LLDebuggerHTTPResponder(this, i)); - if (res) + + LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass, + LLWorkerThread::PRIORITY_LOWBITS, + texture_url, + 0, + requestedSize, + NULL, + mHttpHeaders, + this); + if (LLCORE_HTTP_HANDLE_INVALID != handle) { + mHandleToFetchIndex[handle] = i; + mFetchingHistory[i].mHttpHandle = handle; mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; mNbCurlRequests++; // Hack - if (mNbCurlRequests == 24) + if (mNbCurlRequests == HTTP_REQUESTS_IN_QUEUE_HIGH_WATER) // emulate normal pipeline + { break; + } } else { @@ -3515,7 +4373,7 @@ void LLTextureFetchDebugger::debugGLTextureCreation() { llassert_always(mState == IDLE); mState = GL_TEX; - std::vector<LLViewerFetchedTexture*> tex_list; + mTempTexList.clear(); S32 size = mFetchingHistory.size(); for(S32 i = 0 ; i < size ; i++) @@ -3526,28 +4384,54 @@ void LLTextureFetchDebugger::debugGLTextureCreation() if(tex && !tex->isForSculptOnly()) { tex->destroyGLTexture() ; - tex_list.push_back(tex); + mTempTexList.push_back(tex); } } } + + mGLCreationTime = -1.f; + mTempIndex = 0; + mHistoryListIndex = 0; + + return; +} +bool LLTextureFetchDebugger::processGLCreation(F32 max_time) +{ mTimer.reset(); - S32 j = 0 ; - S32 size1 = tex_list.size(); - for(S32 i = 0 ; i < size && j < size1; i++) + + bool done = true; + S32 size = mFetchingHistory.size(); + S32 size1 = mTempTexList.size(); + for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++) { - if(mFetchingHistory[i].mRawImage.notNull()) + if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull()) { - if(mFetchingHistory[i].mID == tex_list[j]->getID()) + if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID()) { - tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel()); - j++; + mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel, + mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel()); + mTempIndex++; } } + + if(mTimer.getElapsedTimeF32() > max_time) + { + done = false; + break; + } } - mGLCreationTime = mTimer.getElapsedTimeF32() ; - return; + if(mGLCreationTime < 0.f) + { + mGLCreationTime = mTimer.getElapsedTimeF32() ; + } + else + { + mGLCreationTime += mTimer.getElapsedTimeF32() ; + } + + return done; } //clear fetching results of all textures. @@ -3564,15 +4448,62 @@ void LLTextureFetchDebugger::clearTextures() } } +void LLTextureFetchDebugger::makeRefetchList() +{ + mRefetchList.clear(); + S32 size = mFetchingHistory.size(); + for(S32 i = 0 ; i < size; i++) + { + LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID); + if(tex && tex->isJustBound()) //visible + { + continue; //the texture fetch pipeline will take care of visible textures. + } + + mRefetchList[tex].push_back(i); + } +} + +void LLTextureFetchDebugger::scanRefetchList() +{ + if(mStopDebug) + { + return; + } + if(!mRefetchNonVis) + { + return; + } + + for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin(); + iter != mRefetchList.end(); ) + { + if(iter->second.empty()) + { + gTextureList.setDebugFetching(iter->first, -1); + mRefetchList.erase(iter++); // This is the correct method to "erase and move on" in an std::map + } + else + { + gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel); + ++iter; + } + } +} + void LLTextureFetchDebugger::debugRefetchVisibleFromCache() { llassert_always(mState == IDLE); mState = REFETCH_VIS_CACHE; clearTextures(); - + mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); + mTimer.reset(); mFetcher->lockFetcher(false); + mRefetchVisCacheTime = -1.f; + mRefetchedVisData = 0; + mRefetchedVisPixels = 0; } void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() @@ -3580,17 +4511,60 @@ void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() llassert_always(mState == IDLE); mState = REFETCH_VIS_HTTP; - clearCache(); clearTextures(); + mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); + + mTimer.reset(); + mFetcher->lockFetcher(false); + mRefetchVisHTTPTime = -1.f; + mRefetchedVisData = 0; + mRefetchedVisPixels = 0; +} + +void LLTextureFetchDebugger::debugRefetchAllFromCache() +{ + llassert_always(mState == IDLE); + mState = REFETCH_ALL_CACHE; + + clearTextures(); + makeRefetchList(); + mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); mTimer.reset(); mFetcher->lockFetcher(false); + mRefetchAllCacheTime = -1.f; + mRefetchedAllData = 0; + mRefetchedAllPixels = 0; + mRefetchNonVis = FALSE; } -bool LLTextureFetchDebugger::update() +void LLTextureFetchDebugger::debugRefetchAllFromHTTP() +{ + llassert_always(mState == IDLE); + mState = REFETCH_ALL_HTTP; + + clearTextures(); + makeRefetchList(); + mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); + + mTimer.reset(); + mFetcher->lockFetcher(false); + mRefetchAllHTTPTime = -1.f; + mRefetchedAllData = 0; + mRefetchedAllPixels = 0; + mRefetchNonVis = TRUE; +} + +bool LLTextureFetchDebugger::update(F32 max_time) { switch(mState) { + case START_DEBUG: + if(processStartDebug(max_time)) + { + mState = IDLE; + } + break; case READ_CACHE: if(!mTextureCache->update(1)) { @@ -3616,8 +4590,8 @@ bool LLTextureFetchDebugger::update() } break; case HTTP_FETCHING: - mCurlGetRequest->process(); - LLCurl::getCurlThread()->update(1); + // Do some notifications... + mFetcher->getHttpRequest().update(10); if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size()) { mHTTPTime = mTimer.getElapsedTimeF32() ; @@ -3625,22 +4599,59 @@ bool LLTextureFetchDebugger::update() } break; case GL_TEX: - mState = IDLE; + if(processGLCreation(max_time)) + { + mState = IDLE; + mTempTexList.clear(); + } break; case REFETCH_VIS_CACHE: if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { - mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ; mState = IDLE; mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); } break; case REFETCH_VIS_HTTP: if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { - mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ; mState = IDLE; mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); + } + break; + case REFETCH_ALL_CACHE: + scanRefetchList(); + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + if(!mRefetchNonVis) + { + mRefetchNonVis = TRUE; //start to fetch non-vis + scanRefetchList(); + break; + } + + mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); + mRefetchList.clear(); + mRefetchNonVis = FALSE; + } + break; + case REFETCH_ALL_HTTP: + scanRefetchList(); + if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) + { + mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ; + mState = IDLE; + mFetcher->lockFetcher(true); + mFetcher->resetLoadSource(); + mRefetchList.clear(); + mRefetchNonVis = FALSE; } break; default: @@ -3651,6 +4662,28 @@ bool LLTextureFetchDebugger::update() return mState == IDLE; } +void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) +{ + handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle)); + if (mHandleToFetchIndex.end() == iter) + { + llinfos << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << llendl; + return; + } + + S32 fetch_ind(iter->second); + mHandleToFetchIndex.erase(iter); + if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle) + { + llinfos << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << llendl; + } + else + { + callbackHTTP(mFetchingHistory[fetch_ind], response); + mFetchingHistory[fetch_ind].mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; // Not valid after notification + } +} + void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal) { @@ -3677,50 +4710,60 @@ void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* r } } -void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer, - bool partial, bool success) +void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response) { + static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT); + + LLCore::HttpStatus status(response->getStatus()); mNbCurlRequests--; - if (success) + if (status) { - mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; + const bool partial(par_status == status); + LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body + + fetch.mCurlState = FetchEntry::CURL_DONE; mNbCurlCompleted++; - S32 data_size = buffer->countAfter(channels.in(), NULL); - mFetchingHistory[id].mCurlReceivedSize += data_size; - //llinfos << "Fetch Debugger : got results for " << id << ", data_size = " << data_size << ", received = " << mFetchingHistory[id].mCurlReceivedSize << ", requested = " << mFetchingHistory[id].mRequestedSize << ", partial = " << partial << llendl; - if ((mFetchingHistory[id].mCurlReceivedSize >= mFetchingHistory[id].mRequestedSize) || !partial || (mFetchingHistory[id].mRequestedSize == 600)) + S32 data_size = ba ? ba->size() : 0; + fetch.mCurlReceivedSize += data_size; + //llinfos << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << llendl; + if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600)) { U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); - buffer->readAfter(channels.in(), NULL, d_buffer, data_size); + if (ba) + { + ba->read(0, d_buffer, data_size); + } - llassert_always(mFetchingHistory[id].mFormattedImage.isNull()); + llassert_always(fetch.mFormattedImage.isNull()); { // For now, create formatted image based on extension - std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str(); + std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str(); std::string extension = gDirUtilp->getExtension(texture_url); - mFetchingHistory[id].mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); - if (mFetchingHistory[id].mFormattedImage.isNull()) + fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); + if (fetch.mFormattedImage.isNull()) { - mFetchingHistory[id].mFormattedImage = new LLImageJ2C; // default + fetch.mFormattedImage = new LLImageJ2C; // default } } - mFetchingHistory[id].mFormattedImage->setData(d_buffer, data_size); + fetch.mFormattedImage->setData(d_buffer, data_size); } } else //failed { - mFetchingHistory[id].mHTTPFailCount++; - if(mFetchingHistory[id].mHTTPFailCount < 5) + llinfos << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID + << ", status: " << status.toHex() + << " reason: " << status.toString() << llendl; + fetch.mHTTPFailCount++; + if(fetch.mHTTPFailCount < 5) { // Fetch will have to be redone - mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE; + fetch.mCurlState = FetchEntry::CURL_NOT_DONE; } else //skip { - mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; + fetch.mCurlState = FetchEntry::CURL_DONE; mNbCurlCompleted++; } } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 107e1623b0..3a99432b48 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,19 +27,24 @@ #ifndef LL_LLTEXTUREFETCH_H #define LL_LLTEXTUREFETCH_H +#include <vector> +#include <map> + #include "lldir.h" #include "llimage.h" #include "lluuid.h" #include "llworkerthread.h" -#include "llcurl.h" #include "lltextureinfo.h" #include "llapr.h" #include "llimageworker.h" -//#include "lltexturecache.h" +#include "llcurl.h" +#include "httprequest.h" +#include "httpoptions.h" +#include "httpheaders.h" +#include "httphandler.h" class LLViewerTexture; class LLTextureFetchWorker; -class HTTPGetResponder; class LLImageDecodeThread; class LLHost; class LLViewerAssetStats; @@ -47,10 +52,10 @@ class LLTextureFetchDebugger; class LLTextureCache; // Interface class + class LLTextureFetch : public LLWorkerThread { friend class LLTextureFetchWorker; - friend class HTTPGetResponder; public: LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); @@ -58,72 +63,201 @@ public: class TFRequest; - /*virtual*/ S32 update(F32 max_time_ms); - void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down. - void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down. + // Threads: Tmain + /*virtual*/ S32 update(F32 max_time_ms); + + // called in the main thread after the TextureCacheThread shuts down. + // Threads: Tmain + void shutDownTextureCacheThread(); + //called in the main thread after the ImageDecodeThread shuts down. + // Threads: Tmain + void shutDownImageDecodeThread(); + + // Threads: T* (but Tmain mostly) bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); + + // Requests that a fetch operation be deleted from the queue. + // If @cancel is true, also stops any I/O operations pending. + // Actual delete will be scheduled and performed later. + // + // Note: This *looks* like an override/variant of the + // base class's deleteRequest() but is functionally quite + // different. + // + // Threads: T* void deleteRequest(const LLUUID& id, bool cancel); + + void deleteAllRequests(); + + // Threads: T* bool getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux); + + // Threads: T* bool updateRequestPriority(const LLUUID& id, F32 priority); + // Threads: T* bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data); + + // Threads: T* bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data); + // Threads: T* (but not safe) void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; } + + // Threads: T* (but not safe) F32 getTextureBandwidth() { return mTextureBandwidth; } - // Debug + // Threads: T* BOOL isFromLocalCache(const LLUUID& id); + + // @return Magic number giving the internal state of the + // request. We should make these codes public if we're + // going to return them as a status value. + // + // Threads: T* S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p, U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http); + + // Debug utility - generally not safe void dump(); - S32 getNumRequests() ; - S32 getNumHTTPRequests() ; - U32 getTotalNumHTTPRequests() ; + + // Threads: T* + S32 getNumRequests(); + + // Threads: T* + S32 getNumHTTPRequests(); + + // Threads: T* + U32 getTotalNumHTTPRequests(); - // Public for access by callbacks + // Threads: T* S32 getPending(); + + // Threads: T* void lockQueue() { mQueueMutex.lock(); } + + // Threads: T* void unlockQueue() { mQueueMutex.unlock(); } + + // Threads: T* LLTextureFetchWorker* getWorker(const LLUUID& id); + + // Threads: T* + // Locks: Mfq LLTextureFetchWorker* getWorkerAfterLock(const LLUUID& id); - LLTextureInfo* getTextureInfo() { return &mTextureInfo; } - // Commands available to other threads to control metrics gathering operations. + + // Threads: T* void commandSetRegion(U64 region_handle); + + // Threads: T* void commandSendMetrics(const std::string & caps_url, const LLUUID & session_id, const LLUUID & agent_id, LLViewerAssetStats * main_stats); + + // Threads: T* void commandDataBreak(); - LLCurlRequest & getCurlRequest() { return *mCurlGetRequest; } + // Threads: T* + LLCore::HttpRequest & getHttpRequest() { return *mHttpRequest; } + + // Threads: T* + LLCore::HttpRequest::policy_t getPolicyClass() const { return mHttpPolicyClass; } + + // Return a pointer to the shared metrics headers definition. + // Does not increment the reference count, caller is required + // to do that to hold a reference for any length of time. + // + // Threads: T* + LLCore::HttpHeaders * getMetricsHeaders() const { return mHttpMetricsHeaders; } bool isQAMode() const { return mQAMode; } - // Curl POST counter maintenance - inline void incrCurlPOSTCount() { mCurlPOSTRequestCount++; } - inline void decrCurlPOSTCount() { mCurlPOSTRequestCount--; } + // ---------------------------------- + // HTTP resource waiting methods + + // Threads: T* + void addHttpWaiter(const LLUUID & tid); + + // Threads: T* + void removeHttpWaiter(const LLUUID & tid); + + // Threads: T* + bool isHttpWaiter(const LLUUID & tid); + // If there are slots, release one or more LLTextureFetchWorker + // requests from resource wait state (WAIT_HTTP_RESOURCE) to + // active (SEND_HTTP_REQ). + // + // Because this will modify state of many workers, you may not + // hold any Mw lock while calling. This makes it a little + // inconvenient to use but that's the rule. + // + // Threads: T* + // Locks: -Mw (must not hold any worker when called) + void releaseHttpWaiters(); + + // Threads: T* + void cancelHttpWaiters(); + + // Threads: T* + int getHttpWaitersCount(); + // ---------------------------------- + // Stats management + + // Add given counts to the global totals for the states/requests + // Threads: T* + void updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait); + + // Return the global counts + // Threads: T* + void getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait); + + // ---------------------------------- + protected: + // Threads: T* (but Ttf in practice) void addToNetworkQueue(LLTextureFetchWorker* worker); + + // Threads: T* void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); + + // Threads: T* void addToHTTPQueue(const LLUUID& id); - void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0); - void removeRequest(LLTextureFetchWorker* worker, bool cancel); + // XXX possible delete + // Threads: T* + void removeFromHTTPQueue(const LLUUID& id, S32 received_size); + + // Identical to @deleteRequest but with different arguments + // (caller already has the worker pointer). + // + // Threads: T* + void removeRequest(LLTextureFetchWorker* worker, bool cancel); + // Overrides from the LLThread tree + // Locks: Ct bool runCondition(); private: + // Threads: Tmain void sendRequestListToSimulators(); + + // Threads: Ttf /*virtual*/ void startThread(void); + + // Threads: Ttf /*virtual*/ void endThread(void); + + // Threads: Ttf /*virtual*/ void threadedUpdate(void); + + // Threads: Ttf void commonUpdate(); // Metrics command helpers @@ -134,6 +268,8 @@ private: * Takes ownership of the TFRequest object. * * Method locks the command queue. + * + * Threads: T* */ void cmdEnqueue(TFRequest *); @@ -144,6 +280,8 @@ private: * Caller acquires ownership of the object and must dispose of it. * * Method locks the command queue. + * + * Threads: T* */ TFRequest * cmdDequeue(); @@ -153,6 +291,8 @@ private: * additional commands. * * Method locks the command queue. + * + * Threads: Ttf */ void cmdDoWork(); @@ -172,43 +312,64 @@ private: LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; - LLCurlRequest* mCurlGetRequest; // Map of all requests by UUID typedef std::map<LLUUID,LLTextureFetchWorker*> map_t; - map_t mRequestMap; + map_t mRequestMap; // Mfq // Set of requests that require network data typedef std::set<LLUUID> queue_t; - queue_t mNetworkQueue; - queue_t mHTTPTextureQueue; + queue_t mNetworkQueue; // Mfnq + queue_t mHTTPTextureQueue; // Mfnq typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t; - cancel_queue_t mCancelQueue; - F32 mTextureBandwidth; - F32 mMaxBandwidth; + cancel_queue_t mCancelQueue; // Mfnq + F32 mTextureBandwidth; // <none> + F32 mMaxBandwidth; // Mfnq LLTextureInfo mTextureInfo; - U32 mHTTPTextureBits; + // XXX possible delete + U32 mHTTPTextureBits; // Mfnq + // XXX possible delete //debug use - U32 mTotalHTTPRequests ; + U32 mTotalHTTPRequests; // Out-of-band cross-thread command queue. This command queue // is logically tied to LLQueuedThread's list of // QueuedRequest instances and so must be covered by the // same locks. typedef std::vector<TFRequest *> command_queue_t; - command_queue_t mCommands; + command_queue_t mCommands; // Mfq // If true, modifies some behaviors that help with QA tasks. const bool mQAMode; - // Count of POST requests outstanding. We maintain the count - // indirectly in the CURL request responder's ctor and dtor and - // use it when determining whether or not to sleep the thread. Can't - // use the LLCurl module's request counter as it isn't thread compatible. - // *NOTE: Don't mix Atomic and static, apr_initialize must be called first. - LLAtomic32<S32> mCurlPOSTRequestCount; + // Interfaces and objects into the core http library used + // to make our HTTP requests. These replace the various + // LLCurl interfaces used in the past. + LLCore::HttpRequest * mHttpRequest; // Ttf + LLCore::HttpOptions * mHttpOptions; // Ttf + LLCore::HttpHeaders * mHttpHeaders; // Ttf + LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf + LLCore::HttpRequest::policy_t mHttpPolicyClass; // T* + + // We use a resource semaphore to keep HTTP requests in + // WAIT_HTTP_RESOURCE2 if there aren't sufficient slots in the + // transport. This keeps them near where they can be cheaply + // reprioritized rather than dumping them all across a thread + // where it's more expensive to get at them. Requests in either + // SEND_HTTP_REQ or WAIT_HTTP_REQ charge against the semaphore + // and tracking state transitions is critical to liveness. + LLAtomicS32 mHttpSemaphore; // Ttf + Tmain + + typedef std::set<LLUUID> wait_http_res_queue_t; + wait_http_res_queue_t mHttpWaitResource; // Mfnq + + // Cumulative stats on the states/requests issued by + // textures running through here. + U32 mTotalCacheReadCount; // Mfq + U32 mTotalCacheWriteCount; // Mfq + U32 mTotalResourceWaitCount; // Mfq public: // A probabilistically-correct indicator that the current @@ -216,19 +377,35 @@ public: // reporting due to either startup or a problem POSTing data. static volatile bool svMetricsDataBreak; +public: + //debug use + enum e_tex_source + { + FROM_ALL = 0, + FROM_HTTP_ONLY, + INVALID_SOURCE + }; private: //debug use LLTextureFetchDebugger* mFetchDebugger; bool mFetcherLocked; + + e_tex_source mFetchSource; + e_tex_source mOriginFetchSource; public: //debug use LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;} void lockFetcher(bool lock) { mFetcherLocked = lock;} + + void setLoadSource(e_tex_source source) {mFetchSource = source;} + void resetLoadSource() {mFetchSource = mOriginFetchSource;} + bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;} }; //debug use -class LLTextureFetchDebugger +class LLViewerFetchedTexture; +class LLTextureFetchDebugger : public LLCore::HttpHandler { friend class LLTextureFetch; public: @@ -239,6 +416,7 @@ public: enum e_debug_state { IDLE = 0, + START_DEBUG, READ_CACHE, WRITE_CACHE, DECODING, @@ -272,11 +450,13 @@ private: e_curl_state mCurlState; S32 mCurlReceivedSize; S32 mHTTPFailCount; + LLCore::HttpHandle mHttpHandle; FetchEntry() : mDecodedLevel(-1), mFetchedSize(0), - mDecodedSize(0) + mDecodedSize(0), + mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) {} FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) : mID(id), @@ -285,10 +465,15 @@ private: mFetchedSize(f_size), mDecodedSize(d_size), mNeedsAux(false), - mHTTPFailCount(0) + mHTTPFailCount(0), + mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) {} }; - std::vector<FetchEntry> mFetchingHistory; + typedef std::vector<FetchEntry> fetch_list_t; + fetch_list_t mFetchingHistory; + + typedef std::map<LLCore::HttpHandle, S32> handle_fetch_map_t; + handle_fetch_map_t mHandleToFetchIndex; e_debug_state mState; @@ -301,13 +486,16 @@ private: F32 mTotalFetchingTime; F32 mRefetchVisCacheTime; F32 mRefetchVisHTTPTime; + F32 mRefetchAllCacheTime; + F32 mRefetchAllHTTPTime; LLTimer mTimer; LLTextureFetch* mFetcher; LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; - LLCurlRequest* mCurlGetRequest; + LLCore::HttpHeaders* mHttpHeaders; + LLCore::HttpRequest::policy_t mHttpPolicyClass; S32 mNumFetchedTextures; S32 mNumCacheHits; @@ -321,42 +509,44 @@ private: U32 mRenderedDecodedData; U32 mFetchedPixels; U32 mRenderedPixels; - U32 mRefetchedData; - U32 mRefetchedPixels; + U32 mRefetchedVisData; + U32 mRefetchedVisPixels; + U32 mRefetchedAllData; + U32 mRefetchedAllPixels; BOOL mFreezeHistory; + BOOL mStopDebug; + BOOL mClearHistory; + BOOL mRefetchNonVis; std::string mHTTPUrl; S32 mNbCurlRequests; S32 mNbCurlCompleted; + std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; + std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList; + S32 mTempIndex; + S32 mHistoryListIndex; + public: - bool update(); //called in the main thread once per frame + bool update(F32 max_time); //called in the main thread once per frame //fetching history void clearHistory(); void addHistoryEntry(LLTextureFetchWorker* worker); - void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;} - - void startDebug(); - void stopDebug(); //stop everything - void debugCacheRead(); - void debugCacheWrite(); - void debugHTTP(); - void debugDecoder(); - void debugGLTextureCreation(); - void debugRefetchVisibleFromCache(); - void debugRefetchVisibleFromHTTP(); + // Inherited from LLCore::HttpHandler + // Threads: Ttf + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + void startWork(e_debug_state state); + void setStopDebug() {mStopDebug = TRUE;} + void tryToStopDebug(); //stop everything void callbackCacheRead(S32 id, bool success, LLImageFormatted* image, S32 imagesize, BOOL islocal); void callbackCacheWrite(S32 id, bool success); void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux); - void callbackHTTP(S32 id, const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer, - bool partial, bool success); - + void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response); e_debug_state getState() {return mState;} S32 getNumFetchedTextures() {return mNumFetchedTextures;} @@ -372,8 +562,10 @@ public: U32 getRenderedDecodedData() {return mRenderedDecodedData;} U32 getFetchedPixels() {return mFetchedPixels;} U32 getRenderedPixels() {return mRenderedPixels;} - U32 getRefetchedData() {return mRefetchedData;} - U32 getRefetchedPixels() {return mRefetchedPixels;} + U32 getRefetchedVisData() {return mRefetchedVisData;} + U32 getRefetchedVisPixels() {return mRefetchedVisPixels;} + U32 getRefetchedAllData() {return mRefetchedAllData;} + U32 getRefetchedAllPixels() {return mRefetchedAllPixels;} F32 getCacheReadTime() {return mCacheReadTime;} F32 getCacheWriteTime() {return mCacheWriteTime;} @@ -383,11 +575,15 @@ public: F32 getTotalFetchingTime() {return mTotalFetchingTime;} F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;} F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;} + F32 getRefetchAllCacheTime() {return mRefetchAllCacheTime;} + F32 getRefetchAllHTTPTime() {return mRefetchAllHTTPTime;} private: void init(); void clearTextures();//clear fetching results of all textures. void clearCache(); + void makeRefetchList(); + void scanRefetchList(); void lockFetcher(); void unlockFetcher(); @@ -400,6 +596,20 @@ private: S32 fillCurlQueue(); + void startDebug(); + void debugCacheRead(); + void debugCacheWrite(); + void debugHTTP(); + void debugDecoder(); + void debugGLTextureCreation(); + void debugRefetchVisibleFromCache(); + void debugRefetchVisibleFromHTTP(); + void debugRefetchAllFromCache(); + void debugRefetchAllFromHTTP(); + + bool processStartDebug(F32 max_time); + bool processGLCreation(F32 max_time); + private: static bool sDebuggerEnabled; public: diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 52d085dd2c..16c42dbd43 100644..100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -74,7 +74,7 @@ static std::string title_string4(" W x H (Dis) Mem"); static S32 title_x1 = 0; static S32 title_x2 = 460; static S32 title_x3 = title_x2 + 40; -static S32 title_x4 = title_x3 + 50; +static S32 title_x4 = title_x3 + 46; static S32 texture_bar_height = 8; //////////////////////////////////////////////////////////////////////////// @@ -232,6 +232,8 @@ void LLTextureBar::draw() { "DSK", LLColor4::blue }, // CACHE_POST { "NET", LLColor4::green }, // LOAD_FROM_NETWORK { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR + { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE + { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2 { "REQ", LLColor4::yellow },// SEND_HTTP_REQ { "HTP", LLColor4::green }, // WAIT_HTTP_REQ { "DEC", LLColor4::yellow },// DECODE_IMAGE @@ -239,7 +241,7 @@ void LLTextureBar::draw() { "WRT", LLColor4::purple },// WRITE_TO_CACHE { "WRT", LLColor4::orange },// WAIT_ON_WRITE { "END", LLColor4::red }, // DONE -#define LAST_STATE 12 +#define LAST_STATE 14 { "CRE", LLColor4::magenta }, // LAST_STATE+1 { "FUL", LLColor4::green }, // LAST_STATE+2 { "BAD", LLColor4::red }, // LAST_STATE+3 @@ -345,7 +347,7 @@ void LLTextureBar::draw() // draw the image size at the end { - std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(), + std::string num_str = llformat("%3dx%3d (%2d) %7d", mImagep->getWidth(), mImagep->getHeight(), mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0); LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); @@ -514,14 +516,18 @@ void LLGLTexMemBar::draw() S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); - U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; + U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests(); //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); LLColor4 color; - - std::string text = ""; + // Gray background using completely magic numbers + gGL.color4f(0.f, 0.f, 0.f, 0.25f); + // const LLRect & rect(getRect()); + // gl_rect_2d(-4, v_offset, rect.mRight - rect.mLeft + 2, v_offset + line_height*4); + + std::string text = ""; LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6, text_color, LLFontGL::LEFT, LLFontGL::TOP); @@ -531,14 +537,26 @@ void LLGLTexMemBar::draw() bound_mem, max_bound_mem, LLRenderTarget::sBytesAllocated/(1024*1024), - LLImageRaw::sGlobalRawMemory >> 20, discard_bias, - cache_usage, cache_max_usage); + LLImageRaw::sGlobalRawMemory >> 20, + discard_bias, + cache_usage, + cache_max_usage); + //, cache_entries, cache_max_entries + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4, text_color, LLFontGL::LEFT, LLFontGL::TOP); - text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", - total_texture_downloaded, total_object_downloaded, total_http_requests); - //, cache_entries, cache_max_entries + U32 cache_read(0U), cache_write(0U), res_wait(0U); + LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait); + + text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u", + total_texture_downloaded, + total_object_downloaded, + total_http_requests, + cache_read, + cache_write, + res_wait); + LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, text_color, LLFontGL::LEFT, LLFontGL::TOP); diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 0eec7f0afd..9dfb29b905 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -118,7 +118,7 @@ LLToast::LLToast(const LLToast::Params& p) { mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs)); - buildFromFile("panel_toast.xml", NULL); + buildFromFile("panel_toast.xml"); setCanDrag(FALSE); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index d629f3abac..602b924398 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -334,32 +334,24 @@ void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair } U32 ignore_btn_width = 0; + U32 mute_btn_pad = 0; if (mIsScriptDialog && ignore_btn != NULL) { LLRect ignore_btn_rect(ignore_btn->getRect()); - S32 buttons_per_row = max_width / BUTTON_WIDTH; //assume that h_pad far less than BUTTON_WIDTH - S32 ignore_btn_left = buttons_per_row * BUTTON_WIDTH + (buttons_per_row - 1) * h_pad - ignore_btn_rect.getWidth(); - if (ignore_btn_left + ignore_btn_rect.getWidth() > max_width)// make sure that the ignore button is in panel - { - ignore_btn_left = max_width - ignore_btn_rect.getWidth() - 2 * HPAD; - } + S32 ignore_btn_left = max_width - ignore_btn_rect.getWidth(); ignore_btn_rect.setOriginAndSize(ignore_btn_left, BOTTOM_PAD,// always move ignore button at the bottom ignore_btn_rect.getWidth(), ignore_btn_rect.getHeight()); ignore_btn->setRect(ignore_btn_rect); ignore_btn_width = ignore_btn_rect.getWidth(); mControlPanel->addChild(ignore_btn, -1); + mute_btn_pad = 4 * HPAD; //only use a 4 * HPAD padding if an ignore button exists } if (mIsScriptDialog && mute_btn != NULL) { LLRect mute_btn_rect(mute_btn->getRect()); - S32 buttons_per_row = max_width / BUTTON_WIDTH; //assume that h_pad far less than BUTTON_WIDTH // Place mute (Block) button to the left of the ignore button. - S32 mute_btn_left = buttons_per_row * BUTTON_WIDTH + (buttons_per_row - 1) * h_pad - mute_btn_rect.getWidth() - ignore_btn_width - (h_pad / 2); - if (mute_btn_left + mute_btn_rect.getWidth() > max_width) // make sure that the mute button is in panel - { - mute_btn_left = max_width - mute_btn_rect.getWidth() - 2 * HPAD; - } + S32 mute_btn_left = max_width - mute_btn_rect.getWidth() - ignore_btn_width - mute_btn_pad; mute_btn_rect.setOriginAndSize(mute_btn_left, BOTTOM_PAD,// always move mute button at the bottom mute_btn_rect.getWidth(), mute_btn_rect.getHeight()); mute_btn->setRect(mute_btn_rect); diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp index a8a918f259..04c2e27c9d 100644 --- a/indra/newview/llviewerhelp.cpp +++ b/indra/newview/llviewerhelp.cpp @@ -71,12 +71,6 @@ LLHelpHandler gHelpHandler; std::string LLViewerHelp::getURL(const std::string &topic) { - // allow overriding the help server with a local help file - if( gSavedSettings.getBOOL("HelpUseLocal") ) - { - return "__local"; - } - // if the help topic is empty, use the default topic std::string help_topic = topic; if (help_topic.empty()) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 1eb4bedfaf..47059b0b8c 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1184,12 +1184,9 @@ void LLViewerMedia::clearAllCookies() LLDirIterator dir_iter(base_dir, "*_*"); while (dir_iter.next(filename)) { - target = base_dir; - target += filename; - target += gDirUtilp->getDirDelimiter(); - target += "browser_profile"; - target += gDirUtilp->getDirDelimiter(); - target += "cookies"; + target = gDirUtilp->add(base_dir, filename); + gDirUtilp->append(target, "browser_profile"); + gDirUtilp->append(target, "cookies"); lldebugs << "target = " << target << llendl; if(LLFile::isfile(target)) { @@ -1197,10 +1194,8 @@ void LLViewerMedia::clearAllCookies() } // Other accounts may have new-style cookie files too -- delete them as well - target = base_dir; - target += filename; - target += gDirUtilp->getDirDelimiter(); - target += PLUGIN_COOKIE_FILE_NAME; + target = gDirUtilp->add(base_dir, filename); + gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME); lldebugs << "target = " << target << llendl; if(LLFile::isfile(target)) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 1447f133e6..f9342a9736 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -238,7 +238,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mRotTime(0.f), mAngularVelocityRot(), mPreviousRotation(), - mJointInfo(NULL), mState(0), mMedia(NULL), mClickAction(0), @@ -284,12 +283,6 @@ LLViewerObject::~LLViewerObject() mInventory = NULL; } - if (mJointInfo) - { - delete mJointInfo; - mJointInfo = NULL; - } - if (mPartSourcep) { mPartSourcep->setDead(); @@ -340,9 +333,6 @@ void LLViewerObject::markDead() if (getParent()) { ((LLViewerObject *)getParent())->removeChild(this); - // go ahead and delete any jointinfo's that we find - delete mJointInfo; - mJointInfo = NULL; } // Mark itself as dead @@ -745,7 +735,7 @@ void LLViewerObject::addThisAndNonJointChildren(std::vector<LLViewerObject*>& ob iter != mChildList.end(); iter++) { LLViewerObject* child = *iter; - if ( (!child->isAvatar()) && (!child->isJointChild())) + if ( (!child->isAvatar())) { child->addThisAndNonJointChildren(objects); } @@ -796,6 +786,12 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) LLDrawable* old_parent = mDrawable->mParent; mDrawable->mParent = parentp; + if (parentp && mDrawable->isActive()) + { + parentp->makeActive(); + parentp->setState(LLDrawable::ACTIVE_CHILD); + } + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); if( (old_parent != parentp && old_parent) || (parentp && parentp->isActive())) @@ -1298,26 +1294,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } } - U8 joint_type = 0; - mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_JointType, joint_type, block_num); - if (joint_type) - { - // create new joint info - if (!mJointInfo) - { - mJointInfo = new LLVOJointInfo; - } - mJointInfo->mJointType = (EHavokJointType) joint_type; - mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointPivot, mJointInfo->mPivot, block_num); - mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointAxisOrAnchor, mJointInfo->mAxisOrAnchor, block_num); - } - else if (mJointInfo) - { - // this joint info is no longer needed - delete mJointInfo; - mJointInfo = NULL; - } - break; } @@ -1436,8 +1412,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, val = (U16 *) &data[count]; #endif new_angv.set(U16_to_F32(val[VX], -size, size), - U16_to_F32(val[VY], -size, size), - U16_to_F32(val[VZ], -size, size)); + U16_to_F32(val[VY], -size, size), + U16_to_F32(val[VZ], -size, size)); setAngularVelocity(new_angv); break; @@ -1463,8 +1439,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f); new_angv.set(U8_to_F32(data[13], -size, size), - U8_to_F32(data[14], -size, size), - U8_to_F32(data[15], -size, size)); + U8_to_F32(data[14], -size, size), + U8_to_F32(data[15], -size, size) ); setAngularVelocity(new_angv); break; } @@ -1538,8 +1514,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, dp->unpackU16(val[VY], "AccY"); dp->unpackU16(val[VZ], "AccZ"); new_angv.set(U16_to_F32(val[VX], -64.f, 64.f), - U16_to_F32(val[VY], -64.f, 64.f), - U16_to_F32(val[VZ], -64.f, 64.f)); + U16_to_F32(val[VY], -64.f, 64.f), + U16_to_F32(val[VZ], -64.f, 64.f)); setAngularVelocity(new_angv); } break; @@ -1968,14 +1944,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, cur_parentp->removeChild(this); - if (mJointInfo && !parent_id) - { - // since this object is no longer parent-relative - // we make sure we delete any joint info - delete mJointInfo; - mJointInfo = NULL; - } - setChanged(MOVED | SILHOUETTE); if (mDrawable.notNull()) @@ -2078,7 +2046,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, || (new_angv != old_angv)) { if (new_rot != mPreviousRotation) - { + { resetRot(); } else if (new_angv != old_angv) @@ -2116,9 +2084,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, gPipeline.addDebugBlip(getPositionAgent(), color); } - if ((0.0f == vel_mag_sq) && - (0.0f == accel_mag_sq) && - (0.0f == getAngularVelocity().magVecSquared())) + const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO; + + llassert(vel_mag_sq >= 0.f); + llassert(accel_mag_sq >= 0.f); + llassert(getAngularVelocity().magVecSquared() >= 0.f); + + if ((MAG_CUTOFF >= vel_mag_sq) && + (MAG_CUTOFF >= accel_mag_sq) && + (MAG_CUTOFF >= getAngularVelocity().magVecSquared())) { mStatic = TRUE; // This object doesn't move! } @@ -2189,17 +2163,13 @@ BOOL LLViewerObject::isActive() const -BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { //static LLFastTimer::DeclareTimer ftm("Viewer Object"); //LLFastTimer t(ftm); - if (mDead) + if (!mDead) { - // It's dead. Don't update it. - return TRUE; - } - // CRO - don't velocity interp linked objects! // Leviathan - but DO velocity interp joints if (!mStatic && sVelocityInterpolate && !isSelected()) @@ -2208,88 +2178,12 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) F32 dt_raw = (F32)(time - mLastInterpUpdateSecs); F32 dt = mTimeDilation * dt_raw; - if (!mJointInfo) - { applyAngularVelocity(dt); - } - - LLViewerObject *parentp = (LLViewerObject *) getParent(); - if (mJointInfo) - { - if (parentp) - { - // do parent-relative stuff - LLVector3 ang_vel = getAngularVelocity(); - F32 omega = ang_vel.magVecSquared(); - F32 angle = 0.0f; - LLQuaternion dQ; - if (omega > 0.00001f) - { - omega = sqrt(omega); - angle = omega * dt; - dQ.setQuat(angle, ang_vel); - } - LLVector3 pos = getPosition(); - - if (HJT_HINGE == mJointInfo->mJointType) - { - // hinge = uniform circular motion - LLVector3 parent_pivot = getVelocity(); - LLVector3 parent_axis = getAcceleration(); - - angle = dt * (ang_vel * mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis - dQ.setQuat(angle, mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis - LLVector3 pivot_offset = pos - mJointInfo->mPivot; // pos in pivot-frame - pivot_offset = pivot_offset * dQ; // new rotated pivot-frame pos - pos = mJointInfo->mPivot + pivot_offset; // parent-frame - LLViewerObject::setPosition(pos); - LLQuaternion Q_PC = getRotation(); - setRotation(Q_PC * dQ); - mLastInterpUpdateSecs = time; - } - else if (HJT_POINT == mJointInfo->mJointType) - // || HJT_LPOINT == mJointInfo->mJointType) - { - // point-to-point = spin about axis and uniform circular motion - // of axis about the pivot point - // - // NOTE: this interpolation scheme is not quite good enough to - // reduce the bandwidth -- needs a gravitational correction. - // Similarly for hinges with axes that deviate from vertical. - - LLQuaternion Q_PC = getRotation(); - Q_PC = Q_PC * dQ; - setRotation(Q_PC); - LLVector3 pivot_to_child = - mJointInfo->mAxisOrAnchor; // AxisOrAnchor = anchor - pos = mJointInfo->mPivot + pivot_to_child * Q_PC; - LLViewerObject::setPosition(pos); - mLastInterpUpdateSecs = time; - } - /* else if (HJT_WHEEL == mJointInfo->mJointInfo) + if (isAttachment()) { - // wheel = uniform rotation about axis, with linear - // velocity interpolation (if any) - LLVector3 parent_axis = getAcceleration(); // HACK -- accel stores the parent-axis (parent-frame) - - LLQuaternion Q_PC = getRotation(); - - angle = dt * (parent_axis * ang_vel); - dQ.setQuat(angle, parent_axis); - - Q_PC = Q_PC * dQ; - setRotation(Q_PC); - - pos = getPosition() + dt * getVelocity(); - LLViewerObject::setPosition(pos); mLastInterpUpdateSecs = time; - }*/ - } - } - else if (isAttachment()) - { - mLastInterpUpdateSecs = time; - return TRUE; + return; } else { // Move object based on it's velocity and rotation @@ -2298,8 +2192,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } updateDrawable(FALSE); - - return TRUE; + } } @@ -3889,15 +3782,6 @@ void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped) ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset); updateDrawable(damped); } - else if (isJointChild()) - { - // compute new parent-relative position - LLViewerObject *parent = (LLViewerObject *) getParent(); - LLQuaternion inv_parent_rot = parent->getRotation(); - inv_parent_rot.transQuat(); - LLVector3 pos_parent = (pos_edit - parent->getPositionRegion()) * inv_parent_rot; - LLViewerObject::setPosition(pos_parent, damped); - } else { LLViewerObject::setPosition(pos_edit, damped); @@ -3911,8 +3795,7 @@ LLViewerObject* LLViewerObject::getRootEdit() const { const LLViewerObject* root = this; while (root->mParent - && !(root->mJointInfo - || ((LLViewerObject*)root->mParent)->isAvatar()) ) + && !((LLViewerObject*)root->mParent)->isAvatar()) { root = (LLViewerObject*)root->mParent; } @@ -4621,19 +4504,11 @@ void LLViewerObject::clearIcon() LLViewerObject* LLViewerObject::getSubParent() { - if (isJointChild()) - { - return this; - } return (LLViewerObject*) getParent(); } const LLViewerObject* LLViewerObject::getSubParent() const { - if (isJointChild()) - { - return this; - } return (const LLViewerObject*) getParent(); } @@ -5503,9 +5378,12 @@ BOOL LLViewerObject::setFlagsWithoutUpdate(U32 flags, BOOL state) void LLViewerObject::setPhysicsShapeType(U8 type) { mPhysicsShapeUnknown = false; + if (type != mPhysicsShapeType) + { mPhysicsShapeType = type; mCostStale = true; } +} void LLViewerObject::setPhysicsGravity(F32 gravity) { @@ -5531,7 +5409,6 @@ U8 LLViewerObject::getPhysicsShapeType() const { if (mPhysicsShapeUnknown) { - mPhysicsShapeUnknown = false; gObjectList.updatePhysicsFlags(this); } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 6f5f7aae42..1fb30db8f2 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -88,18 +88,6 @@ typedef void (*inventory_callback)(LLViewerObject*, S32 serial_num, void*); -// a small struct for keeping track of joints -struct LLVOJointInfo -{ - EHavokJointType mJointType; - LLVector3 mPivot; // parent-frame - // whether the below an axis or anchor (and thus its frame) - // depends on the joint type: - // HINGE ==> axis=parent-frame - // P2P ==> anchor=child-frame - LLVector3 mAxisOrAnchor; -}; - // for exporting textured materials from SL struct LLMaterialExportInfo { @@ -157,7 +145,7 @@ public: LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name // Object create and update functions - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Types of media we can associate enum { MEDIA_NONE = 0, MEDIA_SET = 1 }; @@ -188,8 +176,6 @@ public: virtual void updateRadius() {}; virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius() - BOOL isJointChild() const { return mJointInfo ? TRUE : FALSE; } - EHavokJointType getJointType() const { return mJointInfo ? mJointInfo->mJointType : HJT_INVALID; } // for jointed and other parent-relative hacks LLViewerObject* getSubParent(); const LLViewerObject* getSubParent() const; @@ -741,7 +727,6 @@ protected: LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations LLQuaternion mPreviousRotation; - LLVOJointInfo* mJointInfo; U8 mState; // legacy LLViewerObjectMedia* mMedia; // NULL if no media associated U8 mClickAction; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index b433484783..3eeab0bf3e 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -49,6 +49,8 @@ #include "llstring.h" #include "llhudnametag.h" #include "lldrawable.h" +#include "llflexibleobject.h" +#include "llviewertextureanim.h" #include "xform.h" #include "llsky.h" #include "llviewercamera.h" @@ -78,11 +80,9 @@ extern F32 gMinObjectDistance; extern BOOL gAnimateTextures; -void dialog_refresh_all(); +#define MAX_CONCURRENT_PHYSICS_REQUESTS 256 -#define CULL_VIS -//#define ORPHAN_SPAM -//#define IGNORE_DEAD +void dialog_refresh_all(); // Global lists of objects - should go away soon. LLViewerObjectList gObjectList; @@ -909,8 +909,6 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) const F64 frame_time = LLFrameTimer::getElapsedSeconds(); - std::vector<LLViewerObject*> kill_list; - S32 num_active_objects = 0; LLViewerObject *objectp = NULL; // Make a copy of the list in case something in idleUpdate() messes with it @@ -950,7 +948,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count; if (gSavedSettings.getBOOL("FreezeTime")) - { + { for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin(); iter != idle_end; iter++) @@ -968,24 +966,20 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) idle_iter != idle_end; idle_iter++) { objectp = *idle_iter; - if (objectp->idleUpdate(agent, world, frame_time)) - { - num_active_objects++; - } - else - { - // If Idle Update returns false, kill object! - kill_list.push_back(objectp); - } - } - for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin(); - kill_iter != kill_list.end(); kill_iter++) - { - objectp = *kill_iter; - killObject(objectp); + llassert(objectp->isActive()); + objectp->idleUpdate(agent, world, frame_time); + } + + //update flexible objects + LLVolumeImplFlexible::updateClass(); + + //update animated textures + LLViewerTextureAnim::updateClass(); } + + fetchObjectCosts(); fetchPhysicsFlags(); @@ -1052,7 +1046,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) */ LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size()); - LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects); + LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count); LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled); LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); } @@ -1073,8 +1067,6 @@ void LLViewerObjectList::fetchObjectCosts() LLSD id_list; U32 object_index = 0; - U32 count = 0; - for ( std::set<LLUUID>::iterator iter = mStaleObjectCost.begin(); iter != mStaleObjectCost.end(); @@ -1091,7 +1083,7 @@ void LLViewerObjectList::fetchObjectCosts() mStaleObjectCost.erase(iter++); - if (count++ >= 450) + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) { break; } @@ -1136,7 +1128,7 @@ void LLViewerObjectList::fetchPhysicsFlags() for ( std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin(); iter != mStalePhysicsFlags.end(); - ++iter) + ) { // Check to see if a request for this object // has already been made. @@ -1146,12 +1138,14 @@ void LLViewerObjectList::fetchPhysicsFlags() mPendingPhysicsFlags.insert(*iter); id_list[object_index++] = *iter; } - } - // id_list should now contain all - // requests in mStalePhysicsFlags before, so clear - // it now - mStalePhysicsFlags.clear(); + mStalePhysicsFlags.erase(iter++); + + if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS) + { + break; + } + } if ( id_list.size() > 0 ) { diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 2bb2e92279..77e382b8c7 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1658,9 +1658,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // Request access list information for this land parcel_mgr.sendParcelAccessListRequest(AL_ACCESS | AL_BAN); - // Request the media url filter list for this land - parcel_mgr.requestParcelMediaURLFilter(); - // Request dwell for this land, if it's not public land. parcel_mgr.mSelectedDwell = DWELL_NAN; if (0 != local_id) @@ -1989,67 +1986,6 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which) } } -class LLParcelMediaURLFilterResponder : public LLHTTPClient::Responder -{ - virtual void result(const LLSD& content) - { - LLViewerParcelMgr::getInstance()->receiveParcelMediaURLFilter(content); - } -}; - -void LLViewerParcelMgr::requestParcelMediaURLFilter() -{ - if (!mSelected) - { - return; - } - - LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); - if (!region) - { - return; - } - - LLParcel* parcel = mCurrentParcel; - if (!parcel) - { - llwarns << "no parcel" << llendl; - return; - } - - LLSD body; - body["local-id"] = parcel->getLocalID(); - body["list"] = parcel->getMediaURLFilterList(); - - std::string url = region->getCapability("ParcelMediaURLFilterList"); - if (!url.empty()) - { - LLHTTPClient::post(url, body, new LLParcelMediaURLFilterResponder); - } - else - { - llwarns << "can't get ParcelMediaURLFilterList cap" << llendl; - } -} - - -void LLViewerParcelMgr::receiveParcelMediaURLFilter(const LLSD &content) -{ - if (content.has("list")) - { - LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel; - if (!parcel) return; - - if (content["local-id"].asInteger() == parcel->getLocalID()) - { - parcel->setMediaURLFilterList(content["list"]); - - LLViewerParcelMgr::getInstance()->notifyObservers(); - } - } -} - - void LLViewerParcelMgr::deedLandToGroup() { std::string group_name; diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 2a11549426..6183b7e90e 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -223,11 +223,6 @@ public: // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListRequest(U32 flags); - // asks for the parcel's media url filter list - void requestParcelMediaURLFilter(); - // receive the response - void receiveParcelMediaURLFilter(const LLSD &content); - // Dwell is not part of the usual parcel update information because the // simulator doesn't actually know the per-parcel dwell. Ack! We have // to get it out of the database. diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 47a99d7ea4..b607afbd9d 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1523,11 +1523,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("CreateInventoryCategory"); capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("EnvironmentSettings"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); - capabilityNames.append("EnvironmentSettings"); - capabilityNames.append("ObjectMedia"); - capabilityNames.append("ObjectMediaNavigate"); if (gSavedSettings.getBOOL("UseHTTPInventory")) { @@ -1538,10 +1536,11 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) } capabilityNames.append("GetDisplayNames"); - capabilityNames.append("GetTexture"); capabilityNames.append("GetMesh"); capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); + capabilityNames.append("GetTexture"); + capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); capabilityNames.append("LandResources"); @@ -1550,10 +1549,10 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("MeshUploadFlag"); capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); + capabilityNames.append("ObjectMedia"); + capabilityNames.append("ObjectMediaNavigate"); capabilityNames.append("ObjectNavMeshProperties"); capabilityNames.append("ParcelPropertiesUpdate"); - capabilityNames.append("ParcelMediaURLFilterList"); - capabilityNames.append("ParcelNavigateMedia"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); @@ -1567,10 +1566,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("SendUserReport"); capabilityNames.append("SendUserReportWithScreenshot"); capabilityNames.append("ServerReleaseNotes"); - capabilityNames.append("SimConsole"); - capabilityNames.append("SimulatorFeatures"); capabilityNames.append("SetDisplayName"); capabilityNames.append("SimConsoleAsync"); + capabilityNames.append("SimulatorFeatures"); capabilityNames.append("StartGroupProposal"); capabilityNames.append("TerrainNavMeshProperties"); capabilityNames.append("TextureStats"); @@ -1578,10 +1576,10 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UpdateAgentInformation"); capabilityNames.append("UpdateAgentLanguage"); capabilityNames.append("UpdateGestureAgentInventory"); - capabilityNames.append("UpdateNotecardAgentInventory"); - capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateGestureTaskInventory"); + capabilityNames.append("UpdateNotecardAgentInventory"); capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UploadBakedTexture"); capabilityNames.append("ViewerMetrics"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index d9918e633b..4b0e0598f6 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -529,9 +529,10 @@ void LLViewerShaderMgr::setShaders() { loaded = loadShadersInterface(); } - + if (loaded) - { + + { loaded = loadTransformShaders(); } diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 8fef13a6bc..603634e5f3 100644..100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -787,7 +787,7 @@ void send_stats() "%-6s Class %d ", gGLManager.mGLVendorShort.substr(0,6).c_str(), (S32)LLFeatureManager::getInstance()->getGPUClass()) - + LLFeatureManager::getInstance()->getGPUString(); + + gGLManager.getRawGLString(); system["gpu"] = gpu_desc; system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass(); @@ -798,7 +798,18 @@ void send_stats() S32 shader_level = 0; if (LLPipeline::sRenderDeferred) { - shader_level = 3; + if (LLPipeline::RenderShadowDetail > 0) + { + shader_level = 5; + } + else if (LLPipeline::RenderDeferredSSAO) + { + shader_level = 4; + } + else + { + shader_level = 3; + } } else if (gPipeline.canUseWindLightShadersOnObjects()) { @@ -949,15 +960,8 @@ LLSD LLViewerStats::PhaseMap::dumpPhases() for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter) { const std::string& phase_name = iter->first; - result[phase_name]["completed"] = !(iter->second.getStarted()); + result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted())); result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); -#if 0 // global stats for each phase seem like overkill here - phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name); - if (stats_iter != sPhaseStats.end()) - { - result[phase_name]["stats"] = stats_iter->second.getData(); - } -#endif } return result; } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 7f638a24bf..32cf8cc1b3 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -62,6 +62,7 @@ #include "llmediaentry.h" #include "llvovolume.h" #include "llviewermedia.h" +#include "lltexturecache.h" /////////////////////////////////////////////////////////////////////////////// // statics @@ -409,7 +410,11 @@ void LLViewerTextureManager::cleanup() void LLViewerTexture::initClass() { LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; - sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); + + if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) + { + sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); + } } // static @@ -1236,7 +1241,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mIsMissingAsset = FALSE; mLoadedCallbackDesiredDiscardLevel = S8_MAX; - mPauseLoadedCallBacks = TRUE ; + mPauseLoadedCallBacks = FALSE ; mNeedsCreateTexture = FALSE; @@ -1253,6 +1258,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mRequestDeltaTime = 0.f; mForSculpt = FALSE ; mIsFetched = FALSE ; + mInFastCacheList = FALSE; mCachedRawImage = NULL ; mCachedRawDiscardLevel = -1 ; @@ -1266,6 +1272,8 @@ void LLViewerFetchedTexture::init(bool firstinit) mLastReferencedSavedRawImageTime = 0.0f ; mKeptSavedRawImageTime = 0.f ; mLastCallBackActiveTime = 0.f; + + mInDebug = FALSE; } LLViewerFetchedTexture::~LLViewerFetchedTexture() @@ -1310,14 +1318,47 @@ void LLViewerFetchedTexture::cleanup() mSavedRawDiscardLevel = -1; } +//access the fast cache +void LLViewerFetchedTexture::loadFromFastCache() +{ + if(!mInFastCacheList) + { + return; //no need to access the fast cache. + } + mInFastCacheList = FALSE; + + mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel) ; + if(mRawImage.notNull()) + { + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; + setTexelsPerImage(); + + if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) + { + //discard all oversized textures. + destroyRawImage(); + setIsMissingAsset(); + mRawDiscardLevel = INVALID_DISCARD_LEVEL ; + } + else + { + mRequestedDiscardLevel = mDesiredDiscardLevel + 1; + mIsRawImageValid = TRUE; + addToCreateTexture() ; + } + } +} + void LLViewerFetchedTexture::setForSculpt() { static const S32 MAX_INTERVAL = 8 ; //frames mForSculpt = TRUE ; - if(isForSculptOnly() && !getBoundRecently()) + if(isForSculptOnly() && hasGLTexture() && !getBoundRecently()) { destroyGLTexture() ; //sculpt image does not need gl texture. + mTextureState = ACTIVE; } checkCachedRawSculptImage() ; setMaxVirtualSizeResetInterval(MAX_INTERVAL) ; @@ -1735,7 +1776,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority() S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired; ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; - setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far. + setAdditionalDecodePriority(0.1f) ;//boost the textures without any data so far. } else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel)) { @@ -1836,8 +1877,6 @@ F32 LLViewerFetchedTexture::maxDecodePriority() void LLViewerFetchedTexture::setDecodePriority(F32 priority) { - llassert(!mInImageList); - mDecodePriority = priority; if(mDecodePriority < F_ALMOST_ZERO) @@ -1865,7 +1904,7 @@ void LLViewerFetchedTexture::updateVirtualSize() for(U32 i = 0 ; i < mNumFaces ; i++) { LLFace* facep = mFaceList[i] ; - if(facep->getDrawable()->isRecentlyVisible()) + if( facep && facep->getDrawable() && facep->getDrawable()->isRecentlyVisible()) { addTextureStats(facep->getVirtualSize()) ; setAdditionalDecodePriority(facep->getImportanceToCamera()) ; @@ -1898,6 +1937,20 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching() return current_discard ; } +bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level) +{ + if(debug_level < 0) + { + mInDebug = FALSE; + return false; + } + mInDebug = TRUE; + + mDesiredDiscardLevel = debug_level; + + return true; +} + bool LLViewerFetchedTexture::updateFetch() { static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); @@ -1935,6 +1988,10 @@ bool LLViewerFetchedTexture::updateFetch() { return false; // process any raw image data in callbacks before replacing } + if(mInFastCacheList) + { + return false; + } S32 current_discard = getCurrentDiscardLevelForFetching() ; S32 desired_discard = getDesiredDiscardLevel(); @@ -2052,6 +2109,10 @@ bool LLViewerFetchedTexture::updateFetch() { make_request = false; } + else if(mDesiredDiscardLevel > getMaxDiscardLevel()) + { + make_request = false; + } else if (mNeedsCreateTexture || mIsMissingAsset) { make_request = false; @@ -2060,6 +2121,11 @@ bool LLViewerFetchedTexture::updateFetch() { make_request = false; } + else if(mCachedRawImage.notNull() && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) + { + make_request = false; + switchToCachedImage() ; //use the cached raw data first + } //else if (!isJustBound() && mCachedRawImageReady) //{ // make_request = false; @@ -2152,7 +2218,10 @@ bool LLViewerFetchedTexture::updateFetch() void LLViewerFetchedTexture::clearFetchedResults() { - llassert_always(!mNeedsCreateTexture && !mIsFetching); + if(mNeedsCreateTexture || mIsFetching) + { + return ; + } cleanup(); destroyGLTexture(); @@ -2167,11 +2236,13 @@ void LLViewerFetchedTexture::forceToDeleteRequest() { if (mHasFetcher) { - LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); mHasFetcher = FALSE; mIsFetching = FALSE ; - resetTextureStats(); } + + resetTextureStats(); + + mDesiredDiscardLevel = getMaxDiscardLevel() + 1; } void LLViewerFetchedTexture::setIsMissingAsset() @@ -2182,7 +2253,8 @@ void LLViewerFetchedTexture::setIsMissingAsset() } else { - llwarns << mUrl << ": Marking image as missing" << llendl; + //it is normal no map tile on an empty region. + //llwarns << mUrl << ": Marking image as missing" << llendl; } if (mHasFetcher) { @@ -2214,10 +2286,18 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ; } - if(mPauseLoadedCallBacks && !pause) + if(mPauseLoadedCallBacks) + { + if(!pause) + { + unpauseLoadedCallbacks(src_callback_list) ; + } + } + else if(pause) { - unpauseLoadedCallbacks(src_callback_list) ; + pauseLoadedCallbacks(src_callback_list) ; } + LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause); mLoadedCallbackList.push_back(entryp); diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f1105c3705..2ea9a07e9a 100644..100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -436,6 +436,8 @@ public: void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } bool updateFetch(); + bool setDebugFetching(S32 debug_level); + bool isInDebug() {return mInDebug;} void clearFetchedResults(); //clear all fetched results, for debug use. @@ -498,6 +500,9 @@ public: void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} void forceToDeleteRequest(); + void loadFromFastCache(); + void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } + bool isInFastCacheList() { return mInFastCacheList; } protected: /*virtual*/ void switchToCachedImage(); S32 getCurrentDiscardLevelForFetching() ; @@ -516,6 +521,8 @@ private: private: BOOL mFullyLoaded; + BOOL mInDebug; + BOOL mInFastCacheList; protected: std::string mLocalFileName; diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp index 9f1ac7c49c..2b364851a7 100644 --- a/indra/newview/llviewertextureanim.cpp +++ b/indra/newview/llviewertextureanim.cpp @@ -27,21 +27,37 @@ #include "llviewerprecompiledheaders.h" #include "llviewertextureanim.h" +#include "llvovolume.h" #include "llmath.h" #include "llerror.h" -LLViewerTextureAnim::LLViewerTextureAnim() : LLTextureAnim() +std::vector<LLViewerTextureAnim*> LLViewerTextureAnim::sInstanceList; + +LLViewerTextureAnim::LLViewerTextureAnim(LLVOVolume* vobj) : LLTextureAnim() { + mVObj = vobj; mLastFrame = -1.f; // Force an update initially mLastTime = 0.f; mOffS = mOffT = 0; mScaleS = mScaleT = 1; mRot = 0; + + mInstanceIndex = sInstanceList.size(); + sInstanceList.push_back(this); } LLViewerTextureAnim::~LLViewerTextureAnim() { + S32 end_idx = sInstanceList.size()-1; + + if (end_idx != mInstanceIndex) + { + sInstanceList[mInstanceIndex] = sInstanceList[end_idx]; + sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex; + } + + sInstanceList.pop_back(); } void LLViewerTextureAnim::reset() @@ -50,6 +66,14 @@ void LLViewerTextureAnim::reset() mTimer.reset(); } +//static +void LLViewerTextureAnim::updateClass() +{ + for (std::vector<LLViewerTextureAnim*>::iterator iter = sInstanceList.begin(); iter != sInstanceList.end(); ++iter) + { + (*iter)->mVObj->animateTextures(); + } +} S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t, F32 &scale_s, F32 &scale_t, diff --git a/indra/newview/llviewertextureanim.h b/indra/newview/llviewertextureanim.h index dd7bd0cb90..abbfabceb9 100644 --- a/indra/newview/llviewertextureanim.h +++ b/indra/newview/llviewertextureanim.h @@ -30,10 +30,18 @@ #include "lltextureanim.h" #include "llframetimer.h" +class LLVOVolume; + class LLViewerTextureAnim : public LLTextureAnim { +private: + static std::vector<LLViewerTextureAnim*> sInstanceList; + S32 mInstanceIndex; + public: - LLViewerTextureAnim(); + static void updateClass(); + + LLViewerTextureAnim(LLVOVolume* vobj); virtual ~LLViewerTextureAnim(); /*virtual*/ void reset(); @@ -51,6 +59,7 @@ public: F32 mRot; protected: + LLVOVolume* mVObj; LLFrameTimer mTimer; F64 mLastTime; F32 mLastFrame; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 9a6c0569a9..49d7e8b842 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,7 +58,7 @@ #include "pipeline.h" #include "llappviewer.h" #include "llxuiparser.h" -#include "llagent.h" +#include "llviewerdisplay.h" //////////////////////////////////////////////////////////////////////////// @@ -276,6 +276,7 @@ void LLViewerTextureList::shutdown() // Flush all of the references mLoadingStreamList.clear(); mCreateTextureList.clear(); + mFastCacheList.clear(); mUUIDMap.clear(); @@ -453,6 +454,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, LLGLenum primary_format, LLHost request_from_host) { + static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled"); + LLPointer<LLViewerFetchedTexture> imagep ; switch(texture_type) { @@ -490,6 +493,11 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, imagep->forceActive() ; } + if(fast_cache_fetching_enabled) + { + mFastCacheList.insert(imagep); + imagep->setInFastCacheList(true); + } return imagep ; } @@ -503,6 +511,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id) void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) { + assert_main_thread(); llassert_always(mInitialized) ; llassert(image); if (image->isInImageList()) @@ -519,6 +528,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image) void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) { + assert_main_thread(); llassert_always(mInitialized) ; llassert(image); if (!image->isInImageList()) @@ -593,16 +603,24 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_PRIORITIES("Prioritize"); static LLFastTimer::DeclareTimer FTM_IMAGE_CALLBACKS("Callbacks"); static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch"); +static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch"); static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create"); static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats"); void LLViewerTextureList::updateImages(F32 max_time) { - if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) + static BOOL cleared = FALSE; + if(gTeleportDisplay) { - clearFetchingRequests(); + if(!cleared) + { + clearFetchingRequests(); + gPipeline.clearRebuildGroups(); + cleared = TRUE; + } return; } + cleared = FALSE; LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); @@ -613,6 +631,11 @@ void LLViewerTextureList::updateImages(F32 max_time) LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); + { + //loading from fast cache + LLFastTimer t(FTM_FAST_CACHE_IMAGE_FETCH); + max_time -= updateImagesLoadingFastCache(max_time); + } { LLFastTimer t(FTM_IMAGE_UPDATE_PRIORITIES); @@ -673,14 +696,13 @@ void LLViewerTextureList::clearFetchingRequests() return; } + LLAppViewer::getTextureFetch()->deleteAllRequests(); + for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { - LLViewerFetchedTexture* image = *iter; - if(image->hasFetcher()) - { - image->forceToDeleteRequest() ; - } + LLViewerFetchedTexture* imagep = *iter; + imagep->forceToDeleteRequest() ; } } @@ -688,10 +710,11 @@ void LLViewerTextureList::updateImagesDecodePriorities() { // Update the decode priority for N images each frame { - const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second - S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); + static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 + const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES); + S32 update_counter = llmin(max_update_count, mUUIDMap.size()); uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); - while(update_counter > 0 && !mUUIDMap.empty()) + while ((update_counter-- > 0) && !mUUIDMap.empty()) { if (iter == mUUIDMap.end()) { @@ -699,7 +722,13 @@ void LLViewerTextureList::updateImagesDecodePriorities() } mLastUpdateUUID = iter->first; LLPointer<LLViewerFetchedTexture> imagep = iter->second; - ++iter; // safe to incrament now + ++iter; // safe to increment now + + if(imagep->isInDebug()) + { + update_counter--; + continue; //is in debug, ignore. + } // // Flush formatted images using a lazy flush @@ -754,7 +783,16 @@ void LLViewerTextureList::updateImagesDecodePriorities() imagep->setInactive() ; } } - + + if (!imagep->isInImageList()) + { + continue; + } + if(imagep->isInFastCacheList()) + { + continue; //wait for loading from the fast cache. + } + imagep->processTextureStats(); F32 old_priority = imagep->getDecodePriority(); F32 old_priority_test = llmax(old_priority, 0.0f); @@ -764,15 +802,35 @@ void LLViewerTextureList::updateImagesDecodePriorities() if ((decode_priority_test < old_priority_test * .8f) || (decode_priority_test > old_priority_test * 1.25f)) { - removeImageFromList(imagep); + mImageList.erase(imagep) ; imagep->setDecodePriority(decode_priority); - addImageToList(imagep); + mImageList.insert(imagep); } - update_counter--; } } } +void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) +{ + if(!tex->setDebugFetching(debug_level)) + { + return; + } + + const F32 DEBUG_PRIORITY = 100000.f; + F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f); + F32 decode_priority_test = DEBUG_PRIORITY; + + // Ignore < 20% difference + if ((decode_priority_test < old_priority_test * .8f) || + (decode_priority_test > old_priority_test * 1.25f)) + { + removeImageFromList(tex); + tex->setDecodePriority(decode_priority_test); + addImageToList(tex); + } +} + /* static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host) { @@ -827,6 +885,36 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) return create_timer.getElapsedTimeF32(); } +F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) +{ + if (gGLManager.mIsDisabled) return 0.0f; + if(mFastCacheList.empty()) + { + return 0.f; + } + + // + // loading texture raw data from the fast cache directly. + // + + LLTimer timer; + image_list_t::iterator enditer = mFastCacheList.begin(); + for (image_list_t::iterator iter = mFastCacheList.begin(); + iter != mFastCacheList.end();) + { + image_list_t::iterator curiter = iter++; + enditer = iter; + LLViewerFetchedTexture *imagep = *curiter; + imagep->loadFromFastCache(); + if (timer.getElapsedTimeF32() > max_time) + { + break; + } + } + mFastCacheList.erase(mFastCacheList.begin(), enditer); + return timer.getElapsedTimeF32(); +} + void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep) { if(!imagep) @@ -850,15 +938,24 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { LLTimer image_op_timer; - // Update the decode priority for N images each frame - // Make a list with 32 high priority entries + 256 cycled entries - const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); - const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); + // Update fetch for N images each frame + static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32 + static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256 + static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32 + static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 + static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false + + size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); + max_priority_count = llmin(max_priority_count, mImageList.size()); + + size_t total_update_count = mUUIDMap.size(); + size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); + max_update_count = llmin(max_update_count, total_update_count); - // 32 high priority entries + // MAX_HIGH_PRIO_COUNT high priority entries typedef std::vector<LLViewerFetchedTexture*> entries_list_t; entries_list_t entries; - size_t update_counter = llmin(max_priority_count, mImageList.size()); + size_t update_counter = max_priority_count; image_priority_list_t::iterator iter1 = mImageList.begin(); while(update_counter > 0) { @@ -868,43 +965,46 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) update_counter--; } - // 256 cycled entries - update_counter = llmin(max_update_count, mUUIDMap.size()); + // MAX_UPDATE_COUNT cycled entries + update_counter = max_update_count; if(update_counter > 0) { uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); - uuid_map_t::iterator iter2p = iter2; - while(update_counter > 0) + while ((update_counter > 0) && (total_update_count > 0)) { if (iter2 == mUUIDMap.end()) { iter2 = mUUIDMap.begin(); } - entries.push_back(iter2->second); - iter2p = iter2++; - update_counter--; + LLViewerFetchedTexture* imagep = iter2->second; + // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set. + if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher()))) + { + entries.push_back(imagep); + update_counter--; + } + + iter2++; + total_update_count--; } - - mLastFetchUUID = iter2p->first; } S32 fetch_count = 0; - S32 min_count = max_priority_count + max_update_count/4; + size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); + S32 min_count = max_priority_count + min_update_count; for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { LLViewerFetchedTexture* imagep = *iter3++; - - bool fetching = imagep->updateFetch(); - if (fetching) + fetch_count += (imagep->updateFetch() ? 1 : 0); + if (min_count <= min_update_count) { - fetch_count++; + mLastFetchUUID = imagep->getID(); } - if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) + if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time)) { break; } - min_count--; } //if (fetch_count == 0) //{ @@ -936,6 +1036,9 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) { LLTimer timer; + //loading from fast cache + updateImagesLoadingFastCache(max_time); + // Update texture stats and priorities std::vector<LLPointer<LLViewerFetchedTexture> > image_list; for (image_priority_list_t::iterator iter = mImageList.begin(); @@ -1583,49 +1686,43 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations> bool LLUIImageList::initFromFile() { - // construct path to canonical textures.xml in default skin dir - std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml"); + // Look for textures.xml in all the right places. Pass + // constraint=LLDir::ALL_SKINS because we want to overlay textures.xml + // from all the skins directories. + std::vector<std::string> textures_paths = + gDirUtilp->findSkinnedFilenames(LLDir::TEXTURES, "textures.xml", LLDir::ALL_SKINS); + std::vector<std::string>::const_iterator pi(textures_paths.begin()), pend(textures_paths.end()); + if (pi == pend) + { + llwarns << "No textures.xml found in skins directories" << llendl; + return false; + } + // The first (most generic) file gets special validations LLXMLNodePtr root; - - if (!LLXMLNode::parseFile(base_file_path, root, NULL)) + if (!LLXMLNode::parseFile(*pi, root, NULL)) { - llwarns << "Unable to parse UI image list file " << base_file_path << llendl; + llwarns << "Unable to parse UI image list file " << *pi << llendl; return false; } if (!root->hasAttribute("version")) { - llwarns << "No valid version number in UI image list file " << base_file_path << llendl; + llwarns << "No valid version number in UI image list file " << *pi << llendl; return false; } UIImageDeclarations images; LLXUIParser parser; - parser.readXUI(root, images, base_file_path); - - // add components defined in current skin - std::string skin_update_path = gDirUtilp->getSkinDir() - + gDirUtilp->getDirDelimiter() - + "textures" - + gDirUtilp->getDirDelimiter() - + "textures.xml"; - LLXMLNodePtr update_root; - if (skin_update_path != base_file_path - && LLXMLNode::parseFile(skin_update_path, update_root, NULL)) - { - parser.readXUI(update_root, images, skin_update_path); - } - - // add components defined in user override of current skin - skin_update_path = gDirUtilp->getUserSkinDir() - + gDirUtilp->getDirDelimiter() - + "textures" - + gDirUtilp->getDirDelimiter() - + "textures.xml"; - if (skin_update_path != base_file_path - && LLXMLNode::parseFile(skin_update_path, update_root, NULL)) - { - parser.readXUI(update_root, images, skin_update_path); + parser.readXUI(root, images, *pi); + + // add components defined in the rest of the skin paths + while (++pi != pend) + { + LLXMLNodePtr update_root; + if (LLXMLNode::parseFile(*pi, update_root, NULL)) + { + parser.readXUI(update_root, images, *pi); + } } if (!images.validateBlock()) return false; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index e89997fe28..3dda973d3f 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -111,6 +111,7 @@ public: void doPrefetchImages(); void clearFetchingRequests(); + void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); static S32 getMinVideoRamSetting(); static S32 getMaxVideoRamSetting(bool get_recommended = false); @@ -120,6 +121,7 @@ private: F32 updateImagesCreateTextures(F32 max_time); F32 updateImagesFetchTextures(F32 max_time); void updateImagesUpdateStats(); + F32 updateImagesLoadingFastCache(F32 max_time); void addImage(LLViewerFetchedTexture *image); void deleteImage(LLViewerFetchedTexture *image); @@ -173,6 +175,7 @@ public: image_list_t mLoadingStreamList; image_list_t mCreateTextureList; image_list_t mCallbackList; + image_list_t mFastCacheList; // Note: just raw pointers because they are never referenced, just compared against std::set<LLViewerFetchedTexture*> mDirtyTextureList; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 98ea923272..ffaf881521 100644..100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1558,8 +1558,12 @@ LLViewerWindow::LLViewerWindow(const Params& p) LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert); LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert); - LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications")); - llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl; + bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications"); + LLNotifications::instance().setIgnoreAllNotifications(ignore); + if (ignore) + { + llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl; + } // Default to application directory. LLViewerWindow::sSnapshotBaseName = "Snapshot"; @@ -1688,8 +1692,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), mDisplayScale.mV[VX], mDisplayScale.mV[VY], - gDirUtilp->getAppRODataDir(), - LLUI::getXUIPaths()); + gDirUtilp->getAppRODataDir()); // Create container for all sub-views LLView::Params rvp; @@ -4233,14 +4236,48 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei image_height = llmin(image_height, window_height); } + S32 original_width = 0; + S32 original_height = 0; + bool reset_deferred = false; + + LLRenderTarget scratch_space; + F32 scale_factor = 1.0f ; if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height)) { - // if image cropping or need to enlarge the scene, compute a scale_factor - F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; - snapshot_width = (S32)(ratio * image_width) ; - snapshot_height = (S32)(ratio * image_height) ; - scale_factor = llmax(1.0f, 1.0f / ratio) ; + if ((image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) + { + if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true)) + { + original_width = gPipeline.mDeferredScreen.getWidth(); + original_height = gPipeline.mDeferredScreen.getHeight(); + + if (gPipeline.allocateScreenBuffer(image_width, image_height)) + { + window_width = image_width; + window_height = image_height; + snapshot_width = image_width; + snapshot_height = image_height; + reset_deferred = true; + mWorldViewRectRaw.set(0, image_height, image_width, 0); + scratch_space.bindTarget(); + } + else + { + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); + } + } + } + + if (!reset_deferred) + { + // if image cropping or need to enlarge the scene, compute a scale_factor + F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; + snapshot_width = (S32)(ratio * image_width) ; + snapshot_height = (S32)(ratio * image_height) ; + scale_factor = llmax(1.0f, 1.0f / ratio) ; + } } if (show_ui && scale_factor > 1.f) @@ -4429,11 +4466,20 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei gPipeline.resetDrawOrders(); } + if (reset_deferred) + { + mWorldViewRectRaw = window_rect; + scratch_space.flush(); + scratch_space.release(); + gPipeline.allocateScreenBuffer(original_width, original_height); + + } + if (high_res) { send_agent_resume(); } - + return ret; } @@ -4760,8 +4806,7 @@ void LLViewerWindow::initFonts(F32 zoom_factor) LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"), mDisplayScale.mV[VX] * zoom_factor, mDisplayScale.mV[VY] * zoom_factor, - gDirUtilp->getAppRODataDir(), - LLUI::getXUIPaths()); + gDirUtilp->getAppRODataDir()); // Force font reloads, which can be very slow LLFontGL::loadDefaultFonts(); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 05febdf93b..627238b0f5 100644..100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2423,7 +2423,7 @@ void LLVOAvatar::dumpAnimationState() //------------------------------------------------------------------------ // idleUpdate() //------------------------------------------------------------------------ -BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { LLMemType mt(LLMemType::MTYPE_AVATAR); LLFastTimer t(FTM_AVATAR_UPDATE); @@ -2431,12 +2431,12 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) if (isDead()) { llinfos << "Warning! Idle on dead avatar" << llendl; - return TRUE; + return; } if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) { - return TRUE; + return; } checkTextureLoading() ; @@ -2519,8 +2519,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) idleUpdateNameTag( root_pos_last ); idleUpdateRenderCost(); - - return TRUE; } void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) @@ -4423,7 +4421,9 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); - if (getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) + + if ( getImage(TEX_HAIR_BAKED, 0) + && getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) { num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy); first_pass = FALSE; @@ -4567,7 +4567,20 @@ void LLVOAvatar::updateTextures() LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index); U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); const LLTextureEntry *te = getTE(texture_index); - const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + + // getTE can return 0. + // Not sure yet why it does, but of course it crashes when te->mScale? gets used. + // Put safeguard in place so this corner case get better handling and does not result in a crash. + F32 texel_area_ratio = 1.0f; + if( te ) + { + texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + } + else + { + llwarns << "getTE( " << texture_index << " ) returned 0" <<llendl; + } + LLViewerFetchedTexture *imagep = NULL; for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++) { @@ -6678,7 +6691,7 @@ void LLVOAvatar::updateMeshTextures() if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } std::vector<BOOL> is_layer_baked; @@ -7223,7 +7236,7 @@ void LLVOAvatar::onFirstTEMessageReceived() if(!isSelf()) { src_callback_list = &mCallbackTextureList ; - paused = mLoadedCallbacksPaused ; + paused = !isVisible(); } for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -8707,6 +8720,12 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index return FALSE; } + if( !getImage( te, index ) ) + { + llwarns << "getImage( " << te << ", " << index << " ) returned 0" << llendl; + return FALSE; + } + return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && getImage(te, index)->getID() != IMG_DEFAULT); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f5692bb52f..1adb680962 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -134,7 +134,7 @@ public: U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual BOOL updateLOD(); BOOL updateJointLODs(); void updateLODRiggedAttachments( void ); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 6d672acc32..7a81063f83 100644..100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -668,15 +668,13 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) } // virtual -BOOL LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (!isAgentAvatarValid()) + if (isAgentAvatarValid()) { - return TRUE; + LLVOAvatar::idleUpdate(agent, world, time); + idleUpdateTractorBeam(); } - LLVOAvatar::idleUpdate(agent, world, time); - idleUpdateTractorBeam(); - return TRUE; } // virtual @@ -2132,9 +2130,7 @@ LLSD LLVOAvatarSelf::metricsData() { // runway - add region info LLSD result; - result["id"] = getID(); result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); - result["is_self"] = isSelf(); std::vector<S32> rez_counts; LLVOAvatar::getNearbyRezzedStats(rez_counts); result["nearby"] = LLSD::emptyMap(); @@ -2148,7 +2144,6 @@ LLSD LLVOAvatarSelf::metricsData() result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32(); result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32(); result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); - result["phases"] = getPhases().dumpPhases(); result["startup"] = LLStartUp::getPhases().dumpPhases(); return result; @@ -2157,7 +2152,12 @@ LLSD LLVOAvatarSelf::metricsData() class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder { public: - ViewerAppearanceChangeMetricsResponder() + ViewerAppearanceChangeMetricsResponder( S32 expected_sequence, + volatile const S32 & live_sequence, + volatile bool & reporting_started): + mExpectedSequence(expected_sequence), + mLiveSequence(live_sequence), + mReportingStarted(reporting_started) { } @@ -2176,14 +2176,44 @@ public: error(status,reason); } } + + // virtual + void error(U32 status_num, const std::string & reason) + { + } + + // virtual + void result(const LLSD & content) + { + if (mLiveSequence == mExpectedSequence) + { + mReportingStarted = true; + } + } + +private: + S32 mExpectedSequence; + volatile const S32 & mLiveSequence; + volatile bool & mReportingStarted; }; void LLVOAvatarSelf::sendAppearanceChangeMetrics() { // gAgentAvatarp->stopAllPhases(); + static volatile bool reporting_started(false); + static volatile S32 report_sequence(0); LLSD msg = metricsData(); msg["message"] = "ViewerAppearanceChangeMetrics"; + msg["session_id"] = gAgentSessionID; + msg["agent_id"] = gAgentID; + msg["sequence"] = report_sequence; + msg["initial"] = !reporting_started; + msg["break"] = false; + + // Update sequence number + if (S32_MAX == ++report_sequence) + report_sequence = 0; LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL; std::string caps_url; @@ -2196,8 +2226,10 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics() { LLCurlRequest::headers_t headers; LLHTTPClient::post(caps_url, - msg, - new ViewerAppearanceChangeMetricsResponder); + msg, + new ViewerAppearanceChangeMetricsResponder(report_sequence, + report_sequence, + reporting_started)); } } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 2b273e616c..7bd0c0bf93 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -85,7 +85,7 @@ protected: //-------------------------------------------------------------------- public: /*virtual*/ void updateRegion(LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); //-------------------------------------------------------------------- // LLCharacter interface and related diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 5ad9ccc9af..566c33c0af 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -277,17 +277,17 @@ BOOL LLVOGrass::isActive() const return TRUE; } -BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS))) { - return TRUE; + return; } if (!mDrawable) { // So drones work. - return TRUE; + return; } if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass @@ -297,14 +297,14 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) mNumBlades = 0 ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } - return TRUE ; + return; } else if(!mNumBlades)//restart grass rendering { mNumBlades = GRASS_MAX_BLADES ; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - return TRUE ; + return; } if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) @@ -312,7 +312,7 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } - return TRUE; + return; } diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index 00a59facf7..b9835b8802 100644 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -73,7 +73,7 @@ public: void plantBlades(); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 6da54435e3..97b7418b40 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -49,18 +49,8 @@ LLVOGround::~LLVOGround() { } -BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GROUND))) - { - return TRUE; - } - - /*if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index 73b097327e..290579b4da 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -41,7 +41,7 @@ protected: public: LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class // later? diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 9cce68fff6..e4f9915e93 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -196,9 +196,8 @@ void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) mDrawable->setPositionGroup(pos); } -BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index 43b2844f07..42c1252d01 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -63,7 +63,7 @@ public: LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual F32 getBinRadius(); virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 312034022e..31358df85f 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1052,9 +1052,8 @@ void LLVOSky::calcAtmospherics(void) mFadeColor.setAlpha(0); } -BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; } BOOL LLVOSky::updateSky() diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 6e6898d80a..2a150eccb9 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -461,7 +461,7 @@ public: void cleanupGL(); void restoreGL(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); BOOL updateSky(); // Graphical stuff for objects - maybe broken out into render class diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 94a3111f4c..cb905d02da 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -80,9 +80,9 @@ public: glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); } if (data_mask & MAP_TEXCOORD3) - { //substitute tex coord 0 for tex coord 3 + { //substitute tex coord 1 for tex coord 3 glClientActiveTextureARB(GL_TEXTURE3_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } if (data_mask & MAP_TEXCOORD2) diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 337ddfb24d..6687ce432f 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -339,11 +339,11 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } -BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))) { - return TRUE; + return; } S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; @@ -393,8 +393,6 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } mTrunkLOD = trunk_LOD; - - return TRUE; } const F32 TREE_BLEND_MIN = 1.f; diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 0554935539..52debc85ab 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -59,7 +59,7 @@ public: void **user_data, U32 block_num, const EObjectUpdateType update_type, LLDataPacker *dp); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); // Graphical stuff for objects - maybe broken out into render class later? /*virtual*/ void render(LLAgent &agent); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0a5c8b5139..5d1c335078 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -329,7 +329,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -431,7 +431,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { if (!mTextureAnimp) { - mTextureAnimp = new LLViewerTextureAnim(); + mTextureAnimp = new LLViewerTextureAnim(this); } else { @@ -499,183 +499,144 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, void LLVOVolume::animateTextures() { - F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; - S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); - - if (result) + if (!mDead) { - if (!mTexAnimMode) - { - mFaceMappingChanged = TRUE; - gPipeline.markTextured(mDrawable); - } - mTexAnimMode = result | mTextureAnimp->mMode; - - S32 start=0, end=mDrawable->getNumFaces()-1; - if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) - { - start = end = mTextureAnimp->mFace; - } - - for (S32 i = start; i <= end; i++) + F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; + S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); + + if (result) { - LLFace* facep = mDrawable->getFace(i); - if (!facep) continue; - if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - - const LLTextureEntry* te = facep->getTextureEntry(); - - if (!te) + if (!mTexAnimMode) { - continue; + mFaceMappingChanged = TRUE; + gPipeline.markTextured(mDrawable); } - - if (!(result & LLViewerTextureAnim::ROTATE)) + mTexAnimMode = result | mTextureAnimp->mMode; + + S32 start=0, end=mDrawable->getNumFaces()-1; + if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) { - te->getRotation(&rot); + start = end = mTextureAnimp->mFace; } - if (!(result & LLViewerTextureAnim::TRANSLATE)) - { - te->getOffset(&off_s,&off_t); - } - if (!(result & LLViewerTextureAnim::SCALE)) + + for (S32 i = start; i <= end; i++) { - te->getScale(&scale_s, &scale_t); - } + LLFace* facep = mDrawable->getFace(i); + if (!facep) continue; + if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - if (!facep->mTextureMatrix) - { - facep->mTextureMatrix = new LLMatrix4(); - } + const LLTextureEntry* te = facep->getTextureEntry(); + + if (!te) + { + continue; + } + + if (!(result & LLViewerTextureAnim::ROTATE)) + { + te->getRotation(&rot); + } + if (!(result & LLViewerTextureAnim::TRANSLATE)) + { + te->getOffset(&off_s,&off_t); + } + if (!(result & LLViewerTextureAnim::SCALE)) + { + te->getScale(&scale_s, &scale_t); + } + + if (!facep->mTextureMatrix) + { + facep->mTextureMatrix = new LLMatrix4(); + } - LLMatrix4& tex_mat = *facep->mTextureMatrix; - tex_mat.setIdentity(); - LLVector3 trans ; + LLMatrix4& tex_mat = *facep->mTextureMatrix; + tex_mat.setIdentity(); + LLVector3 trans ; - if(facep->isAtlasInUse()) - { - // - //if use atlas for animated texture - //apply the following transform to the animation matrix. - // - - F32 tcoord_xoffset = 0.f ; - F32 tcoord_yoffset = 0.f ; - F32 tcoord_xscale = 1.f ; - F32 tcoord_yscale = 1.f ; if(facep->isAtlasInUse()) { - const LLVector2* tmp = facep->getTexCoordOffset() ; - tcoord_xoffset = tmp->mV[0] ; - tcoord_yoffset = tmp->mV[1] ; + // + //if use atlas for animated texture + //apply the following transform to the animation matrix. + // + + F32 tcoord_xoffset = 0.f ; + F32 tcoord_yoffset = 0.f ; + F32 tcoord_xscale = 1.f ; + F32 tcoord_yscale = 1.f ; + if(facep->isAtlasInUse()) + { + const LLVector2* tmp = facep->getTexCoordOffset() ; + tcoord_xoffset = tmp->mV[0] ; + tcoord_yoffset = tmp->mV[1] ; - tmp = facep->getTexCoordScale() ; - tcoord_xscale = tmp->mV[0] ; - tcoord_yscale = tmp->mV[1] ; - } - trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); + tmp = facep->getTexCoordScale() ; + tcoord_xscale = tmp->mV[0] ; + tcoord_yscale = tmp->mV[1] ; + } + trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); - tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); - } - else //non atlas - { - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); - } + tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); + } + else //non atlas + { + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + } - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); - tex_mat.rotate(quat); + tex_mat.rotate(quat); - LLMatrix4 mat; - mat.initAll(scale, LLQuaternion(), LLVector3()); - tex_mat *= mat; + LLMatrix4 mat; + mat.initAll(scale, LLQuaternion(), LLVector3()); + tex_mat *= mat; - tex_mat.translate(trans); + tex_mat.translate(trans); + } } - } - else - { - if (mTexAnimMode && mTextureAnimp->mRate == 0) + else { - U8 start, count; - - if (mTextureAnimp->mFace == -1) - { - start = 0; - count = getNumTEs(); - } - else + if (mTexAnimMode && mTextureAnimp->mRate == 0) { - start = (U8) mTextureAnimp->mFace; - count = 1; - } + U8 start, count; - for (S32 i = start; i < start + count; i++) - { - if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + if (mTextureAnimp->mFace == -1) { - setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + start = 0; + count = getNumTEs(); } - if (mTexAnimMode & LLViewerTextureAnim::SCALE) + else { - setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + start = (U8) mTextureAnimp->mFace; + count = 1; } - if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + + for (S32 i = start; i < start + count; i++) { - setTERotation(i, mTextureAnimp->mRot); + if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + { + setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + } + if (mTexAnimMode & LLViewerTextureAnim::SCALE) + { + setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + } + if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + { + setTERotation(i, mTextureAnimp->mRot); + } } - } - - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; - } - } -} -BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) -{ - LLViewerObject::idleUpdate(agent, world, time); - - //static LLFastTimer::DeclareTimer ftm("Volume Idle"); - //LLFastTimer t(ftm); - - if (mDead || mDrawable.isNull()) - { - return TRUE; - } - - /////////////////////// - // - // Do texture animation stuff - // - - if (mTextureAnimp && gAnimateTextures) - { - animateTextures(); - } - - // Dispatch to implementation - if (mVolumeImpl) - { - mVolumeImpl->doIdleUpdate(agent, world, time); - } - - const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; - if (mDrawable->isActive()) - { - if (mDrawable->isRoot() && - mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && - (!mDrawable->getParent() || !mDrawable->getParent()->isActive())) - { - mDrawable->makeStatic(); + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } } } - - return TRUE; } void LLVOVolume::updateTextures() @@ -698,7 +659,8 @@ void LLVOVolume::updateTextures() } } - } + + } } BOOL LLVOVolume::isVisible() const @@ -860,7 +822,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) } } - S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture + S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; if (texture_discard >= 0 && //texture has some data available @@ -916,8 +878,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) BOOL LLVOVolume::isActive() const { - return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()) || - (mDrawable.notNull() && mDrawable->isActive()); + return !mStatic; } BOOL LLVOVolume::setMaterial(const U8 material) @@ -1167,7 +1128,7 @@ void LLVOVolume::sculpt() S8 sculpt_components = 0; const U8* sculpt_data = NULL; - S32 discard_level = mSculptTexture->getDiscardLevel() ; + S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; S32 max_discard = mSculptTexture->getMaxDiscardLevel(); @@ -1266,6 +1227,13 @@ BOOL LLVOVolume::calcLOD() if (mDrawable->isState(LLDrawable::RIGGED)) { LLVOAvatar* avatar = getAvatar(); + + // Not sure how this can really happen, but alas it does. Better exit here than crashing. + if( !avatar || !avatar->mDrawable ) + { + return FALSE; + } + distance = avatar->mDrawable->mDistanceWRTCamera; radius = avatar->getBinRadius(); } @@ -1374,7 +1342,8 @@ BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp) void LLVOVolume::updateFaceFlags() { - for (S32 i = 0; i < getVolume()->getNumFaces(); i++) + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++) { LLFace *face = mDrawable->getFace(i); if (face) @@ -1475,7 +1444,10 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) volume = getVolume(); } - for (S32 i = 0; i < getVolume()->getNumVolumeFaces(); i++) + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; + i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs(); + i++) { LLFace *face = mDrawable->getFace(i); if (!face) @@ -1776,6 +1748,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) void LLVOVolume::updateFaceSize(S32 idx) { + if( mDrawable->getNumFaces() <= idx ) + { + return; + } + LLFace* facep = mDrawable->getFace(idx); if (facep) { @@ -2466,7 +2443,12 @@ void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) //add the face to show the media if it is in playing if(mDrawable) { - LLFace* facep = mDrawable->getFace(texture_index) ; + LLFace* facep(NULL); + if( texture_index < mDrawable->getNumFaces() ) + { + facep = mDrawable->getFace(texture_index) ; + } + if(facep) { LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; @@ -3865,6 +3847,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a* pos = dst_face.mPositions; + if( pos && weight && dst_face.mExtents ) { LLFastTimer t(FTM_SKIN_RIGGED); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 798927a45f..5482c80f2b 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -68,7 +68,7 @@ class LLVolumeInterface public: virtual ~LLVolumeInterface() { } virtual LLVolumeInterfaceType getInterfaceType() const = 0; - virtual void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0; + virtual void doIdleUpdate() = 0; virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0; virtual LLVector3 getPivotPosition() const = 0; virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0; @@ -114,8 +114,7 @@ public: void deleteFaces(); void animateTextures(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - + BOOL isVisible() const ; /*virtual*/ BOOL isActive() const; /*virtual*/ BOOL isAttachment() const; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 942eff6171..e8a1c3d1d6 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -100,17 +100,8 @@ void LLVOWater::updateTextures() } // Never gets called -BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - /*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))) - { - return TRUE; - } - if (mDrawable) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - }*/ - return TRUE; } LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index ed709dd840..cf9323ef2e 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -58,7 +58,7 @@ public: static void initClass(); static void cleanupClass(); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index afd902201b..a33f42cf84 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -92,9 +92,9 @@ void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction, { } -BOOL LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +void LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - return TRUE; + } BOOL LLVOWLSky::isActive(void) const diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h index 825e13a203..729dced15e 100644 --- a/indra/newview/llvowlsky.h +++ b/indra/newview/llvowlsky.h @@ -53,7 +53,7 @@ public: void initSunDirection(LLVector3 const & sun_direction, LLVector3 const & sun_angular_velocity); - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ BOOL isActive(void) const; /*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index e386112334..4f52ff9778 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -100,7 +100,7 @@ void LLWaterParamManager::loadPresetsFromDir(const std::string& dir) break; // no more files } - std::string path = dir + file; + std::string path = gDirUtilp->add(dir, file); if (!loadPreset(path)) { llwarns << "Error loading water preset from " << path << llendl; diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index 2425b96678..be3e3ff30e 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -105,10 +105,16 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() return; } - if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + LLUUID regionId; + if( gAgent.getRegion() ) + { + regionId = gAgent.getRegion()->getRegionID(); + } + + if (unvalidated_content[0]["regionID"].asUUID() != regionId ) { LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " - << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() + << regionId << " but got " << unvalidated_content[0]["regionID"].asUUID() << ") - ignoring..." << LL_ENDL; return; } diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 49d9d44d74..6077208799 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -283,7 +283,7 @@ void LLWLParamManager::loadPresetsFromDir(const std::string& dir) break; // no more files } - std::string path = dir + file; + std::string path = gDirUtilp->add(dir, file); if (!loadPreset(path)) { llwarns << "Error loading sky preset from " << path << llendl; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b42a84da47..ab45bd3d3b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -449,6 +449,19 @@ LLPipeline::LLPipeline() : mLightFunc = 0; } +void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name) +{ + LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name); + if ( cntrl_ptr.isNull() ) + { + llwarns << "Global setting name not found:" << name << llendl; + } + else + { + cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + } +} + void LLPipeline::init() { LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT); @@ -533,88 +546,86 @@ void LLPipeline::init() // // Update all settings to trigger a cached settings refresh // - - gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderUseFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderAvatarMaxVisible")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDelayVBUpdate")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - - gSavedSettings.getControl("UseOcclusion")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - - gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderAvatarVP")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDeferredSunWash")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderFSAASamples")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderResolutionDivisor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderUIBuffer")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDeferredSSAO")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowResolutionScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderLocalLights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDelayCreation")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderAnimateRes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("FreezeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("DebugBeaconLineWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderHighlightBrightness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderHighlightColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderHighlightThickness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderSpotLightsInNondeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewAmbientColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewDiffuse0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewSpecular0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewDiffuse1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewSpecular1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewDiffuse2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewSpecular2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewDirection0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewDirection1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("PreviewDirection2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowMinLuminance")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowMaxExtractAlpha")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowWarmthAmount")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowLumWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowWarmthWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowResolutionPow")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowIterations")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderGlowStrength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDepthOfField")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("CameraFocusTransitionTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("CameraFNumber")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("CameraFocalLength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("CameraFieldOfView")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowNoise")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowBlurSize")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderSSAOScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderSSAOMaxScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderSSAOFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderSSAOEffect")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowOffsetError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowBiasError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderSpotShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderSpotShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderEdgeDepthCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderEdgeNormCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowGaussian")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowBlurDistFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDeferredAtmospheric")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderReflectionDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderHighlightFadeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowOrthoClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowNearDist")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowSplitExponent")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowErrorCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderShadowFOVCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("CameraOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("CameraMaxCoF")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("CameraDoFResScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred"); + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred"); + connectRefreshCachedSettingsSafe("RenderUseFarClip"); + connectRefreshCachedSettingsSafe("RenderAvatarMaxVisible"); + connectRefreshCachedSettingsSafe("RenderDelayVBUpdate"); + connectRefreshCachedSettingsSafe("UseOcclusion"); + connectRefreshCachedSettingsSafe("VertexShaderEnable"); + connectRefreshCachedSettingsSafe("RenderAvatarVP"); + connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); + connectRefreshCachedSettingsSafe("RenderDeferred"); + connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); + connectRefreshCachedSettingsSafe("RenderFSAASamples"); + connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); + connectRefreshCachedSettingsSafe("RenderUIBuffer"); + connectRefreshCachedSettingsSafe("RenderShadowDetail"); + connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); + connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); + connectRefreshCachedSettingsSafe("RenderLocalLights"); + connectRefreshCachedSettingsSafe("RenderDelayCreation"); + connectRefreshCachedSettingsSafe("RenderAnimateRes"); + connectRefreshCachedSettingsSafe("FreezeTime"); + connectRefreshCachedSettingsSafe("DebugBeaconLineWidth"); + connectRefreshCachedSettingsSafe("RenderHighlightBrightness"); + connectRefreshCachedSettingsSafe("RenderHighlightColor"); + connectRefreshCachedSettingsSafe("RenderHighlightThickness"); + connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred"); + connectRefreshCachedSettingsSafe("PreviewAmbientColor"); + connectRefreshCachedSettingsSafe("PreviewDiffuse0"); + connectRefreshCachedSettingsSafe("PreviewSpecular0"); + connectRefreshCachedSettingsSafe("PreviewDiffuse1"); + connectRefreshCachedSettingsSafe("PreviewSpecular1"); + connectRefreshCachedSettingsSafe("PreviewDiffuse2"); + connectRefreshCachedSettingsSafe("PreviewSpecular2"); + connectRefreshCachedSettingsSafe("PreviewDirection0"); + connectRefreshCachedSettingsSafe("PreviewDirection1"); + connectRefreshCachedSettingsSafe("PreviewDirection2"); + connectRefreshCachedSettingsSafe("RenderGlowMinLuminance"); + connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount"); + connectRefreshCachedSettingsSafe("RenderGlowLumWeights"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights"); + connectRefreshCachedSettingsSafe("RenderGlowResolutionPow"); + connectRefreshCachedSettingsSafe("RenderGlowIterations"); + connectRefreshCachedSettingsSafe("RenderGlowWidth"); + connectRefreshCachedSettingsSafe("RenderGlowStrength"); + connectRefreshCachedSettingsSafe("RenderDepthOfField"); + connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); + connectRefreshCachedSettingsSafe("CameraFNumber"); + connectRefreshCachedSettingsSafe("CameraFocalLength"); + connectRefreshCachedSettingsSafe("CameraFieldOfView"); + connectRefreshCachedSettingsSafe("RenderShadowNoise"); + connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); + connectRefreshCachedSettingsSafe("RenderSSAOScale"); + connectRefreshCachedSettingsSafe("RenderSSAOMaxScale"); + connectRefreshCachedSettingsSafe("RenderSSAOFactor"); + connectRefreshCachedSettingsSafe("RenderSSAOEffect"); + connectRefreshCachedSettingsSafe("RenderShadowOffsetError"); + connectRefreshCachedSettingsSafe("RenderShadowBiasError"); + connectRefreshCachedSettingsSafe("RenderShadowOffset"); + connectRefreshCachedSettingsSafe("RenderShadowBias"); + connectRefreshCachedSettingsSafe("RenderSpotShadowOffset"); + connectRefreshCachedSettingsSafe("RenderSpotShadowBias"); + connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff"); + connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowGaussian"); + connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor"); + connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric"); + connectRefreshCachedSettingsSafe("RenderReflectionDetail"); + connectRefreshCachedSettingsSafe("RenderHighlightFadeTime"); + connectRefreshCachedSettingsSafe("RenderShadowClipPlanes"); + connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes"); + connectRefreshCachedSettingsSafe("RenderShadowNearDist"); + connectRefreshCachedSettingsSafe("RenderFarClip"); + connectRefreshCachedSettingsSafe("RenderShadowSplitExponent"); + connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff"); + connectRefreshCachedSettingsSafe("CameraOffset"); + connectRefreshCachedSettingsSafe("CameraMaxCoF"); + connectRefreshCachedSettingsSafe("CameraDoFResScale"); + connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } @@ -722,7 +733,7 @@ void LLPipeline::destroyGL() { glDeleteQueriesARB(1, &mMeshDirtyQueryObject); mMeshDirtyQueryObject = 0; -} + } } static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); @@ -768,18 +779,57 @@ void LLPipeline::allocatePhysicsBuffer() } } -void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) +bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { refreshCachedSettings(); - U32 samples = RenderFSAASamples; + + bool save_settings = sRenderDeferred; + if (save_settings) + { + // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets + gSavedSettings.setBOOL("RenderInitError", TRUE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } + + eFBOStatus ret = doAllocateScreenBuffer(resX, resY); + + if (save_settings) + { + // don't disable shaders on next session + gSavedSettings.setBOOL("RenderInitError", FALSE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } + + if (ret == FBO_FAILURE) + { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled + //NOTE: if the session closes successfully after this call, deferred rendering will be + // disabled on future sessions + if (LLPipeline::sRenderDeferred) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LLPipeline::refreshCachedSettings(); + } + } + + return ret == FBO_SUCCESS_FULLRES; +} + - //try to allocate screen buffers at requested resolution and samples +LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) +{ + // try to allocate screen buffers at requested resolution and samples // - on failure, shrink number of samples and try again // - if not multisampled, shrink resolution and try again (favor X resolution over Y) // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state + U32 samples = RenderFSAASamples; + + eFBOStatus ret = FBO_SUCCESS_FULLRES; if (!allocateScreenBuffer(resX, resY, samples)) { + //failed to allocate at requested specification, return false + ret = FBO_FAILURE; + releaseScreenBuffers(); //reduce number of samples while (samples > 0) @@ -787,7 +837,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) samples /= 2; if (allocateScreenBuffer(resX, resY, samples)) { //success - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); } @@ -800,22 +850,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) resY /= 2; if (allocateScreenBuffer(resX, resY, samples)) { - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); resX /= 2; if (allocateScreenBuffer(resX, resY, samples)) { - return; + return FBO_SUCCESS_LOWRES; } releaseScreenBuffers(); } llwarns << "Unable to allocate screen buffer at any resolution!" << llendl; } -} + return ret; +} bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { @@ -843,10 +894,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (LLPipeline::sRenderDeferred) { - // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets - gSavedSettings.setBOOL("RenderInitError", TRUE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - S32 shadow_detail = RenderShadowDetail; BOOL ssao = RenderDeferredSSAO; @@ -858,7 +905,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (samples > 0) { - if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; } else { @@ -881,7 +928,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) U32 sun_shadow_map_width = ((U32(resX*scale)+1)&~1); // must be even to avoid a stripe in the horizontal shadow blur for (U32 i = 0; i < 4; i++) { - if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false; + if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; } } else @@ -892,7 +939,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } } - U32 width = nhpo2(U32(resX*scale))/2; + U32 width = (U32) (resX*scale); U32 height = width; if (shadow_detail > 1) @@ -911,9 +958,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } } - // don't disable shaders on next session - gSavedSettings.setBOOL("RenderInitError", FALSE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + //HACK make screenbuffer allocations start failing after 30 seconds + if (gSavedSettings.getBOOL("SimulateFBOFailure")) + { + return false; + } } else { @@ -1671,6 +1720,21 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } +//static +void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) +{ + LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET); + for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + iter != gPipeline.mNearbyLights.end(); iter++) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + gPipeline.mNearbyLights.erase(iter); + } + } +} + U32 LLPipeline::addObject(LLViewerObject *vobj) { LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT); @@ -1850,6 +1914,10 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); if (done) { + if (drawablep->isRoot()) + { + drawablep->makeStatic(); + } drawablep->clearState(LLDrawable::ON_MOVE_LIST); if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) { //will likely not receive any future world matrix updates @@ -1981,6 +2049,7 @@ void LLPipeline::grabReferences(LLCullResult& result) void LLPipeline::clearReferences() { sCull = NULL; + mGroupSaveQ1.clear(); } void check_references(LLSpatialGroup* group, LLDrawable* drawable) @@ -2545,6 +2614,64 @@ void LLPipeline::updateGL() static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); +void LLPipeline::clearRebuildGroups() +{ + LLSpatialGroup::sg_vector_t hudGroups; + + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + } + + // Clear the group + mGroupQ1.clear(); + + // Copy the saved HUD groups back in + mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ1Locked = false; + + // Clear the HUD groups + hudGroups.clear(); + + mGroupQ2Locked = true; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + // Clear the group + mGroupQ2.clear(); + + // Copy the saved HUD groups back in + mGroupQ2.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ2Locked = false; +} + void LLPipeline::rebuildPriorityGroups() { LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS); @@ -2564,6 +2691,7 @@ void LLPipeline::rebuildPriorityGroups() group->clearState(LLSpatialGroup::IN_BUILD_Q1); } + mGroupSaveQ1 = mGroupQ1; mGroupQ1.clear(); mGroupQ1Locked = false; @@ -3469,7 +3597,7 @@ void LLPipeline::postSort(LLCamera& camera) rebuildPriorityGroups(); llpushcallstacks ; - + //build render map for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { @@ -3541,7 +3669,7 @@ void LLPipeline::postSort(LLCamera& camera) } } } - + //flush particle VB LLVOPartGroup::sVB->flush(); @@ -6720,10 +6848,10 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) LLFace* facep = drawable->getFace(i); if (facep) { - facep->clearVertexBuffer(); + facep->clearVertexBuffer(); + } } } -} void LLPipeline::resetVertexBuffers() { @@ -6762,6 +6890,8 @@ void LLPipeline::doResetVertexBuffers() gSky.resetVertexBuffers(); + LLVOPartGroup::destroyGL(); + if ( LLPathingLib::getInstance() ) { LLPathingLib::getInstance()->cleanupVBOManager(); @@ -7025,11 +7155,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGlowProgram.unbind(); - if (LLRenderTarget::sUseFBO) + /*if (LLRenderTarget::sUseFBO) { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + }*/ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; @@ -7096,15 +7226,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } else { - LLViewerObject* obj = gAgentCamera.getFocusObject(); - if (obj) - { //focus on alt-zoom target - focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); - } - else - { //focus on your avatar - focus_point = gAgent.getPositionAgent(); - } + //focus on alt-zoom target + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); } } @@ -7605,7 +7728,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n for (U32 i = 0; i < 4; i++) { - channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE); stop_glerror(); if (channel > -1) { @@ -7615,8 +7738,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); stop_glerror(); } } @@ -7696,13 +7819,13 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n matrix_nondiag, matrix_nondiag, matrix_diag}; shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat); - F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); - F32 shadow_bias_error = 1.f + RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f; shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f); - shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset*shadow_offset_error); - shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias*shadow_bias_error); + shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error); + shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias+shadow_bias_error); shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset); shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias); @@ -7912,10 +8035,6 @@ void LLPipeline::renderDeferredLighting() gGL.popMatrix(); stop_glerror(); - //copy depth and stencil from deferred screen - //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - mScreen.bindTarget(); // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky glClearColor(0,0,0,0); @@ -7993,7 +8112,7 @@ void LLPipeline::renderDeferredLighting() } mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - + LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { @@ -8039,7 +8158,7 @@ void LLPipeline::renderDeferredLighting() } sVisibleLightCount++; - + if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f || camera->getOrigin().mV[1] > c[1] + s + 0.2f || @@ -8426,9 +8545,9 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) for (U32 i = 0; i < 4; i++) { - if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) + if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1) { - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } } @@ -8687,8 +8806,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; - LLRenderTarget::unbindTarget(); - LLPipeline::sReflectionRender = FALSE; if (!LLRenderTarget::sUseFBO) @@ -8845,6 +8962,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gGL.setColorMask(false, false); LLFastTimer ftm(FTM_SHADOW_SIMPLE); + gGL.getTexUnit(0)->disable(); for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 368be1c14d..36abeca295 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -119,8 +119,25 @@ public: void createGLBuffers(); void createLUTBuffers(); - void allocateScreenBuffer(U32 resX, U32 resY); + //allocate the largest screen buffer possible up to resX, resY + //returns true if full size buffer allocated, false if some other size is allocated + bool allocateScreenBuffer(U32 resX, U32 resY); + + typedef enum { + FBO_SUCCESS_FULLRES = 0, + FBO_SUCCESS_LOWRES, + FBO_FAILURE + } eFBOStatus; + +private: + //implementation of above, wrapped for easy error handling + eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY); +public: + + //attempt to allocate screen buffers at resX, resY + //returns true if allocation successful, false otherwise bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples); + void allocatePhysicsBuffer(); void resetVertexBuffers(LLDrawable* drawable); @@ -151,6 +168,8 @@ public: void unlinkDrawable(LLDrawable*); + static void removeMutedAVsLights(LLVOAvatar*); + // Object related methods void markVisible(LLDrawable *drawablep, LLCamera& camera); void markOccluder(LLSpatialGroup* group); @@ -223,6 +242,7 @@ public: void updateGL(); void rebuildPriorityGroups(); void rebuildGroups(); + void clearRebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -382,6 +402,7 @@ private: BOOL updateDrawableGeom(LLDrawable* drawable, BOOL priority); void assertInitializedDoError(); bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; }; + void connectRefreshCachedSettingsSafe(const std::string name); void hideDrawable( LLDrawable *pDrawable ); void unhideDrawable( LLDrawable *pDrawable ); public: @@ -664,6 +685,8 @@ protected: LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref + LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called U32 mMeshDirtyQueryObject; diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index cf6f1ccdd9..33b876bdb9 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -481,7 +481,6 @@ Du kan bruge [SECOND_LIFE] normalt og andre personer vil se dig korrekt. [APP_NAME] installationen er færdig. Hvis det er første gang du bruger [SECOND_LIFE], skal du først oprette en konto for at logge på. -Vend tilbage til [http://join.secondlife.com secondlife.com] for at oprette en ny konto? </notification> <notification name="LoginPacketNeverReceived"> Der er problemer med at koble på. Der kan være et problem med din Internet forbindelse eller [SECOND_LIFE_GRID]. diff --git a/indra/newview/skins/default/xui/da/panel_login.xml b/indra/newview/skins/default/xui/da/panel_login.xml index 2e0f726e1a..b7cb76d4cb 100644 --- a/indra/newview/skins/default/xui/da/panel_login.xml +++ b/indra/newview/skins/default/xui/da/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + LOG PÅ + </text> <text name="username_text"> Brugernavn: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Password: </text> - <check_box label="Husk password" name="remember_check"/> - <button label="Log på" name="connect_btn"/> - <text name="mode_selection_text"> - Tilstand: - </text> - <combo_box name="mode_combo" tool_tip="Vælg ønsket tilstand. Vælg basis for hurtig og nem udforskning og chat. Vælg avanceret for at få adgang til flere muligheder."> - <combo_box.item label="Basis" name="Basic"/> - <combo_box.item label="Avanceret" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Start ved: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Indtast regionnavn>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Opret bruger + <layout_panel name="links_login_panel"> + <text name="login_help"> + Hjælp til login </text> <text name="forgot_password_text"> Har du glemt brugernavn eller password? </text> - <text name="login_help"> - Hjælp til login + <button label="Log på" name="connect_btn"/> + <check_box label="Husk password" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREATE YǾUR ACCǾUNT </text> + <button name="create_new_account_btn" label="Opret bruger"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index b4c28daac9..4387a61963 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -66,27 +66,26 @@ Voice-Serverversion: [VOICE_VERSION] </panel> <panel label="Lizenzen" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion. - APR Copyright (C) 2000-2004 The Apache Software Foundation. - Collada DOM Copyright 2005 Sony Computer Entertainment Inc. - cURL Copyright (C) 1996-2002, Daniel Stenberg (daniel@haxx.se). + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion. + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, Daniel Stenberg (daniel@haxx.se). DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. - FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). + FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm und Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University sowie David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW). jpeglib Copyright (C) 1991-1998, Thomas G. Lane. - ogg/vorbis Copyright (C) 2001, Xiphophorus. - OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. - PCRE Copyright (c) 1997-2008 University of Cambridge. + ogg/vorbis Copyright (C) 2002, Xiphophorus. + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 University of Cambridge. SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga. SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com). xmlrpc-epi Copyright (C) 2000 Epinions, Inc. - zlib Copyright (C) 1995-2002 Jean-loup Gailly und Mark Adler. - google-perftools Copyright (c) 2005, Google Inc. + zlib Copyright (C) 1995-2012 Jean-loup Gailly und Mark Adler. Second Life Viewer verwendet Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (und Lizenzgeber). Alle Rechte vorbehalten. Details siehe www.havok.com. diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml index 9e330f9766..44922fbe78 100644 --- a/indra/newview/skins/default/xui/de/floater_about_land.xml +++ b/indra/newview/skins/default/xui/de/floater_about_land.xml @@ -463,7 +463,7 @@ Nur große Parzellen können in der Suche aufgeführt werden. Zugang nur Einwohnern gestatten, die: </text> <check_box label="Zahlungsinformationen hinterlegt haben [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> - <check_box label="ihr Alter bestätigt haben [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner ihr Alter bestätigt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> + <check_box label="Sind mindestens 18 Jahre alt [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diese Parzelle betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/> <check_box label="Gruppenzugang erlauben: [GROUP]" name="GroupCheck" tool_tip="Gruppe im Register „Allgemein“ festlegen."/> <check_box label="Pässe verkaufen an:" name="PassCheck" tool_tip="Ermöglicht befristeten Zugang zu dieser Parzelle"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/de/floater_animation_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_preview.xml deleted file mode 100644 index 82a4a51d07..0000000000 --- a/indra/newview/skins/default/xui/de/floater_animation_preview.xml +++ /dev/null @@ -1,188 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> - <floater.string name="failed_to_initialize"> - Bewegung konnte nicht initialisiert werden - </floater.string> - <floater.string name="anim_too_long"> - Animationsdatei ist [LENGTH] Sekunden lang. - -Maximal erlaubt sind [MAX_LENGTH] Sekunden. - </floater.string> - <floater.string name="failed_file_read"> - Animationsdatei konnte nicht gelesen werden. - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - OK - </floater.string> - <floater.string name="E_ST_EOF"> - Unvollständige Datei - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Constraint-Definition kann nicht gelesen werden. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - BVH-Datei kann nicht geöffnet werden - </floater.string> - <floater.string name="E_ST_NO_HIER"> - Ungültiger HIERARCHY-Titel. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - ROOT oder JOINT nicht gefunden. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - JOINT-Name nicht erfasst. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - VERSATZ nicht gefunden. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - CHANNELS nicht gefunden. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Kann Rotations-Reihenfolge nicht erfassen. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Kann Rotations-Achse nicht erfassen. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - MOTION nicht gefunden. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - Anzahl der Bilder kann nicht erfasst werden. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Bildzeit kann nicht erfasst werden. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Positions-Werte können nicht erfasst werden. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Kann Rotations-Werte nicht erfassen. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Datei kann nicht geöffnet werden - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Übersetzungstitel kann nicht gelesen werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Übersetzungsnamen können nicht geladen werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Ignorier-Wert kann nicht gelesen werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Übersetzungs-Wert kann nicht gelesen werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Outname-Wert kann nicht gelesen werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Übersetzungsmatrix kann nicht geladen werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Mergechild-Name nicht erfasst. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Mergeparent-Name nicht erfasst. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Prioritätswert kann nicht erfasst werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Loop-Wert kann nicht erfasst werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Easeln-Wert kann nicht erfasst werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - easeOut-Wert kann nicht erfasst werden. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Hand-Morph-Wert nicht erfasst. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Emote-Name kann nicht gelesen werden. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Falscher Root-Joint-Name, "hip" verwenden. - </floater.string> - <text name="name_label"> - Name: - </text> - <line_editor name="name_form"/> - <text name="description_label"> - Beschreibung: - </text> - <spinner label="Priorität" name="priority" tool_tip="Steuert, welche Animationen von dieser Animation überschrieben werden können"/> - <check_box bottom_delta="-18" label="Schleife" name="loop_check" tool_tip="Erzeugt eine Animationsschleife"/> - <spinner label="In (%)" name="loop_in_point" tool_tip="Anfang einer Animationsschleife festlegen"/> - <spinner label="Aus (%)" name="loop_out_point" tool_tip="Ende einer Animationsschleife festlegen"/> - <text name="hand_label"> - Handhaltung - </text> - <combo_box label="" name="hand_pose_combo" tool_tip="Steuert während der Animation die Bewegung der Hände"> - <combo_box.item label="Dehnen" name="Spread"/> - <combo_box.item label="Entspannt" name="Relaxed"/> - <combo_box.item label="Beide zeigen" name="PointBoth"/> - <combo_box.item label="Faust" name="Fist"/> - <combo_box.item label="Links entspannt" name="RelaxedLeft"/> - <combo_box.item label="Nach links zeigen" name="PointLeft"/> - <combo_box.item label="Linke Faust" name="FistLeft"/> - <combo_box.item label="Rechts entspannt" name="RelaxedRight"/> - <combo_box.item label="Nach rechts zeigen" name="PointRight"/> - <combo_box.item label="Rechte Faust" name="FistRight"/> - <combo_box.item label="Rechts salutieren" name="SaluteRight"/> - <combo_box.item label="Tippt" name="Typing"/> - <combo_box.item label="Friedensrecht" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Ausdruck - </text> - <combo_box label="" name="emote_combo" tool_tip="Steuert Gesichtsregungen während der Animation"> - <item label="(Keiner)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Ängstlich" name="Afraid" value="Ängstlich"/> - <item label="Verärgert" name="Angry" value="Verärgert"/> - <item label="Grinst" name="BigSmile" value="Grinsend"/> - <item label="Gelangweilt" name="Bored" value="Gelangweilt"/> - <item label="Weinen" name="Cry" value="Weinen"/> - <item label="Verachten" name="Disdain" value="Verachten"/> - <item label="Verlegen" name="Embarrassed" value="Verlegen"/> - <item label="Stirnrunzeln" name="Frown" value="Stirnrunzeln"/> - <item label="Küssen" name="Kiss" value="Küssen"/> - <item label="Lachen" name="Laugh" value="Lachen"/> - <item label="Bäääh" name="Plllppt" value="Bäääh"/> - <item label="Angewidert" name="Repulsed" value="Angewidert"/> - <item label="Traurig" name="Sad" value="Traurig"/> - <item label="Schulterzucken" name="Shrug" value="Schulterzucken"/> - <item label="Lächeln" name="Smile" value="Lächeln"/> - <item label="Überraschung" name="Surprise" value="Überraschung"/> - <item label="Zwinkern" name="Wink" value="Zwinkern"/> - <item label="Sorgenvoll" name="Worry" value="Sorgenvoll"/> - </combo_box> - <text name="preview_label" width="97"> - Vorschau während: - </text> - <combo_box label="" left_delta="107" name="preview_base_anim" tool_tip="Hiermit können Sie das Verhalten Ihres Avatars testen, während Ihr Avatar normale Bewegungen ausführt."> - <item label="Stehend" name="Standing" value="Stehend"/> - <item label="Geht" name="Walking" value="Gehend"/> - <item label="Sitzt" name="Sitting" value="Sitzend"/> - <item label="Fliegen" name="Flying" value="Fliegen"/> - </combo_box> - <spinner label="Eingang glätten (s)" label_width="105" name="ease_in_time" tool_tip="Einblendungsgeschwindigkeit von Animationen (in Sekunden)" width="175"/> - <spinner bottom_delta="-20" label="Ausgang glätten (s)" label_width="105" left="10" name="ease_out_time" tool_tip="Ausblendegeschwindigkeit von Animationen (in Sekunden)" width="175"/> - <button bottom_delta="-32" label="" name="play_btn" tool_tip="Ihre Animation abspielen"/> - <button name="pause_btn" tool_tip="Ihre Animation pausieren"/> - <button label="" name="stop_btn" tool_tip="Animation anhalten"/> - <slider label="" name="playback_slider"/> - <text name="bad_animation_text"> - Animationsdatei konnte nicht gelesen werden. - -Wir empfehlen exportierte BVH-Dateien aus Poser 4. - </text> - <button label="Hochladen ([AMOUNT] L$)" name="ok_btn" width="160"/> - <button label="Abbrechen" left="180" name="cancel_btn" width="88"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_autoreplace.xml b/indra/newview/skins/default/xui/de/floater_autoreplace.xml new file mode 100644 index 0000000000..0c774990ef --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Einstellungen für automatische Ersetzung..."> + <check_box label="Automatische Ersetzung aktivieren..." name="autoreplace_enable" tool_tip="Eines oder mehrere Schlüsselwörter bei der Eingabe von Chat-Text durch die entsprechende Ersetzung substituieren"/> + <button label="Liste importieren..." name="autoreplace_import_list" tool_tip="Exportierte Liste aus einer Datei laden."/> + <button label="Liste exportieren..." name="autoreplace_export_list" tool_tip="Ausgewählte Liste zur Weitergabe in einer Datei speichern."/> + <button label="Neue Liste..." name="autoreplace_new_list" tool_tip="Neue Liste erstellen."/> + <button label="Liste löschen" name="autoreplace_delete_list" tool_tip="Ausgewählte Liste löschen."/> + <button name="autoreplace_list_up" tool_tip="Dieser Liste eine höhere Priorität einräumen."/> + <button name="autoreplace_list_down" tool_tip="Dieser Liste eine niedrigere Priorität einräumen."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Schlüsselwort" name="keyword"/> + <scroll_list.columns label="Ersetzung" name="replacement"/> + </scroll_list> + <button label="Hinzufügen..." name="autoreplace_add_entry"/> + <button label="Entfernen" name="autoreplace_delete_entry"/> + <button label="Eintrag speichern" name="autoreplace_save_entry" tool_tip="Diesen Eintrag speichern."/> + <button label="Änderungen speichern" name="autoreplace_save_changes" tool_tip="Alle Änderungen speichern."/> + <button label="Abbrechen" name="autoreplace_cancel" tool_tip="Alle Änderungen löschen."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/de/floater_inventory.xml b/indra/newview/skins/default/xui/de/floater_inventory.xml deleted file mode 100644 index d9b7c30fd2..0000000000 --- a/indra/newview/skins/default/xui/de/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MEIN INVENTAR"> - <floater.string name="Title"> - MEIN INVENTAR - </floater.string> - <floater.string name="TitleFetching"> - MEIN INVENTAR ([ITEM_COUNT] Objekte werden abgerufen...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MEIN INVENTAR ([ITEM_COUNT] Objekte) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Abgerufen - </floater.string> - <panel label="Inventar" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_model_preview.xml b/indra/newview/skins/default/xui/de/floater_model_preview.xml index 4af8d67686..4285462bc8 100644 --- a/indra/newview/skins/default/xui/de/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/de/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="Dreiecke" name="triangles" value="Dreiecke"/> <text initial_value="Scheitelpunkte" name="vertices" value="Scheitelpunkte"/> <text initial_value="Hoch" name="high_label" value="Hoch"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Mittel" name="medium_label" value="Mittel"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + <item name="Use LoD above" value="Detailstufe oben verwenden"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Niedrig" name="low_label" value="Niedrig"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + <item name="Use LoD above" value="Detailstufe oben verwenden"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Niedrigste" name="lowest_label" value="Niedrigste"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Aus Datei laden"/> + <item name="Generate" value="Generieren"/> + <item name="Use LoD above" value="Detailstufe oben verwenden"/> + </combo_box> <button label="Durchsuchen..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Dreiecklimit"/> + <item name="Error Threshold" value="Fehlerschwelle"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Normalen generieren" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/de/floater_nearby_chat.xml b/indra/newview/skins/default/xui/de/floater_nearby_chat.xml deleted file mode 100644 index 2aabbb18f2..0000000000 --- a/indra/newview/skins/default/xui/de/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT IN DER NÄHE"> - <check_box label="Chat übersetzen" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..7096dbc156 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Pathfinding-Figuren"> + <floater.string name="messaging_get_inprogress"> + Pathfinding-Figuren werden abgerufen... + </floater.string> + <floater.string name="messaging_get_error"> + Fehler beim Abrufen von Pathfinding-Figuren. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Keine Pathfinding-Figuren. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] Figuren von [NUM_TOTAL] ausgewählt. + </floater.string> + <floater.string name="messaging_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Laden] + </floater.string> + <floater.string name="character_owner_unknown"> + [Unbekannt] + </floater.string> + <floater.string name="character_owner_group"> + [Gruppe] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Name" name="name"/> + <scroll_list.columns label="Beschreibung" name="description"/> + <scroll_list.columns label="Eigentümer" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Höhe" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Figuren: + </text> + <button label="Liste aktualisieren" name="refresh_objects_list"/> + <button label="Alle auswählen" name="select_all_objects"/> + <button label="Keine auswählen" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Aktionen für ausgewählte Figuren: + </text> + <check_box label="Beacon anzeigen" name="show_beacon"/> + <check_box label="Physikkapsel anzeigen" name="show_physics_capsule"/> + <button label="Nehmen" name="take_objects"/> + <button label="Kopie nehmen" name="take_copy_objects"/> + <button label="Dorthin teleportieren" name="teleport_me_to_object" tool_tip="Nur aktiviert, wenn eine Figur ausgewählt ist."/> + <button label="Zurückgeben" name="return_objects"/> + <button label="Löschen" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml new file mode 100644 index 0000000000..ebf8f01632 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Pathfinding-Ansicht/-Test"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Pathfinding-Bibliotheksimplementierung nicht gefunden. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Warten, bis Region geladen ist. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Navmesh-Status wird geprüft. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Navmesh wird heruntergeladen. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Navmesh hat sich auf dem Server geändert. Neuestes Navmesh wird heruntergeladen. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Neuestes Navmesh wurde heruntergeladen. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Navmesh kann nicht heruntergeladen werden. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Navmesh weist ausstehende Änderungen auf. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Navmesh wird erstellt. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Einige Navmesh-Regionen weisen ausstehende Änderungen auf. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Einige Navmesh-Regionen werden erstellt. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Einige Navmesh-Regionen weisen ausstehende Änderungen auf und andere werden erstellt. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Navmesh ist aktuell. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Pathfinding-Bibliotheksimplementierung nicht gefunden. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Bitte wählen Sie Anfangs- und Endpunkte aus. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Bitte wählen Sie einen Anfangspunkt aus. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Bitte wählen Sie einen Endpunkt aus. + </floater.string> + <floater.string name="pathing_path_valid"> + Pfad wird orange dargestellt. + </floater.string> + <floater.string name="pathing_path_invalid"> + Zwischen den gewählten Punkten wurde kein Pfad gefunden. + </floater.string> + <floater.string name="pathing_error"> + Fehler bei der Pfaderstellung aufgetreten. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Anzeigen" name="view_panel"> + <text name="show_label"> + Anzeigen: + </text> + <check_box label="Welt" name="show_world"/> + <check_box label="Nur bewegliche Objekte" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Begehbarkeitskarte anzeigen: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Nicht anzeigen" name="show_heatmap_mode_none"/> + <combo_box.item label="Figurentyp A" name="show_heatmap_mode_a"/> + <combo_box.item label="Figurentyp B" name="show_heatmap_mode_b"/> + <combo_box.item label="Figurentyp C" name="show_heatmap_mode_c"/> + <combo_box.item label="Figurentyp D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Begehbare Objekte" name="show_walkables"/> + <check_box label="Materialvolumen" name="show_material_volumes"/> + <check_box label="Statische Hinternisse" name="show_static_obstacles"/> + <check_box label="Ausschlussvolumen" name="show_exclusion_volumes"/> + <check_box label="Wasserebene" name="show_water_plane"/> + <check_box label="Mit Röntgenblick" name="show_xray"/> + </panel> + <panel label="Pfad testen" name="test_panel"> + <text name="ctrl_click_label"> + Bei gedrückter Strg-Taste klicken, um Anfangspunkt auszuwählen. + </text> + <text name="shift_click_label"> + Bei gedrückter Umschalttaste klicken, um Endpunkt auszuwählen. + </text> + <text name="character_width_label"> + Figurenbreite + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Figurentyp + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Keine" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Pfad löschen" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..0d3ba59efb --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Pathfinding-Linksets"> + <floater.string name="messaging_get_inprogress"> + Pathfinding-Linksets werden abgerufen... + </floater.string> + <floater.string name="messaging_get_error"> + Fehler beim Abrufen von Pathfinding-Linksets. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Ausgewählte Pathfinding-Linksets werden geändert... + </floater.string> + <floater.string name="messaging_set_error"> + Fehler beim Ändern der ausgewählten Pathfinding-Linksets. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Keine Pathfinding-Linksets. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] Linksets von [NUM_TOTAL] ausgewählt. + </floater.string> + <floater.string name="messaging_not_enabled"> + Pathfinding ist in dieser Region nicht aktiviert. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Laden] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Unbekannt] + </floater.string> + <floater.string name="linkset_owner_group"> + [Gruppe] + </floater.string> + <floater.string name="linkset_is_scripted"> + Ja + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Nein + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Unbekannt + </floater.string> + <floater.string name="linkset_use_walkable"> + Begehbar + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Statisches Hinternis + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Bewegliches Hinternis + </floater.string> + <floater.string name="linkset_use_material_volume"> + Materialvolumen + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Ausschlussvolumen + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Bewegliches Phantom + </floater.string> + <floater.string name="linkset_is_terrain"> + [nicht änderbar] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [beschränkt] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [konkav] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [beschränkt,konkav] + </floater.string> + <floater.string name="linkset_choose_use"> + Linkset-Nutzung auswählen... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Nach Linkset-Nutzung filtern..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Begehbar" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Statisches Hinternis" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Bewegliches Hinternis" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Materialvolumen" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Ausschlussvolumen" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Bewegliches Phantom" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Anwenden" name="apply_filters"/> + <button label="Entfernen" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Name (Hauptprim)" name="name"/> + <scroll_list.columns label="Beschreibung (Hauptprim)" name="description"/> + <scroll_list.columns label="Eigentümer" name="owner"/> + <scroll_list.columns label="Geskriptet" name="scripted"/> + <scroll_list.columns label="Belastung" name="land_impact"/> + <scroll_list.columns label="Abstand" name="dist_from_you"/> + <scroll_list.columns label="Linkset-Nutzung" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Linksets: + </text> + <button label="Liste aktualisieren" name="refresh_objects_list"/> + <button label="Alle auswählen" name="select_all_objects"/> + <button label="Keine auswählen" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Beacon anzeigen" name="show_beacon"/> + <button label="Nehmen" name="take_objects"/> + <button label="Kopie nehmen" name="take_copy_objects"/> + <button label="Dorthin teleportieren" name="teleport_me_to_object"/> + <button label="Zurückgeben" name="return_objects"/> + <button label="Löschen" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Begehbarkeit: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Begehbarkeit für Figuren vom Typ A. Ein Beispiel für diesen Typ wäre „Humanoid“."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Begehbarkeit für Figuren vom Typ B. Ein Beispiel für diesen Typ wäre „Kreatur“."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Begehbarkeit für Figuren vom Typ C. Ein Beispiel für diesen Typ wäre „Mechanisch“."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Begehbarkeit für Figuren vom Typ D. Ein Beispiel für diesen Typ wäre „Anderer“."/> + <button label="Änderungen übernehmen" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoid) + </text> + <text name="suggested_use_b_label"> + (Kreatur) + </text> + <text name="suggested_use_c_label"> + (Mechanisch) + </text> + <text name="suggested_use_d_label"> + (Anderer) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_postcard.xml b/indra/newview/skins/default/xui/de/floater_postcard.xml deleted file mode 100644 index 28af0183cb..0000000000 --- a/indra/newview/skins/default/xui/de/floater_postcard.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="FOTO EMAILEN"> - <text name="to_label"> - E-Mail des Empfängers: - </text> - <text name="from_label"> - Ihre E-Mail: - </text> - <text name="name_label"> - Ihr Name: - </text> - <text name="subject_label"> - Betreff: - </text> - <line_editor label="Betreff hier eingeben." name="subject_form"/> - <text name="msg_label"> - Nachricht: - </text> - <text_editor name="msg_form"> - Nachricht hier eingeben. - </text_editor> - <text name="fine_print"> - Wenn sich der Empfänger bei SL anmeldet, erhalten Sie einen Empfehlungsbonus. - </text> - <button label="Abbrechen" name="cancel_btn"/> - <button label="Senden" name="send_btn"/> - <text name="default_subject"> - Postkarte aus [SECOND_LIFE]. - </text> - <text name="default_message"> - Sehen Sie hier! - </text> - <string name="upload_message"> - Wird gesendet... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_spellcheck.xml b/indra/newview/skins/default/xui/de/floater_spellcheck.xml new file mode 100644 index 0000000000..213db277b6 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Einstellungen für Rechtschreibprüfung"> + <check_box label="Rechtschreibprüfung aktivieren" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Hauptwörterbuch: + </text> + <text label="Protokolle:" name="spellcheck_additional"> + Zusätzliche Wörterbücher: + </text> + <text name="spellcheck_available"> + Verfügbar + </text> + <text name="spellcheck_active"> + Aktiv + </text> + <button label="Entfernen" name="spellcheck_remove_btn"/> + <button label="Importieren..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml new file mode 100644 index 0000000000..374c0fc0d2 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Wörterbuch importieren"> + <button label="Durchsuchen" label_selected="Durchsuchen" name="dictionary_path_browse"/> + <button label="Importieren" name="ok_btn"/> + <button label="Abbrechen" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_stats.xml b/indra/newview/skins/default/xui/de/floater_stats.xml index 92d057a4fe..f3239f73c7 100644 --- a/indra/newview/skins/default/xui/de/floater_stats.xml +++ b/indra/newview/skins/default/xui/de/floater_stats.xml @@ -53,7 +53,13 @@ <stat_bar label="Objekte" name="simobjects"/> <stat_bar label="Aktive Objekte" name="simactiveobjects"/> <stat_bar label="Aktive Skripts" name="simactivescripts"/> + <stat_bar label="Skripts ausgeführt" name="simpctscriptsrun"/> <stat_bar label="Skript-Events" name="simscripteps"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="AI-Schrittzeit" name="simsimaistepmsec"/> + <stat_bar label="Übersprungene Silhouettenschritte" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Figuren aktualisiert" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="Paketeingang" name="siminpps"/> <stat_bar label="Paketausgang" name="simoutpps"/> <stat_bar label="Ausstehende Downloads" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml index 5bb96bebc4..9585622516 100644 --- a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml @@ -20,6 +20,8 @@ <button label="Leer" label_selected="Leer" name="Blank"/> <button label="Keine" label_selected="Keine" name="None"/> <button label="" label_selected="" name="Pipette"/> + <check_box initial_value="true" label="Live-Vorschau" name="apply_immediate_check"/> + <text name="preview_disabled" value="Vorschau deaktiviert"/> <filter_editor label="Texturen filtern" name="inventory search editor"/> <check_box initial_value="false" label="Ordner anzeigen" name="show_folders_check"/> <button label="Hinzufügen" label_selected="Hinzufügen" name="l_add_btn"/> @@ -31,5 +33,4 @@ </scroll_list> <button label="OK" label_selected="OK" name="Select"/> <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> - <check_box initial_value="true" label="Jetzt übernehmen" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml index 0f407cb15c..97b0364832 100644 --- a/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, Neuabruf sichtbarer Texturen aus Cache, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel </text> + <text name="total_time_refetch_all_cache_label"> + 16, Neuabruf aller Texturen aus Cache, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + </text> <text name="total_time_refetch_vis_http_label"> - 16, Neuabruf sichtbarer Texturen von HTTP, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + 17, Neuabruf sichtbarer Texturen von HTTP, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + </text> + <text name="total_time_refetch_all_http_label"> + 18, Neuabruf aller Texturen von HTTP, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel + </text> + <spinner label="19, Verhältnis Texel/Pixel:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Texturquelle: </text> - <spinner label="17, Verhältnis Texel/Pixel:" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="Nur HTTP" name="1"/> + </radio_group> <button label="Starten" name="start_btn"/> <button label="Zurücksetzen" name="clear_btn"/> <button label="Schließen" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="Decodieren" name="decode_btn"/> <button label="GL-Textur" name="gl_btn"/> <button label="Neuabruf sichtbarer Texturen (Cache)" name="refetchviscache_btn"/> + <button label="Neuabruf des gesamten Cache" name="refetchallcache_btn"/> <button label="Neuabruf sichtbarer Texturen (HTTP)" name="refetchvishttp_btn"/> + <button label="Neuabruf des gesamten HTTP" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index dee89b28e5..5f5c34a5cf 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -148,6 +148,12 @@ <panel.string name="text modify info 4"> Sie können diese Objekte nicht bearbeiten. </panel.string> + <panel.string name="text modify info 5"> + Dieses Objekt kann nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> + <panel.string name="text modify info 6"> + Diese Objekte können nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> <panel.string name="text modify warning"> Gesamtes Objekt wählen, um Berechtigungen festzulegen. </panel.string> @@ -197,12 +203,12 @@ <combo_box.item label="Zoom" name="Zoom"/> </combo_box> <check_box label="Zum Verkauf:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Kopie" name="Copy"/> <combo_box.item label="Inhalt" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Preis: L$" name="Edit Cost"/> <check_box label="In Suche anzeigen" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/> <panel name="perms_build"> <text name="perm_modify"> @@ -238,6 +244,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Pathfinding-Attribute: + </text> + </panel> </panel> <panel label="Objekt" name="Object"> <check_box label="Gesperrt" name="checkbox locked" tool_tip="Verhindert, dass das Objekt verschoben oder gelöscht wird. Oft beim Bauen nützlich, um unbeabsichtigte Bearbeitungen zu vermeiden."/> diff --git a/indra/newview/skins/default/xui/de/floater_top_objects.xml b/indra/newview/skins/default/xui/de/floater_top_objects.xml index d2055a53db..f8130c6379 100644 --- a/indra/newview/skins/default/xui/de/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/de/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Zeit </floater.string> - <floater.string name="scripts_mono_time_label"> - Mono-Uhrzeit: - </floater.string> <floater.string name="top_colliders_title"> Top-Kollisionsobjekte </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Name" name="name" width="135"/> <scroll_list.columns label="Eigentümer" name="owner"/> <scroll_list.columns label="Position" name="location" width="125"/> + <scroll_list.columns label="Parzelle" name="parcel"/> <scroll_list.columns label="Uhrzeit" name="time"/> - <scroll_list.columns label="Mono-Uhrzeit:" name="mono_time"/> <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="Speicher (KB)" name="memory"/> </scroll_list> <text name="id_text"> Objekt-ID: @@ -42,12 +40,16 @@ <button label="Beacon anzeigen" name="show_beacon_btn"/> <text name="obj_name_text"> Objektname: - </text> + </text> <button label="Filter" name="filter_object_btn"/> <text name="owner_name_text"> Eigentümer: - </text> + </text> <button label="Filter" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parzelle: + </text> + <button label="Filtern" name="filter_parcel_btn"/> <button label="Aktualisieren" name="refresh_btn"/> <button label="Auswahl zurückgeben" name="return_selected_btn" width="134"/> <button label="Alle zurückgeben" left="150" name="return_all_btn" width="134"/> diff --git a/indra/newview/skins/default/xui/de/menu_bottomtray.xml b/indra/newview/skins/default/xui/de/menu_bottomtray.xml deleted file mode 100644 index cb0082f944..0000000000 --- a/indra/newview/skins/default/xui/de/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Schaltfläche „Sprechen“" name="EnableVoiceChat"/> - <menu_item_check label="Schaltfläche Gesten" name="ShowGestureButton"/> - <menu_item_check label="Schaltfläche Bewegungssteuerung" name="ShowMoveButton"/> - <menu_item_check label="Schaltfläche Ansicht" name="ShowCameraButton"/> - <menu_item_check label="Schaltfläche Foto" name="ShowSnapshotButton"/> - <menu_item_check label="Schaltfläche „Bauen“" name="ShowBuildButton"/> - <menu_item_check label="Schaltfläche „Suchen“" name="ShowSearchButton"/> - <menu_item_check label="Schaltfläche „Karte“" name="ShowWorldMapButton"/> - <menu_item_check label="Minikarten-Schaltfläche" name="ShowMiniMapButton"/> - <menu_item_call label="Ausschneiden" name="NearbyChatBar_Cut"/> - <menu_item_call label="Kopieren" name="NearbyChatBar_Copy"/> - <menu_item_call label="Einfügen" name="NearbyChatBar_Paste"/> - <menu_item_call label="Löschen" name="NearbyChatBar_Delete"/> - <menu_item_call label="Alle auswählen" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/de/menu_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml index 39b3099336..cd2fca313e 100644 --- a/indra/newview/skins/default/xui/de/menu_inventory.xml +++ b/indra/newview/skins/default/xui/de/menu_inventory.xml @@ -68,6 +68,7 @@ <menu_item_call label="Systemordner löschen" name="Delete System Folder"/> <menu_item_call label="Konferenz-Chat starten" name="Conference Chat Folder"/> <menu_item_call label="Wiedergeben/Abspielen" name="Sound Play"/> + <menu_item_call label="SLurl kopieren" name="url_copy"/> <menu_item_call label="Landmarken-Info" name="About Landmark"/> <menu_item_call label="Inworld abspielen" name="Animation Play"/> <menu_item_call label="Lokal abspielen" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/de/menu_mode_change.xml b/indra/newview/skins/default/xui/de/menu_mode_change.xml deleted file mode 100644 index b8090018b7..0000000000 --- a/indra/newview/skins/default/xui/de/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Basis" name="BasicMode"/> - <menu_item_check label="Erweitert" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/de/menu_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml index 412bd3ac04..9f44ced928 100644 --- a/indra/newview/skins/default/xui/de/menu_object.xml +++ b/indra/newview/skins/default/xui/de/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Bearbeiten" name="Edit..."/> <menu_item_call label="Bauen" name="Build"/> + <menu_item_call label="In Linksets anzeigen" name="show_in_linksets"/> + <menu_item_call label="In Figuren anzeigen" name="show_in_characters"/> <menu_item_call label="Öffnen" name="Open"/> <menu_item_call label="Hier sitzen" name="Object Sit"/> <menu_item_call label="Aufstehen" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/de/menu_text_editor.xml b/indra/newview/skins/default/xui/de/menu_text_editor.xml index c00186c13e..2e33ed3416 100644 --- a/indra/newview/skins/default/xui/de/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/de/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(unbekannt)" name="Suggestion 1"/> + <menu_item_call label="(unbekannt)" name="Suggestion 2"/> + <menu_item_call label="(unbekannt)" name="Suggestion 3"/> + <menu_item_call label="(unbekannt)" name="Suggestion 4"/> + <menu_item_call label="(unbekannt)" name="Suggestion 5"/> + <menu_item_call label="Zum Wörterbuch hinzufügen" name="Add to Dictionary"/> + <menu_item_call label="Zur Ignorieren-Liste hinzufügen" name="Add to Ignore"/> <menu_item_call label="Ausschneiden" name="Cut"/> <menu_item_call label="Kopieren" name="Copy"/> <menu_item_call label="Einfügen" name="Paste"/> diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index 856f91e214..845df1f050 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -28,6 +28,7 @@ <menu_item_call label="Einstellungen..." name="Preferences"/> <menu_item_call label="Symbolleistenschaltflächen..." name="Toolbars"/> <menu_item_call label="Alle Steuerelemente ausblenden" name="Hide UI"/> + <menu_item_check label="HUD-Anhänge anzeigen" name="Show HUD Attachments"/> <menu_item_call label="[APP_NAME] schließen" name="Quit"/> </menu> <menu label="Unterhalten" name="Communicate"> @@ -39,6 +40,7 @@ <menu_item_call label="Freunde" name="My Friends"/> <menu_item_call label="Gruppen" name="My Groups"/> <menu_item_call label="Leute in der Nähe" name="Active Speakers"/> + <menu_item_call label="Blockierliste" name="Block List"/> </menu> <menu label="Welt" name="World"> <menu_item_call label="Landmarke für diesen Ort setzen" name="Create Landmark Here"/> @@ -124,6 +126,11 @@ <menu_item_call label="Skripts auf ausführen einstellen" name="Set Scripts to Running"/> <menu_item_call label="Skripts auf nicht ausführen einstellen" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Figuren..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Anzeigen/Testen..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Optionen" name="Options"> <menu_item_check label="Erweiterte Berechtigungen anzeigen" name="DebugPermissions"/> <menu_item_check label="Nur meine Objekte auswählen" name="Select Only My Objects"/> @@ -174,7 +181,6 @@ <menu_item_check label="Partikel ausblenden" name="Hide Particles"/> <menu_item_check label="Auswahl ausblenden" name="Hide Selected"/> <menu_item_check label="Durchsichtig hervorheben" name="Highlight Transparent"/> - <menu_item_check label="HUD-Anhänge anzeigen" name="Show HUD Attachments"/> <menu_item_check label="Fadenkreuz für Mouselook anzeigen" name="ShowCrosshairs"/> </menu> <menu label="Darstellungstypen" name="Rendering Types"> @@ -377,7 +383,6 @@ <menu_item_call label="Avatargeometry ein-/ausschalten" name="Toggle Character Geometry"/> <menu_item_call label="Männlich testen" name="Test Male"/> <menu_item_call label="Weiblich testen" name="Test Female"/> - <menu_item_call label="PG ein-/ausschalten" name="Toggle PG"/> <menu_item_check label="Avatarauswahl zulassen" name="Allow Select Avatar"/> </menu> <menu_item_call label="Param auf Standard erzwingen" name="Force Params to Default"/> diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index f7274d31e1..4b7a60b4eb 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -367,13 +373,19 @@ Sie müssen den Benutzernamen Ihres Avatars eingeben. Sie benötigen ein Konto, um [SECOND_LIFE] betreten zu können. Möchten Sie jetzt ein Konto erstellen? <url name="url"> - https://join.secondlife.com/index.php?lang=de-DE + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Erneut versuchen" yestext="Neues Benutzerkonto anlegen"/> </notification> <notification name="InvalidCredentialFormat"> Sie müssen entweder den Benutzernamen oder den Vor- und Nachnamen Ihres Avatars in das Feld „Benutzername“ eingeben und die Anmeldung dann erneut versuchen. </notification> + <notification name="InvalidGrid"> + „[GRID]“ ist keine gültige Grid-ID. + </notification> + <notification name="InvalidLocationSLURL"> + Ihre Startposition gibt kein gültiges Grid an. + </notification> <notification name="DeleteClassified"> Anzeige „[NAME]“ löschen? Gebühren werden nicht rückerstattet. @@ -479,8 +491,8 @@ Das Objekt ist möglicherweise außer Reichweite oder wurde gelöscht. Ein kompiliertes Skript konnte aus folgendem Grund nicht gespeichert werden: [REASON]. Speichern Sie das Skript bitte später. </notification> <notification name="StartRegionEmpty"> - Sie haben keine Start-Region festgelegt. -Bitte geben Sie den Namen der Region im Feld „Startposition“ ein oder wählen Sie „Mein letzter Standort“ oder „Mein Zuhause“ als Startposition aus. + Ihre Startregion ist nicht definiert. +Geben Sie den Namen der Region im Feld „Startposition“ ein oder wählen Sie „Mein letzter Standort“ oder „Mein Zuhause“ als Startposition aus. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -607,6 +619,9 @@ Sie können maximal [MAX] Objekte verknüpfen. Stellen Sie sicher, dass kein Objekt gesperrt ist und alle Objekte Ihnen gehören. </notification> + <notification name="CannotLinkPermanent"> + Objekte können nicht über Regionsgrenzen hinweg verknüpft werden. + </notification> <notification name="CannotLinkDifferentOwners"> Verknüpfung nicht möglich, da nicht alle Objekte denselben Eigentümer haben. @@ -991,6 +1006,41 @@ Sie sind nicht berechtigt, Land für die aktive Gruppe zu kaufen. <button name="Cancel" text="Abbrechen"/> </form> </notification> + <notification label="Automatische Ersetzungsliste hinzufügen" name="AddAutoReplaceList"> + Name für neue Liste: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Automatische Ersetzungsliste umbenennen" name="RenameAutoReplaceList"> + Der Name „[DUPNAME]“ wird bereits verwendet. + Geben Sie einen neuen eindeutigen Namen ein: + <form name="form"> + <button name="ReplaceList" text="Aktuelle Liste ersetzen"/> + <button name="SetName" text="Neuen Namen verwenden"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Das Schlüsselwort muss ein einziges Wort sein; die Ersetzungszeichenfolge darf nicht leer sein. + </notification> + <notification name="InvalidAutoReplaceList"> + Diese Ersetzungsliste ist nicht gültig. + </notification> + <notification name="SpellingDictImportRequired"> + Sie müssen eine Datei, einen Namen und eine Sprache angeben. + </notification> + <notification name="SpellingDictIsSecondary"> + Das Wörterbuch [DIC_NAME] scheint keine „aff“-Datei zu haben und ist deshalb ein sekundäres Wörterbuch. +Es kann als zusätzliches Wörterbuch verwendet werden, aber nicht als Hauptwörterbuch. + +Weitere Informationen finden Sie unter https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries. + </notification> + <notification name="SpellingDictImportFailed"> + Kopieren nicht möglich: + [FROM_NAME] + in + [TO_NAME] + </notification> <notification label="Outfit speichern" name="SaveOutfitAs"> Mein aktuelles Outfit als neues Outfit speichern: <form name="form"> @@ -1171,7 +1221,7 @@ in „[THIS_GPU]“ Sie wurden zur nächstgelegenen Region teleportiert. </notification> <notification name="AvatarMovedLast"> - Ihr letzter Standort ist zurzeit nicht verfügbar. + Ihr angeforderter Standort ist zurzeit nicht verfügbar. Sie wurden zur nächstgelegenen Region teleportiert. </notification> <notification name="AvatarMovedHome"> @@ -1190,8 +1240,7 @@ Sie können [SECOND_LIFE] normal verwenden. Andere Benutzer können Sie korrekt Installation von [APP_NAME] vollständig abgeschlossen. Falls Sie [SECOND_LIFE] zum ersten Mal verwenden, müssen Sie zuerst ein Konto erstellen, bevor Sie sich anmelden können. -Zurück zu [http://join.secondlife.com secondlife.com], um ein neues Konto zu erstellen? - <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Neues Konto..."/> + <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Konto erstellen..."/> </notification> <notification name="LoginPacketNeverReceived"> Es gibt Probleme mit der Verbindung. Möglicherweise besteht ein Problem mit Ihrer Internetverbindung oder dem [SECOND_LIFE_GRID]. @@ -1708,83 +1757,128 @@ Tausende Regionen werden verändert und der Spaceserver wird dadurch stark belas <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind. - -Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren. + Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. - -Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de </url> - <usetemplate ignoretext="Ich kann diese Region aufgrund der Alterseinstufung nicht betreten" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/> + <usetemplate ignoretext="Regionswechsel: Die Region, die Sie besuchen möchten, enthält Inhalte, die nur für Erwachsene zugänglich sind." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Aufgrund Ihrer Alterseinstufung dürfen Sie diese Region nicht betreten. + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Sie dürfen diese Region aufgrund der Einstellung Ihrer Inhaltseinstufung nicht betreten. - -Bitte ändern Sie Ihre Einstellungen bezüglich der Inhaltseinstufung, um die gewünschte Region zu betreten. Danach können Sie nach [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Um die Veränderungen rückgängig zu machen, gehen Sie zu Ich > Einstellungen > Allgemein. + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern oder diesen Vorgang abbrechen. Nachdem Sie Ihre Einstellungen geändert haben, können Sie erneut versuchen, die Region zu betreten. <form name="form"> - <button name="OK" text="Einstellung ändern"/> - <button name="Cancel" text="Schließen"/> - <ignore name="ignore" text="Meine Alterseinstufung lässt nicht zu, dass ich eine Region betrete."/> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Regionswechsel: Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Wir haben technische Probleme mit Ihrem Teleport, da Ihre Einstellungen nicht mit dem Server synchronisiert sind. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de + </url> + <usetemplate ignoretext="Teleport: Die Region, die Sie besuchen möchten, enthält Inhalte, die nur für Erwachsene zugänglich sind." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und den Teleport fortsetzen oder Sie können den Teleport abbrechen. + <form name="form"> + <button name="OK" text="Ändern und fortfahren"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Teleport (kann neu gestartet werden): Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern oder den Teleport abbrechen. Nachdem Sie Ihre Einstellungen geändert haben, können Sie den Teleport erneut versuchen. + <form name="form"> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Teleport (kann nicht neu gestartet werden): Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Wir haben technische Probleme mit Ihrem Teleport, da Ihre Einstellungen nicht mit dem Server synchronisiert sind. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Ihre Inhaltseinstufung ist jetzt [RATING]. + Sie erhalten keine Benachrichtigungen mehr, wenn Sie eine Region der Inhaltseinstufung „[RATING]“ besuchen. Sie können Ihre Inhaltseinstellungen von der Menüleiste aus ändern („Ich“ > „Einstellungen“ > „Allgemein“). + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Wir konnten Ihre Einstellungen zur Anzeige von [PREFERRED_MATURITY]-Inhalten leider nicht ändern. Ihre Einstellungen wurden auf [ACTUAL_MATURITY]-Inhalte zurückgesetzt. Sie können erneut versuchen, Ihre Inhaltseinstellungen von der Menüleiste aus zu ändern („Ich“ > „Einstellungen“ > „Allgemein“). + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind. - -Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren. + Die Inhaltseinstufung des Landes, das Sie in Besitz nehmen möchten, überschreitet Ihre aktuellen Einstellungen. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land. - -Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Nur Erwachsene können dieses Land in Besitz nehmen. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de </url> - <usetemplate ignoretext="Ich habe aufgrund der Alterseinstufung keinen Anspruch auf dieses Land" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/> + <usetemplate ignoretext="Nur Erwachsene können dieses Land in Besitz nehmen." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land. + Das Land, das Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Das Land, das Sie in Besitz nehmen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind. </notification> <notification name="LandClaimAccessBlocked_Change"> - Sie haben aufgrund der Einstellung Ihrer Alterseinstufung keinen Anspruch auf dieses Land. - -Klicken Sie auf „Einstellung ändern“, um Ihre Einstellung für Altereinstufung sofort zu ändern und Zugang zu erhalten. Sie können ab sofort [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Falls Sie diese Einstellung später rückgängig machen möchten, gehen Sie zu Bearbeiten > Einstellungen > Allgemein. - <usetemplate ignoretext="Meine Alterseinstufung lässt nicht zu, dass ich auf Land Anspruch erhebe" name="okcancelignore" notext="Schließen" yestext="Einstellung ändern"/> + Das Land, das Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und anschließend erneut versuchen, das Land in Besitz zu nehmen. + <form name="form"> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Das Land, das Sie in Besitz nehmen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind. - -Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren. + Die Inhaltseinstufung des Landes, das Sie kaufen möchten, überschreitet Ihre aktuellen Einstellungen. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen. - -Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Nur Erwachsene können dieses Land kaufen. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de </url> - <usetemplate ignoretext="Ich kann aufgrund der Alterseinstufung dieses Land nicht kaufen" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/> + <usetemplate ignoretext="Nur Erwachsene können dieses Land kaufen." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen. + Das Land, das Sie kaufen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Das Land, das Sie kaufen möchten, enthält Inhalte der Einstufung „[REGIONMATURITY]“, die nur für Erwachsene zugänglich sind. </notification> <notification name="LandBuyAccessBlocked_Change"> - Sie können aufgrund Ihrer Einstellung für Alterseinstufung dieses Land nicht kaufen. - -Klicken Sie auf „Einstellung ändern“, um Ihre Einstellung für Altereinstufung sofort zu ändern und Zugang zu erhalten. Sie können ab sofort [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Falls Sie diese Einstellung später rückgängig machen möchten, gehen Sie zu Bearbeiten > Einstellungen > Allgemein. - <usetemplate ignoretext="Meine Alterseinstufung lässt nicht zu, dass ich Land kaufe" name="okcancelignore" notext="Schließen" yestext="Einstellung ändern"/> + Das Land, das Sie kaufen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und anschließend erneut versuchen, das Land zu kaufen. + <form name="form"> + <button name="OK" text="Einstellungen ändern"/> + <button name="Cancel" text="Abbrechen"/> + <ignore name="ignore" text="Das Land, das Sie kaufen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Zu viele Prims wurden ausgewählt. Bitte wählen Sie höchstens [MAX_PRIM_COUNT] Prims aus und versuchen Sie es erneut. @@ -1839,10 +1933,9 @@ Anzeige für [AMOUNT] L$ veröffentlichen? </form> </notification> <notification label="Alterseinstufung der Region ändern" name="RegionMaturityChange"> - Die Alterseinstufung dieser Region wurde aktualisiert. + Die Inhaltseinstufung dieser Region wurde geändert. Es kann eine Weile dauern, bis diese Änderung auf der Karte angezeigt wird. - -Um Regionen der Alterseinstufung „Adult" zu betreten, müssen Einwohner altersüberprüft sein. Dies kann entweder über die Alterverifizierung oder Zahlungsverifizierung geschehen. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Falsche Voice-Version" name="VoiceVersionMismatch"> Diese Version von [APP_NAME] ist mit der Voice-Chat-Funktion in dieser Region nicht kompatibel. Damit Voice-Chat funktioniert, müssen Sie [APP_NAME] aktualisieren. @@ -2132,14 +2225,11 @@ Von einer Webseite zu diesem Formular linken, um anderen leichten Zugang zu dies <usetemplate ignoretext="Die Kleidung, die während dem Bearbeiten meines Aussehens erstellt wird, sofort anziehen" name="okcancelignore" notext="Nein" yestext="Ja"/> </notification> <notification name="NotAgeVerified"> - Um auf Adult-Inhalte und –Bereiche in Second Life zuzugreifen, müssen Sie mindestens 18 Jahre alt sein. Bitte besuchen Sie die Altersüberprüfungsseite, um zu bestätigen, dass Sie mindestens 18 Jahre alt sind. -Hierzu wird Ihr Webbrowser geöffnet. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Ich habe mein Alter nicht verifizieren lassen" name="okcancelignore" notext="Abbrechen" yestext="Zur Altersüberprüfung"/> + Der Ort, den Sie besuchen möchten, ist nur für Bewohner zugänglich, die mindestens 18 Jahre alt sind. + <usetemplate ignoretext="Ich bin nicht alt genug, um beschränkte Bereiche zu besuchen." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Ort auf Einwohner beschränkt, die mindestens 18 Jahre alt sind. </notification> <notification name="Cannot enter parcel: no payment info on file"> Um diesen Bereich besuchen zu können, müssen Ihre Zahlungsinformationen gespeichert sein. Möchten Sie diese Einstellung auf der [SECOND_LIFE]-Webseite einrichten? @@ -2200,7 +2290,7 @@ Hierzu wird Ihr Webbrowser geöffnet. Terrain.raw heruntergeladen </notification> <notification name="GestureMissing"> - Hmm. Geste [NAME] fehlt in Datenbank. + Geste [NAME] fehlt in Datenbank. </notification> <notification name="UnableToLoadGesture"> Geste [NAME] konnte nicht geladen werden. @@ -2400,6 +2490,23 @@ Fliegen ist hier nicht möglich. <notification name="NoBuild"> In diesem Bereich ist das Bauen deaktiviert. Sie können keine Objekte bauen oder rezzen. </notification> + <notification name="PathfindingDirty"> + Diese Region weist ausstehende Pathfinding-Änderungen auf. Wenn Sie Baurechte besitzen, können Sie die Region durch Klicken auf die Schaltfläche „Region neu formen“ neu formen. + </notification> + <notification name="DynamicPathfindingDisabled"> + Dynamisches Pathfinding ist in dieser Region nicht aktiviert. Geskriptete Objekte, die Pathfinding-LSL-Aufrufe verwenden, funktionieren in dieser Region u. U. nicht wie erwartet. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Wenn Sie bestimmte Objekte in dieser Region ändern, verhalten sich andere bewegliche Objekte u. U. inkorrekt. Um dieses Problem zu beheben, klicken Sie auf die Schaltfläche „Region neu formen“. Um weitere Informationen zu erhalten, klicken Sie auf „Hilfe“. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Hilfe" ignoretext="Wenn Sie bestimmte Objekte in dieser Region ändern, verhalten sich andere bewegliche Objekte u. U. inkorrekt." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Fehler aufgetreten. Möglicherweise ist ein Netzwerk- oder Serverproblem aufgetreten oder Sie haben nicht die erforderlichen Baurechte. Dieses Problem lässt sich manchmal durch Ab- und Anmelden lösen. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Diese Parzelle verbirgt Avatare und Text-Chat vor einer anderen Parzelle. Sie können Einwohner außerhalb dieser Parzelle weder sehen noch von ihnen gesehen werden. Regulärer Text-Chat auf Kanal 0 ist ebenfalls blockiert. </notification> @@ -2418,9 +2525,7 @@ Hier funktionieren nur Skripts, die dem Landeigentümer gehören. Öffentliches Land kann nur in der Region in Besitz genommen werden, in der Sie sich befinden. </notification> <notification name="RegionTPAccessBlocked"> - Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. Sie müssen eventuell eine Altersüberprüfung vornehmen und/oder den aktuellsten Viewer installieren. - -Bitte besuchen Sie unsere Knowledgebase, um mehr Details über Zugang zu Regionen mit dieser Alterseinstufung zu erhalten. + Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ > „Einstellungen“ > „Allgemein“ ändern. </notification> <notification name="URBannedFromRegion"> Sie dürfen diese Region nicht betreten. @@ -2431,11 +2536,11 @@ Bitte besuchen Sie unsere Knowledgebase, um mehr Details über Zugang zu Regione <notification name="ImproperPaymentStatus"> Die für den Zutritt zu dieser Region erforderlichen Zahlungsinformationen liegen nicht vor. </notification> - <notification name="MustGetAgeRgion"> - Sie müssen altersüberprüft sein, um diese Region betreten zu können. + <notification name="MustGetAgeRegion"> + Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können. </notification> <notification name="MustGetAgeParcel"> - Sie müssen altersüberprüft sein, um diese Parzelle betreten zu können. + Sie müssen mindestens 18 Jahre alt sein, um diese Parzelle betreten zu können. </notification> <notification name="NoDestRegion"> Keine Zielregion gefunden. @@ -2535,14 +2640,35 @@ Versuchen Sie es in einigen Minuten erneut. </form> </notification> <notification name="TeleportOffered"> - [NAME_SLURL] hat Ihnen einen Teleport an seine/ihre Position angeboten: + [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +„[MESSAGE]“ +<icon>[MATURITY_ICON]</icon> – [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teleportieren"/> <button name="Cancel" text="Abbrechen"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten: + +„[MESSAGE]“ +<icon>[MATURITY_ICON]</icon> – [MATURITY_STR] + +Diese Region enthält [REGION_CONTENT_MATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGION_CONTENT_MATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und den Teleport fortsetzen oder Sie können den Teleport abbrechen. + <form name="form"> + <button name="Teleport" text="Ändern und fortfahren"/> + <button name="Cancel" text="Abbrechen"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten: + +„[MESSAGE]“ +<icon>[MATURITY_ICON]</icon> – [MATURITY_STR] + +Diese Region enthält jedoch Inhalte, die nur für Erwachsene zugänglich sind. + </notification> <notification name="TeleportOfferSent"> Ein Teleportangebot wurde an [TO_NAME] geschickt </notification> @@ -2947,6 +3073,10 @@ Sie haben eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME] ( [EXISTENCE] Sekunden am Leben) Sie haben lokal eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME] Sekunden aktualisiert. </notification> + <notification name="LivePreviewUnavailable"> + Wir können keine Vorschau dieser Textur anzeigen, da sie nicht kopier- und/oder übertragungsfähig ist. + <usetemplate ignoretext="Hinweis anzeigen, wenn bei nicht kopier- und/oder übertragungsfähigen Texturen keine Live-Vorschau möglich ist" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Möchten Sie dieses Gespräch wirklich verlassen ? <usetemplate ignoretext="Bestätigen, bevor ich den Anruf verlasse." name="okcancelignore" notext="Nein" yestext="Ja"/> @@ -3116,6 +3246,62 @@ Durch Ausblenden der Schaltfläche „Sprechen“ wird die Sprechfunktion deakti Durch diese Aktion werden alle Menüelemente und Schaltflächen ausgeblendet. Um sie wieder anzuzeigen, klicken Sie erneut auf [SHORTCUT]. <usetemplate ignoretext="Vor Ausblenden der UI bestätigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht gesetzt werden." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Einige der ausgewählten Linksets können nicht gesetzt werden, da die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können aufgrund von Berechtigungseinschränkungen nicht gesetzt werden." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können nicht gesetzt werden, da die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. Die Nutzungsarten dieser Linksets bleiben unverändert. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Einige der ausgewählten Linksets können nicht gesetzt werden, da die Berechtigungen eingeschränkt sind und die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet. + +Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt. + +Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. Die Nutzungsarten dieser Linksets bleiben unverändert. + +Möchten Sie fortfahren? + <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können nicht gesetzt werden, da die Berechtigungen für das Linkset eingeschränkt sind und die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + Das ausgewählte Objekt wirkt sich auf das Navmesh aus. Wenn Sie es in einen flexiblen Pfad ändern, wird es aus dem Navmesh entfernt. + <usetemplate ignoretext="Das ausgewählte Objekt wirkt sich auf das Navmesh aus. Wenn Sie es in einen flexiblen Pfad ändern, wird es aus dem Navmesh entfernt." name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Ihr Computer entspricht nicht den Hardwareanforderungen von [APP_NAME]. [APP_NAME] setzt eine OpenGL-Grafikkarte mit Multitextur-Unterstützung voraus. Falls Ihre Grafikkarte diese Funktion unterstützt, installieren Sie die neuesten Treiber sowie die aktuellen Service Packs und Patches für Ihr Betriebssystem. @@ -3152,4 +3338,12 @@ Zukünftige Aktualisierungen dieser Datei werden deaktiviert. Versuch, eine ungültige oder nicht lesbare Bilddatei ([FNAME]) hinzuzufügen, die nicht geöffnet oder decodiert werden konnte. Versuch abgebrochen. </notification> + <notification name="PathfindingReturnMultipleItems"> + Sie sind dabei, [NUM_ITEMS] Objekte zurückzugeben. Möchten Sie diesen Vorgang wirklich fortsetzen? + <usetemplate ignoretext="Möchten Sie wirklich mehrere Objekte zurückgeben?" name="okcancelignore" notext="Nein" yestext="Ja"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Sie sind dabei, [NUM_ITEMS] Objekte zu löschen. Möchten Sie diesen Vorgang wirklich fortsetzen? + <usetemplate ignoretext="Möchten Sie wirklich mehrere Objekte löschen?" name="okcancelignore" notext="Nein" yestext="Ja"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/de/panel_bottomtray.xml b/indra/newview/skins/default/xui/de/panel_bottomtray.xml deleted file mode 100644 index afe9836401..0000000000 --- a/indra/newview/skins/default/xui/de/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Schaltet Mikrofon ein/aus"/> - <string name="VoiceControlBtnToolTip" value="Voice-Chat-Steuerung anzeigen/ausblenden"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Sprechen" label_selected="Sprechen" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gesten" name="Gesture" tool_tip="Gesten anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Bewegen" name="movement_btn" tool_tip="Bewegungssteuerung anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Ansicht" name="camera_btn" tool_tip="Kamerasteuerung anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Foto machen"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Bauen" name="build_btn" tool_tip="Bauwerkzeuge ein-/ausblenden"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Suche" name="search_btn" tool_tip="Suche anzeigen/ausblenden"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Karte" name="world_map_btn" tool_tip="Karte ein-/ausblenden"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Minikarte" name="mini_map_btn" tool_tip="Minikarte ein-/ausblenden"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="IMs"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Benachrichtigungen"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_group_invite.xml b/indra/newview/skins/default/xui/de/panel_group_invite.xml index 5f323d80dd..c32d2fe4bf 100644 --- a/indra/newview/skins/default/xui/de/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/de/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Einige der ausgewählten Einwohner sind bereits Gruppenmitglieder und haben aus diesem Grund keine Einladung erhalten. </panel.string> + <panel.string name="invite_selection_too_large"> + Gruppeneinladungen nicht gesendet: zu viele Einwohner ausgewählt. Gruppeneinladungen sind auf 100 Einwohner pro Anfrage beschränkt. + </panel.string> <text name="help_text"> Sie können mehrere Einwohner in Ihre Gruppe einladen. Klicken Sie hierzu auf „Einwohnerliste öffnen“. </text> diff --git a/indra/newview/skins/default/xui/de/panel_login.xml b/indra/newview/skins/default/xui/de/panel_login.xml index 553bd3e2ff..8cc467185c 100644 --- a/indra/newview/skins/default/xui/de/panel_login.xml +++ b/indra/newview/skins/default/xui/de/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://de.secondlife.com/registration/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=de </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ANMELDEN + </text> <text name="username_text"> Benutzername: </text> @@ -15,17 +15,10 @@ <text name="password_text"> Kennwort: </text> - <check_box label="Kennwort merken" name="remember_check"/> - <button label="Anmelden" name="connect_btn"/> - <text name="mode_selection_text"> - Modus: - </text> - <combo_box name="mode_combo" tool_tip="Wählen Sie den gewünschten Modus aus. Basis: Second Life schnell und einfach erkunden und chatten. Erweitert: Zugriff auf zusätzliche Funktionen."> - <combo_box.item label="Basis" name="Basic"/> - <combo_box.item label="Erweitert" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> - Hier anfangen: + Hier starten: </text> <combo_box name="start_location_combo"> <combo_box.item label="Mein letzter Standort" name="MyLastLocation"/> @@ -33,16 +26,21 @@ <combo_box.item label="<Region eingeben>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Registrieren + <layout_panel name="links_login_panel"> + <text name="login_help"> + Brauchen Sie Hilfe beim Anmelden? </text> <text name="forgot_password_text"> Benutzernamen oder Kennwort vergessen? </text> - <text name="login_help"> - Sie brauchen Hilfe? + <button label="Anmelden" name="connect_btn"/> + <check_box label="Kennwort speichern" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + IHR KONTO ERSTELLEN </text> + <button label="Jetzt starten" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/de/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..44be6d67b1 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="Region neu formen" name="navmesh_btn" tool_tip="Klicken, um das Navmesh der Region neu zu formen."/> + <button label="Neuformen wird angefordert" name="navmesh_btn_sending" tool_tip="Anforderung zum Neuformen wird an den Server gesendet."/> + <button label="Region wird neu geformt" name="navmesh_btn_baking" tool_tip="Region wird neu geformt. Nach Abschluss des Vorgangs verschwindet diese Schaltfläche."/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml index 746a561e6c..c9ae350147 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="IM-Chats" name="EnableIMChatPopups" tool_tip="Markieren, um Popups zu sehen, wenn Instant Message eintrifft"/> <spinner label="Lebenszeit von Toasts für Chat in der Nähe:" name="nearby_toasts_lifetime"/> <spinner label="Ein-/Ausblenddauer von Toasts für Chat in der Nähe:" name="nearby_toasts_fadingtime"/> - <button label="Übersetzungseinstellungen für Chats" name="ok_btn"/> + <button label="Übersetzen..." name="ok_btn"/> + <button label="Automatisch ersetzen..." name="autoreplace_showgui"/> + <button label="Rechtschreibprüfung..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_region_debug.xml b/indra/newview/skins/default/xui/de/panel_region_debug.xml index d1b8f0d78a..a03a0b8b7b 100644 --- a/indra/newview/skins/default/xui/de/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/de/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" name="top_scripts_help"/> <button label="Region neu starten" name="restart_btn" tool_tip="2-Minuten-Countdown und Region neu starten"/> <button label="?" name="restart_help"/> - <button label="Neustart verzögern" name="cancel_restart_btn" tool_tip="Regionsneustart um eine Stunde verschieben"/> + <button label="Neustart abbrechen" name="cancel_restart_btn" tool_tip="Regionsneustart abbrechen"/> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_region_estate.xml b/indra/newview/skins/default/xui/de/panel_region_estate.xml index aecf6f62fc..b087451391 100644 --- a/indra/newview/skins/default/xui/de/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/de/panel_region_estate.xml @@ -19,7 +19,7 @@ Zugang nur Einwohnern gestatten, die: </text> <check_box label="Zahlungsinformationen hinterlegt haben" name="limit_payment" tool_tip="Um diesen Grundbesitz besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> - <check_box label="ihr Alter bestätigt haben" name="limit_age_verified" tool_tip="Um diesen Grundbesitz besuchen zu können, müssen Einwohner ihr Alter bestätigt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> + <check_box label="Sind mindestens 18 Jahre alt" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diesen Grundbesitz betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/> <check_box label="Voice-Chat erlauben" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <text name="abuse_email_text" width="222"> diff --git a/indra/newview/skins/default/xui/de/panel_region_texture.xml b/indra/newview/skins/default/xui/de/panel_region_texture.xml deleted file mode 100644 index 2f4904730b..0000000000 --- a/indra/newview/skins/default/xui/de/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Bodentexturen" name="Textures"> - <text name="region_text_lbl"> - Region: - </text> - <text name="region_text"> - unbekannt - </text> - <text name="detail_texture_text"> - Terraintexturen (erfordert 512x512, 24-Bit-.tga-Dateien) - </text> - <text name="height_text_lbl"> - 1 (niedrig) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Hoch) - </text> - <text name="height_text_lbl5"> - Texturhöhenbereich - </text> - <text name="height_text_lbl6"> - Nordwest - </text> - <text name="height_text_lbl7"> - Nordost - </text> - <text name="height_text_lbl8"> - Südwest - </text> - <text name="height_text_lbl9"> - Südost - </text> - <spinner label="Niedrig" label_width="40" name="height_start_spin_0"/> - <spinner label="Niedrig" label_width="40" name="height_start_spin_1"/> - <spinner label="Niedrig" label_width="40" name="height_start_spin_2"/> - <spinner label="Niedrig" label_width="40" name="height_start_spin_3"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_0"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_1"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_2"/> - <spinner label="Hoch" label_width="40" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Diese Werte geben den Mischungsgrad für die obigen Texturen an. - </text> - <text name="height_text_lbl11"> - In Metern gemessen. Der NIEDRIG-Wert ist die MAXIMALE Höhe der Textur #1, der HÖCHST-Wert ist die MINDEST-Höhe von Textur #4. - </text> - <text name="height_text_lbl12"> - und der OBERE WERT die MINIMALE Höhe von Textur 4. - </text> - <button label="Übernehmen" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_side_tray.xml b/indra/newview/skins/default/xui/de/panel_side_tray.xml deleted file mode 100644 index 3c81636fa0..0000000000 --- a/indra/newview/skins/default/xui/de/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Seitenleiste auf-/zuklappen." name="sidebar_openclose" tab_title="Seitenleiste auf-/zuklappen"/> - <sidetray_tab description="Startseite." name="sidebar_home" tab_title="Startseite"> - <panel label="Startseite" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Ihr öffentliches Profil und Auswahl bearbeiten." name="sidebar_me" tab_title="Mein Profil"> - <panel_container name="panel_container"> - <panel label="Ich" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Freunde, Kontakte und Leute in Ihrer Nähe finden." name="sidebar_people" tab_title="Leute"> - <panel_container name="panel_container"> - <panel label="Gruppenprofil" name="panel_group_info_sidetray"/> - <panel label="Ignorierte Einwohner & Objekte" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Hier finden Sie neue Orte und Orte, die Sie bereits besucht haben." label="Orte" name="sidebar_places" tab_title="Orte"> - <panel label="Orte" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Inventar durchsuchen." name="sidebar_inventory" tab_title="Mein Inventar"> - <panel label="Inventar bearbeiten" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Ändern Sie Ihr Aussehen und Ihren aktuellen Look." name="sidebar_appearance" tab_title="Mein Aussehen"> - <panel label="Aussehen bearbeiten" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml new file mode 100644 index 0000000000..3d43200e48 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater" width="240"> + <button left="217" name="prefs_btn"/> + <slider label="Master" label_width="80" name="System Volume" width="180"/> + <slider label="Schaltflächen" label_width="80" name="UI Volume" width="180"/> + <slider label="Umgebung" label_width="80" name="Wind Volume" width="180"/> + <slider label="Sounds" label_width="80" name="SFX Volume" width="180"/> + <check_box name="gesture_audio_play_btn" tool_tip="Sounds von Gesten aktivieren"/> + <slider label="Musik" label_width="80" name="Music Volume" width="180"/> + <check_box name="enable_music" tool_tip="Streaming-Musik aktivieren"/> + <slider label="Medien" label_width="80" name="Media Volume" width="180"/> + <check_box name="enable_media" tool_tip="Streaming-Medien aktivieren"/> + <slider label="Voice" label_width="80" name="Voice Volume" width="180"/> + <check_box name="enable_voice_check" tool_tip="Voice-Chat aktivieren"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml index 18241dea32..1b67eaf03b 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (unbekannt) </panel.string> + <panel.string name="unknown_multiple"> + (unbekannt/mehrere) + </panel.string> <panel.string name="public"> (öffentlich) </panel.string> diff --git a/indra/newview/skins/default/xui/de/sidepanel_task_info.xml b/indra/newview/skins/default/xui/de/sidepanel_task_info.xml index 7b46ee7c9b..4c8d77d336 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Sie können diese Objekte nicht bearbeiten. </panel.string> + <panel.string name="text modify info 5"> + Dieses Objekt kann nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> + <panel.string name="text modify info 6"> + Diese Objekte können nicht über eine Regionsgrenze hinweg geändert werden + </panel.string> <panel.string name="text modify warning"> Diese Objekt verfügt über verknüpfte Teile </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Preis: L$" name="Edit Cost"/> <check_box label="In Suche anzeigen" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/> + <text name="pathfinding_attributes_label"> + Pathfinding-Attribute: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 668a7b35bf..79cb73ecf9 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -137,7 +137,7 @@ Beenden </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=de-DE + http://join.secondlife.com/index.php?lang=de-DE&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Mit dem von Ihnen verwendeten Viewer ist der Zugriff auf Second Life nicht mehr möglich. Laden Sie von den folgenden Seite einen neuen Viewer herunter: @@ -1006,6 +1006,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="script_files"> Skripts </string> + <string name="dictionary_files"> + Wörterbücher + </string> <string name="AvatarSetNotAway"> Nicht abwesend </string> @@ -1411,6 +1414,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="InvFolder favorite"> Meine Favoriten </string> + <string name="InvFolder Favorites"> + Meine Favoriten + </string> + <string name="InvFolder favorites"> + Meine Favoriten + </string> <string name="InvFolder Current Outfit"> Aktuelles Outfit </string> @@ -1426,6 +1435,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. <string name="InvFolder Meshes"> Netze </string> + <string name="InvFolder Received Items"> + Erhaltene Artikel + </string> + <string name="InvFolder Merchant Outbox"> + Händler-Outbox + </string> <string name="InvFolder Friends"> Freunde </string> @@ -3864,6 +3879,12 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="LocationCtrlSeeAVsTooltip"> Avatare sichtbar; Chat außerhalb dieser Parzelle gestattet </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Bewegliche Objekte verhalten sich in dieser Region u. U. erst dann korrekt, wenn die Region neu geformt wird. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Dynamisches Pathfinding ist in dieser Region nicht aktiviert. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] Aktualisierung </string> @@ -5006,6 +5027,21 @@ Setzen Sie den Editorpfad in Anführungszeichen <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Keine + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Wirkt sich auf Navmesh aus + </string> + <string name="Pathfinding_Object_Attr_Character"> + Figur + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (mehrere) + </string> <string name="snapshot_quality_very_low"> Sehr niedrig </string> @@ -5021,4 +5057,10 @@ Setzen Sie den Editorpfad in Anführungszeichen <string name="snapshot_quality_very_high"> Sehr hoch </string> + <string name="TeleportMaturityExceeded"> + Der Einwohner kann diese Region nicht besuchen. + </string> + <string name="UserDictionary"> + [Benutzer] + </string> </strings> diff --git a/indra/newview/skins/default/xui/de/teleport_strings.xml b/indra/newview/skins/default/xui/de/teleport_strings.xml index 9cf381bacc..8062633df6 100644 --- a/indra/newview/skins/default/xui/de/teleport_strings.xml +++ b/indra/newview/skins/default/xui/de/teleport_strings.xml @@ -46,6 +46,9 @@ Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in e <message name="no_inventory_host"> Das Inventarsystem ist zurzeit nicht verfügbar. </message> + <message name="MustGetAgeRegion"> + Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -81,5 +84,8 @@ Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in e <message name="requesting"> Teleport wird initialisiert... </message> + <message name="pending"> + Anstehender Teleport... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml index f3f8d4ddca..1ea256b8b3 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_minimize="false" - height="550" + height="600" layout="topleft" name="TexFetchDebugger" help_topic="texfetchdebugger" @@ -195,10 +195,34 @@ height="25" layout="topleft" left_delta="0" + name="total_time_refetch_all_cache_label" + top_delta="25" + width="540"> + 16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" name="total_time_refetch_vis_http_label" top_delta="25" width="540"> - 16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + 17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + </text> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="total_time_refetch_all_http_label" + top_delta="25" + width="540"> + 18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels </text> <spinner decimal_digits="2" @@ -206,7 +230,7 @@ height="20" increment="0.01" initial_value="1.0" - label="17, Ratio of Texel/Pixel:" + label="19, Ratio of Texel/Pixel:" label_width="130" layout="topleft" left_delta="0" @@ -218,14 +242,53 @@ <spinner.commit_callback function="TexFetchDebugger.ChangeTexelPixelRatio" /> </spinner> + <text + type="string" + length="1" + follows="left|top" + height="25" + layout="topleft" + left_delta="0" + name="texture_source_label" + top_delta="30" + width="110"> + 20, Texture Source: + </text> + <radio_group + control_name="TextureFetchSource" + follows="top|left" + draw_border="false" + height="25" + layout="topleft" + left_pad="0" + name="texture_source" + top_delta="0" + width="264"> + <radio_item + height="16" + label="Cache + HTTP" + layout="topleft" + left="3" + name="0" + top="0" + width="100" /> + <radio_item + height="16" + label="HTTP Only" + layout="topleft" + left_delta="100" + name="1" + top_delta="0" + width="200" /> + </radio_group> <button follows="left|top" height="20" label="Start" layout="topleft" - left_delta="0" + left="10" name="start_btn" - top_delta="30" + top_delta="20" width="70"> <button.commit_callback function="TexFetchDebugger.Start" /> @@ -261,7 +324,7 @@ layout="topleft" left="10" name="cacheread_btn" - top_delta="30" + top_delta="20" width="80"> <button.commit_callback function="TexFetchDebugger.CacheRead" /> @@ -321,7 +384,7 @@ layout="topleft" left="10" name="refetchviscache_btn" - top_delta="30" + top_delta="20" width="120"> <button.commit_callback function="TexFetchDebugger.RefetchVisCache" /> @@ -329,6 +392,18 @@ <button follows="left|top" height="20" + label="Refetch All Cache" + layout="topleft" + left_pad="7" + name="refetchallcache_btn" + top_delta="0" + width="120"> + <button.commit_callback + function="TexFetchDebugger.RefetchAllCache" /> + </button> + <button + follows="left|top" + height="20" label="Refetch Vis HTTP" layout="topleft" left_pad="7" @@ -338,4 +413,16 @@ <button.commit_callback function="TexFetchDebugger.RefetchVisHTTP" /> </button> + <button + follows="left|top" + height="20" + label="Refetch All HTTP" + layout="topleft" + left_pad="7" + name="refetchallhttp_btn" + top_delta="0" + width="120"> + <button.commit_callback + function="TexFetchDebugger.RefetchAllHTTP" /> + </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml index 4dfdcd15c7..0b71177345 100644 --- a/indra/newview/skins/default/xui/en/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_resize="true" - height="350" + height="372" layout="topleft" min_height="300" min_width="450" @@ -23,10 +23,6 @@ Time </floater.string> <floater.string - name="scripts_mono_time_label"> - Mono Time - </floater.string> - <floater.string name="top_colliders_title"> Top Colliders </floater.string> @@ -68,31 +64,35 @@ <scroll_list.columns label="Score" name="score" - width="55" /> + width="45" /> <scroll_list.columns label="Name" name="name" - width="140" /> + width="130" /> <scroll_list.columns label="Owner" name="owner" - width="105" /> + width="100" /> <scroll_list.columns label="Location" name="location" - width="130" /> + width="120" /> + <scroll_list.columns + label="Parcel" + name="parcel" + width="120" /> <scroll_list.columns label="Time" name="time" - width="150" /> - <scroll_list.columns - label="Mono Time" - name="mono_time" - width="100" /> + width="130" /> <scroll_list.columns label="URLs" name="URLs" - width="100" /> + width="40" /> + <scroll_list.columns + label="Memory (KB)" + name="memory" + width="40" /> <scroll_list.commit_callback function="TopObjects.CommitObjectsList" /> </scroll_list> @@ -193,6 +193,38 @@ <button.commit_callback function="TopObjects.GetByOwnerName" /> </button> + <text + type="string" + length="1" + follows="left|bottom" + height="20" + layout="topleft" + left="10" + top_pad="5" + name="parcel_name_text" + width="107"> + Parcel: + </text> + <line_editor + follows="left|bottom|right" + height="20" + layout="topleft" + left_pad="3" + name="parcel_name_editor" + top_delta="-3" + width="568" /> + <button + follows="bottom|right" + height="23" + label="Filter" + layout="topleft" + left_pad="5" + name="filter_parcel_btn" + top_delta="0" + width="100"> + <button.commit_callback + function="TopObjects.GetByParcelName" /> + </button> <button follows="bottom|right" height="22" diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml index 63e154697b..2c420aa1e3 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml @@ -57,7 +57,7 @@ layout="topleft" name="take_copy"> <menu_item_call.on_click - function="InspectObject.TakeFreeCopy"/> + function="Tools.TakeCopy"/> <menu_item_call.on_visible function="Tools.EnableTakeCopy"/> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index b13bf5b508..13dc0b941a 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -537,6 +537,14 @@ layout="topleft" name="Landmark Separator" /> <menu_item_call + label="Copy SLurl" + layout="topleft" + name="url_copy"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="copy_slurl" /> + </menu_item_call> + <menu_item_call label="About Landmark" layout="topleft" name="About Landmark"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c785cee856..8e6de6ed4f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -896,8 +896,7 @@ You need an account to enter [SECOND_LIFE]. Would you like to create one now? option="0" name="url" target = "_external"> - - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" @@ -2929,12 +2928,11 @@ You can use [SECOND_LIFE] normally and other people will see you correctly. [APP_NAME] installation is complete. If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in. -Return to [http://join.secondlife.com secondlife.com] to create a new account? <tag>confirm</tag> <usetemplate name="okcancelbuttons" notext="Continue" - yestext="New Account..."/> + yestext="Create Account..."/> </notification> <notification diff --git a/indra/newview/skins/default/xui/en/panel_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml index cd834b61ce..124c0596c3 100644 --- a/indra/newview/skins/default/xui/en/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml @@ -19,6 +19,10 @@ name="already_in_group"> Some Residents you chose are already in the group, and so were not sent an invitation. </panel.string> + <panel.string + name="invite_selection_too_large"> + Group Invitations not sent: too many Residents selected. Group Invitations are limited to 100 per request. + </panel.string> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 44702c828f..134ca75018 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -7,11 +7,7 @@ name="panel_login" focus_root="true" top="600" - width="996"> - <panel.string - name="create_account_url"> - http://join.secondlife.com/ - </panel.string> + width="1130"> <string name="reg_in_client_url" translate="false"> http://secondlife.eniac15.lindenlab.com/reg-in-client/ </string> @@ -32,59 +28,82 @@ start_url="" top="0" height="600" - width="980"/> + width="996"/> <layout_stack + animate="false" + clip="false" follows="left|bottom|right" name="login_widgets" layout="topleft" orientation="horizontal" top="519" - width="996" + width="1130" height="80"> <layout_panel auto_resize="false" follows="left|bottom" name="login" layout="topleft" - width="705" - min_width="705" + width="310" + min_width="310" height="80"> <text follows="left|bottom" + font="SansSerif" + font.style="BOLD" + font.size="Large" + height="16" + name="log_in_text" + top="8" + left="15" + width="150"> + LOG IN + </text> + <text + follows="left|bottom" font="SansSerifSmall" height="16" name="username_text" - top="20" - left="20" + top="35" + left="15" width="150"> Username: </text> + <!-- STEAM-14: Turn off commit_on_focus_lost so if user presses Enter + with focus in this combo_box, we can use commit action to initiate + login --> <combo_box allow_text_entry="true" follows="left|bottom" height="22" left_delta="0" max_chars="128" + commit_on_focus_lost="false" combo_editor.prevalidate_callback="ascii" tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" top_pad="0" name="username_combo" width="178"> +<!-- empirically, displayed width is 150 anyway?!? --> <combo_box.combo_button visible ="false"/> <combo_box.drop_down_button visible ="false"/> </combo_box> +<!-- left="175" based on actual "username_combo" width of 150 vs. 178 --> <text follows="left|bottom" font="SansSerifSmall" - height="15" - left_pad="-19" + height="16" name="password_text" - top="20" + top="35" + left="175" width="150"> Password: </text> + <!-- STEAM-14: Turn off commit_on_focus_lost so if user presses Enter + with focus in this line_editor, we can use commit action to + initiate login --> <line_editor follows="left|bottom" height="22" @@ -92,36 +111,25 @@ name="password_edit" is_password="true" select_on_focus="true" + commit_on_focus_lost="false" top_pad="0" width="135" /> - <check_box - control_name="RememberPassword" - follows="left|bottom" - font="SansSerifSmall" - height="16" - label="Remember password" - top_pad="3" - name="remember_check" - width="135" /> - <button - follows="left|bottom" - height="23" - image_unselected="PushButton_On" - image_selected="PushButton_On_Selected" - label="Log In" - label_color="White" - layout="topleft" - left_pad="10" - name="connect_btn" - top="35" - width="90" /> + </layout_panel> + <layout_panel + auto_resize="false" + follows="left|bottom" + name="start_location_panel" + layout="topleft" + width="175" + min_width="175" + height="80"> <text follows="left|bottom" font="SansSerifSmall" - height="15" - left_pad="8" + height="16" + left="10" name="start_location_text" - top="20" + top="35" width="130"> Start at: </text> @@ -129,7 +137,7 @@ allow_text_entry="true" control_name="NextLoginLocation" follows="left|bottom" - height="23" + height="22" max_chars="128" top_pad="0" name="start_location_combo" @@ -146,60 +154,112 @@ label="<Type region name>" name="Typeregionname" value="" /> </combo_box> + </layout_panel> + <layout_panel + auto_resize="false" + follows="left|bottom" + name="grid_panel" + layout="topleft" + width="145" + height="80" + visible="false"> <combo_box allow_text_entry="false" font="SansSerifSmall" follows="left|right|bottom" height="23" max_chars="256" + left="10" + top="51" layout="topleft" top_pad="2" name="server_combo" - width="250" - visible="false" /> + width="135" /> </layout_panel> <layout_panel - tab_stop="false" - follows="right|bottom" - name="links" - width="205" - min_width="205" + auto_resize="false" + follows="left|bottom" + name="links_login_panel" + layout="topleft" + width="290" height="80"> <text - follows="right|bottom" + follows="left|bottom" font="SansSerifSmall" text_color="EmphasisColor" - halign="right" + left="10" height="16" - top="12" - right="-10" - name="create_new_account_text" - width="200"> - Sign up + name="login_help" + top="19" + width="280"> + Need help logging in? </text> <text - follows="right|bottom" + follows="left|bottom" font="SansSerifSmall" text_color="EmphasisColor" - halign="right" height="16" name="forgot_password_text" - top_pad="12" - right="-10" - width="200"> + top="35" + width="280"> Forgot your username or password? </text> + <button + follows="left|bottom" + top_pad="0" + height="23" + image_unselected="PushButton_On" + image_selected="PushButton_On_Selected" + label="Log In" + label_color="White" + layout="topleft" + name="connect_btn" + width="90" /> + <check_box + control_name="RememberPassword" + follows="left|bottom" + font="SansSerifSmall" + left="110" + top="56" + height="16" + label="Remember password" + top_pad="3" + name="remember_check" + width="145" /> + </layout_panel> + <layout_panel + tab_stop="false" + follows="right|bottom" + name="links" + width="210" + min_width="100" + height="80"> <text follows="right|bottom" - font="SansSerifSmall" - text_color="EmphasisColor" + font="SansSerif" + font.style="BOLD" + font.size="Large" halign="right" height="16" - name="login_help" - top_pad="2" - right="-10" + name="create_account_text" + top="8" + right="-15" width="200"> - Need help logging in? </text> + CREATE YOUR ACCOUNT + </text> + <button + follows="right|bottom" + top="35" + right="-15" + height="23" + image_unselected="PushButton_On" + image_selected="PushButton_On_Selected" + label="Start now" + label_color="White" + layout="topleft" + left_pad="10" + name="create_new_account_btn" + width="90" /> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index f7666bdc4c..849f3ef73d 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -55,30 +55,57 @@ name="LowGraphicsDivet" top_delta="-2" width="2" /> + <icon + color="0.12 0.12 0.12 1" + height="14" + image_name="Rounded_Square" + layout="topleft" + left_pad="41" + name="LowMidraphicsDivet" + top_delta="-2" + width="2" /> <icon color="0.12 0.12 0.12 1" height="14" image_name="Rounded_Square" layout="topleft" - left_pad="83" + left_pad="41" name="MidGraphicsDivet" top_delta="0" width="2" /> + <icon + color="0.12 0.12 0.12 1" + height="14" + image_name="Rounded_Square" + layout="topleft" + left_pad="41" + name="MidHighGraphicsDivet" + top_delta="0" + width="2" /> <icon color="0.12 0.12 0.12 1" height="14" image_name="Rounded_Square" layout="topleft" - left_pad="85" + left_pad="41" name="HighGraphicsDivet" top_delta="0" width="2" /> + <icon + color="0.12 0.12 0.12 1" + height="14" + image_name="Rounded_Square" + layout="topleft" + left_pad="41" + name="HighUltraGraphicsDivet" + top_delta="0" + width="2" /> <icon color="0.12 0.12 0.12 1" height="14" image_name="Rounded_Square" layout="topleft" - left_pad="83" + left_pad="41" name="UltraGraphicsDivet" top_delta="0" width="2" /> @@ -91,7 +118,7 @@ initial_value="0" layout="topleft" left="120" - max_val="3" + max_val="6" name="QualityPerformanceSelection" show_text="false" top_delta="-2" @@ -120,12 +147,12 @@ height="12" layout="topleft" left_delta="87" - name="ShadersPrefText2" + name="ShadersPrefText3" top_delta="0" width="80"> Mid </text> - <text + <text type="string" length="1" follows="left|top" @@ -136,8 +163,8 @@ name="ShadersPrefText3" top_delta="0" width="80"> - High - </text> + High + </text> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml index 4550603134..81b2281adb 100644 --- a/indra/newview/skins/default/xui/en/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml @@ -194,11 +194,11 @@ <button follows="left|top" height="20" - label="Delay Restart" + label="Cancel Restart" layout="topleft" left_pad="155" name="cancel_restart_btn" - tool_tip="Delay region restart by one hour" + tool_tip="Cancel region restart" top_delta="0" width="150" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 3aa34439f1..dd2a0c6627 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -129,6 +129,5 @@ left_pad="5" top="2" name="volume_btn" - tool_tip="Global Volume Control" width="16" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml index 7b22b2cce1..6adede0362 100644 --- a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml +++ b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml @@ -8,41 +8,289 @@ border="false" chrome="true" follows="bottom" - height="150" + height="155" layout="topleft" name="volumepulldown_floater" - width="32"> - <slider - control_name="AudioLevelMaster" - follows="left|top" - left="0" - top="1" - orientation="vertical" - height="120" - increment="0.05" - initial_value="0.5" - layout="topleft" - name="mastervolume" - show_text="false" - slider_label.halign="right" - top_pad="2" - volume="true"> - <slider.commit_callback - function="Vol.setControlFalse" - parameter="MuteAudio" /> - </slider> - <button - left="10" - top_pad="9" - width="12" - height="12" - follows="top|left" - name="prefs_btn" - image_unselected="Icon_Gear_Foreground" - image_disabled="Icon_Gear_Background" - image_pressed="Icon_Gear_Press" - scale_image="false"> - <button.commit_callback - function="Vol.GoAudioPrefs" /> - </button> + width="225"> + <slider + control_name="AudioLevelMaster" + follows="top|left" + font.style="BOLD" + height="15" + increment="0.025" + initial_value="0.5" + label="Master" + label_width="60" + left="10" + width="160" + layout="topleft" + name="System Volume" + show_text="false" + top="10" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteAudio" /> + </slider> + <button + control_name="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <slider + control_name="AudioLevelUI" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Buttons" + label_width="60" + left="10" + width="160" + layout="topleft" + name="UI Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteUI" /> + </slider> + <button + control_name="MuteUI" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <slider + control_name="AudioLevelAmbient" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Ambient" + label_width="60" + left="10" + width="160" + layout="topleft" + name="Wind Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteAmbient" /> + </slider> + <button + control_name="MuteAmbient" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <slider + control_name="AudioLevelSFX" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Sounds" + label_width="60" + left="10" + width="160" + layout="topleft" + name="SFX Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteSounds" /> + </slider> + <button + control_name="MuteSounds" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16"> + <button.commit_callback + function="Pref.SetSounds"/> + </button> + <check_box + name="gesture_audio_play_btn" + control_name="EnableGestureSounds" + disabled_control="MuteAudio" + height="16" + layout="topleft" + left_pad="5" + tool_tip="Enable sounds from gestures" + top_delta="2" + width="350"/> + <slider + control_name="AudioLevelMusic" + disabled_control="MuteAudio" + follows="left|top" + height="15" + increment="0.025" + initial_value="0.5" + label="Music" + label_width="60" + left="10" + width="160" + layout="topleft" + name="Music Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteMusic" /> + </slider> + <button + control_name="MuteMusic" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <check_box + control_name="AudioStreamingMusic" + height="16" + tool_tip="Enable Streaming Music" + layout="topleft" + left_pad="5" + name="enable_music" + top_delta="2" + width="350"> + <check_box.commit_callback + function="Pref.updateMediaAutoPlayCheckbox"/> + </check_box> + <slider + control_name="AudioLevelMedia" + disabled_control="MuteAudio" + follows="left|top" + height="16" + increment="0.025" + initial_value="0.5" + label="Media" + label_width="60" + left="10" + width="160" + layout="topleft" + name="Media Volume" + show_text="false" + top_pad="4" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteMedia" /> + </slider> + <button + control_name="MuteMedia" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <check_box + label_text.halign="left" + follows="left|top" + height="16" + control_name ="AudioStreamingMedia" + tool_tip="Enable Streaming Media" + layout="topleft" + top_delta="2" + left_pad="5" + name="enable_media" + width="110"> + <check_box.commit_callback + function="Pref.updateMediaAutoPlayCheckbox"/> + </check_box> + <slider + control_name="AudioLevelVoice" + disabled_control="MuteAudio" + follows="left|top" + height="16" + increment="0.025" + initial_value="0.5" + label="Voice" + label_width="60" + left="10" + width="160" + layout="topleft" + top_pad="4" + name="Voice Volume" + show_text="false" + volume="true"> + <slider.commit_callback + function="Pref.setControlFalse" + parameter="MuteVoice" /> + </slider> + <button + control_name="MuteVoice" + disabled_control="MuteAudio" + follows="top|left" + height="16" + image_selected="AudioMute_Off" + image_unselected="Audio_Off" + is_toggle="true" + layout="topleft" + left_pad="5" + name="mute_audio" + tab_stop="false" + width="16" /> + <check_box + label_text.halign="left" + follows="left|top" + height="16" + control_name ="EnableVoiceChat" + disabled_control="CmdLineDisableVoice" + tool_tip="Enable Voice Chat" + layout="topleft" + top_delta="2" + left_pad="5" + name="enable_voice_check" + width="110"/> </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index d5186e4c1b..2157a05bbf 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -59,7 +59,7 @@ <string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string> <string name="LoginFailed">Login failed.</string> <string name="Quit">Quit</string> - <string name="create_account_url">http://join.secondlife.com/</string> + <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> <string name="LoginFailedViewerNotPermitted"> The viewer you are using can no longer access Second Life. Please visit the following page to download a new viewer: @@ -2272,11 +2272,15 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale <!-- historically default name of the Favorites folder can start from either "f" or "F" letter. We should localize both of them with the same value --> <string name="InvFolder favorite">My Favorites</string> + <string name="InvFolder Favorites">My Favorites</string> + <string name="InvFolder favorites">My Favorites</string> <string name="InvFolder Current Outfit">Current Outfit</string> <string name="InvFolder Initial Outfits">Initial Outfits</string> <string name="InvFolder My Outfits">My Outfits</string> <string name="InvFolder Accessories">Accessories</string> <string name="InvFolder Meshes">Meshes</string> + <string name="InvFolder Received Items">Received Items</string> + <string name="InvFolder Merchant Outbox">Merchant Outbox</string> <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694--> <string name="InvFolder Friends">Friends</string> diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index 307b61133f..3696c7e12c 100644 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -66,27 +66,26 @@ Versión del servidor de voz: [VOICE_VERSION] </panel> <panel label="Licencias" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion - APR Copyright (C) 2000-2004 The Apache Software Foundation - Collada DOM Copyright 2005 Sony Computer Entertainment Inc. - cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. - FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). + FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. - ogg/vorbis Copyright (C) 2001, Xiphophorus - OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. - PCRE Copyright (c) 1997-2008 University of Cambridge + ogg/vorbis Copyright (C) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. - zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. - google-perftools Copyright (c) 2005, Google Inc. + zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. El visor de Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (y sus licenciadores). Reservados todos los derechos. Vea los detalles en www.havok.com. 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 fd54d74af2..f8c40d798a 100644 --- a/indra/newview/skins/default/xui/es/floater_about_land.xml +++ b/indra/newview/skins/default/xui/es/floater_about_land.xml @@ -465,7 +465,7 @@ los media: Permitir únicamente el acceso a los Residentes que: </text> <check_box label="Han aportado información de pago [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Para poder acceder a esta parcela los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/> - <check_box label="Han verificado su edad [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Para poder acceder a esta parcela los Residentes deben haber verificado su edad. Para más información, ver [SUPPORT_SITE]."/> + <check_box label="Son mayores de 18 años [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Para poder acceder a esta parcela los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/> <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"> diff --git a/indra/newview/skins/default/xui/es/floater_animation_preview.xml b/indra/newview/skins/default/xui/es/floater_animation_preview.xml deleted file mode 100644 index d57405f7e5..0000000000 --- a/indra/newview/skins/default/xui/es/floater_animation_preview.xml +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> - <floater.string name="failed_to_initialize"> - Fallo al iniciar el movimiento - </floater.string> - <floater.string name="anim_too_long"> - El archivo de la animación dura [LENGTH] segundos. - -La duración máxima de una animación es de [MAX_LENGTH] segundos. - </floater.string> - <floater.string name="failed_file_read"> - No se ha podido leer el archivo de la animación. - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - OK - </floater.string> - <floater.string name="E_ST_EOF"> - Fin prematuro del archivo. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - No se puede leer la definición de la restricción. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - No se puede abrir el archivo BVH. - </floater.string> - <floater.string name="E_ST_NO_HIER"> - 'HIERARCHY header' inválido. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - No se pueden encontrar 'ROOT' o 'JOINT'. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - No se puede obtener el nombre 'JOINT'. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - No se puede encontrar 'OFFSET'. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - No se puede encontrar 'CHANNELS'. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - No se puede conseguir el orden de la rotación. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - No se puede encontrar el eje de rotación. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - No se puede encontrar 'MOTION'. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - No se puede conseguir el número de frames. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - No se puede conseguir el tiempo del frame. - </floater.string> - <floater.string name="E_ST_NO_POS"> - No se pueden conseguir los valores de la posición. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - No se pueden conseguir los valores de la rotación. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - No se puede abrir el archivo de traducción. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - No se puede leer el encabezamiento de la traducción. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - No se puede leer la traducción de los nombres. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - No se puede leer la traducción de los valores ignorados. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - No se puede leer el valor relativo de la traducción. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - No se puede leer la traducción del valor 'outname' - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - No se puede leer la matriz de traducciones. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - No se puede conseguir el nombre 'mergechild'. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - No se puede conseguir el nombre 'mergeparent'. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - No se puede obtener el valor prioritario. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - No se puede conseguir el valor del bucle. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - No se pueden conseguir los valores 'easeIn'. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - No se pueden conseguir los valores 'easeOut'. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - No se puede conseguir el valor de 'hand morph'. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - No se puede leer el nombre del gesto. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Nombre incorrecto de 'root joint', usa "hip". - </floater.string> - <text name="name_label"> - Nombre: - </text> - <text name="description_label"> - Descripción: - </text> - <spinner label="Prioridad:" name="priority" tool_tip="Controla qué otras animaciones pueden ser anuladas por ésta"/> - <check_box label="Bucle:" name="loop_check" tool_tip="Hace esta animación en bucle"/> - <spinner label="Empieza(%)" name="loop_in_point" tool_tip="Indica el punto en el que la animación vuelve a empezar"/> - <spinner label="Acaba(%)" name="loop_out_point" tool_tip="Indica el punto en el que la animación acaba el bucle"/> - <text name="hand_label"> - Posición de las manos - </text> - <combo_box name="hand_pose_combo" tool_tip="Controla qué hacen las manos durante la animación"> - <combo_box.item label="Extendidas" name="Spread"/> - <combo_box.item label="Relajadas" name="Relaxed"/> - <combo_box.item label="Ambas señalan" name="PointBoth"/> - <combo_box.item label="Puño" name="Fist"/> - <combo_box.item label="La izq. relajada" name="RelaxedLeft"/> - <combo_box.item label="La izq. señala" name="PointLeft"/> - <combo_box.item label="Puño izq." name="FistLeft"/> - <combo_box.item label="La der. relajada" name="RelaxedRight"/> - <combo_box.item label="La der. señala" name="PointRight"/> - <combo_box.item label="Puño der." name="FistRight"/> - <combo_box.item label="La derecha saluda" name="SaluteRight"/> - <combo_box.item label="Escribiendo" name="Typing"/> - <combo_box.item label="'Paz' en la der." name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Expresión - </text> - <combo_box name="emote_combo" tool_tip="Controla qué hace la cara durante la animación"> - <item label="(ninguno)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Con miedo" name="Afraid" value="Miedo"/> - <item label="Enfado" name="Angry" value="Enfado"/> - <item label="Gran sonrisa" name="BigSmile" value="Gran sonrisa"/> - <item label="Aburrimiento" name="Bored" value="Aburrimiento"/> - <item label="Llorar" name="Cry" value="Lloro"/> - <item label="Desdén" name="Disdain" value="Desdén"/> - <item label="Avergonzarse" name="Embarrassed" value="Vergüenza"/> - <item label="Fruncir el ceño" name="Frown" value="Fruncir el ceño"/> - <item label="Beso" name="Kiss" value="Beso"/> - <item label="Reír" name="Laugh" value="Risa"/> - <item label="Sacar la lengua" name="Plllppt" value="Sacar la lengua"/> - <item label="Rechazo" name="Repulsed" value="Rechazo"/> - <item label="Triste" name="Sad" value="Tristeza"/> - <item label="Encogerse de hombros" name="Shrug" value="Encogerse de hombros"/> - <item label="Sonrisa" name="Smile" value="Sonrisa"/> - <item label="Sorpresa" name="Surprise" value="Sorpresa"/> - <item label="Guiño" name="Wink" value="Guiño"/> - <item label="Preocupación" name="Worry" value="Preocupación"/> - </combo_box> - <text name="preview_label"> - Vista previa mientras - </text> - <combo_box name="preview_base_anim" tool_tip="Compruebe cómo se comporta su animación a la vez que el avatar realiza acciones comunes."> - <item label="De pie" name="Standing" value="De pie"/> - <item label="Caminando" name="Walking" value="Caminando"/> - <item label="Sentado/a" name="Sitting" value="Sentado"/> - <item label="Volando" name="Flying" value="Volando"/> - </combo_box> - <spinner label="Combinar (sec)" name="ease_in_time" tool_tip="Tiempo (en segundos) en el que se combinan las animaciones"/> - <spinner label="Dejar de combinar (sec)" name="ease_out_time" tool_tip="Tiempo (en segundos) en el que dejan de combinarse las animaciones"/> - <button bottom_delta="-32" name="play_btn" tool_tip="Ejecutar tu animación"/> - <button name="pause_btn" tool_tip="Pausar tu animación"/> - <button label="" name="stop_btn" tool_tip="Parar la repetición de la animación"/> - <slider label="" name="playback_slider"/> - <text name="bad_animation_text"> - No se ha podido leer el archivo de la animación. - -Recomendamos usar archivos BVH exportados de Poser 4. - </text> - <button label="Subir ([AMOUNT] L$)" name="ok_btn"/> - <button label="Cancelar" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/es/floater_autoreplace.xml b/indra/newview/skins/default/xui/es/floater_autoreplace.xml new file mode 100644 index 0000000000..15abccc376 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Configuración de reemplazo automático"> + <check_box label="Habilitar el reemplazo automático" name="autoreplace_enable" tool_tip="Al escribir el texto del chat, reemplaza las palabras clave especificadas con la sustitución correspondiente"/> + <button label="Importar lista..." name="autoreplace_import_list" tool_tip="Carga una lista previamente exportada desde un archivo."/> + <button label="Exportar lista..." name="autoreplace_export_list" tool_tip="Guarda la lista seleccionada en un archivo para poder compartirla."/> + <button label="Lista nueva..." name="autoreplace_new_list" tool_tip="Crea una lista nueva."/> + <button label="Eliminar lista" name="autoreplace_delete_list" tool_tip="Elimina la lista seleccionada."/> + <button name="autoreplace_list_up" tool_tip="Aumenta la prioridad de esta lista."/> + <button name="autoreplace_list_down" tool_tip="Baja la prioridad de esta lista."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Palabra clave" name="keyword"/> + <scroll_list.columns label="Reemplazo" name="replacement"/> + </scroll_list> + <button label="Añadir..." name="autoreplace_add_entry"/> + <button label="Eliminar" name="autoreplace_delete_entry"/> + <button label="Guardar entrada" name="autoreplace_save_entry" tool_tip="Guarda esta entrada."/> + <button label="Guardar cambios" name="autoreplace_save_changes" tool_tip="Guarda todos los cambios."/> + <button label="Cancelar" name="autoreplace_cancel" tool_tip="Descarta todos los cambios."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/es/floater_inventory.xml b/indra/newview/skins/default/xui/es/floater_inventory.xml deleted file mode 100644 index 0f0ba2fce6..0000000000 --- a/indra/newview/skins/default/xui/es/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MI INVENTARIO"> - <floater.string name="Title"> - MI INVENTARIO - </floater.string> - <floater.string name="TitleFetching"> - MI INVENTARIO (obteniendo [ITEM_COUNT] ítems...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MI INVENTARIO ([ITEM_COUNT] ítems) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Obtenido - </floater.string> - <panel label="Panel del inventario" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/es/floater_model_preview.xml b/indra/newview/skins/default/xui/es/floater_model_preview.xml index ab3ba5aed7..e2313bce99 100644 --- a/indra/newview/skins/default/xui/es/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/es/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="Triángulos" name="triangles" value="Triángulos"/> <text initial_value="Vértices" name="vertices" value="Vértices"/> <text initial_value="Alto" name="high_label" value="Alto"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + </combo_box> <button label="Buscar..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Límite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Medio" name="medium_label" value="Medio"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + <item name="Use LoD above" value="Usar nivel de detalle superior"/> + </combo_box> <button label="Buscar..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Límite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Bajo" name="low_label" value="Bajo"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + <item name="Use LoD above" value="Usar nivel de detalle superior"/> + </combo_box> <button label="Buscar..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Límite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Mínimo" name="lowest_label" value="Mínimo"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Cargar desde archivo"/> + <item name="Generate" value="Generar"/> + <item name="Use LoD above" value="Usar nivel de detalle superior"/> + </combo_box> <button label="Buscar..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Límite de triángulo"/> + <item name="Error Threshold" value="Margen de error"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Generar normales" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/es/floater_nearby_chat.xml b/indra/newview/skins/default/xui/es/floater_nearby_chat.xml deleted file mode 100644 index b3b8cdcfff..0000000000 --- a/indra/newview/skins/default/xui/es/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT"> - <check_box label="Traducir chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..e3ee0563d2 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personajes de pathfinding"> + <floater.string name="messaging_get_inprogress"> + Consultando los personajes de pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Se ha detectado un error al consultar los personajes de pathfinding. + </floater.string> + <floater.string name="messaging_complete_none_found"> + No hay personajes de pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personajes seleccionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Cargando] + </floater.string> + <floater.string name="character_owner_unknown"> + [Desconocido] + </floater.string> + <floater.string name="character_owner_group"> + [grupo] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nombre" name="name"/> + <scroll_list.columns label="Descripción" name="description"/> + <scroll_list.columns label="Propietario" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitud" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personajes: + </text> + <button label="Actualizar la lista" name="refresh_objects_list"/> + <button label="Seleccionar todo" name="select_all_objects"/> + <button label="No seleccionar ninguno" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Acciones en los personajes seleccionados: + </text> + <check_box label="Mostrar baliza" name="show_beacon"/> + <check_box label="Mostrar la cápsula de física" name="show_physics_capsule"/> + <button label="Tomar" name="take_objects"/> + <button label="Tomar una copia" name="take_copy_objects"/> + <button label="Teleportarme a él" name="teleport_me_to_object" tool_tip="Se habilita solo cuando está seleccionado un personaje."/> + <button label="Devolver" name="return_objects"/> + <button label="Eliminar" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml new file mode 100644 index 0000000000..e93ecc9e10 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Vista/prueba de pathfinding"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + No se encuentra la implementación de la biblioteca de localización de rutas. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Esperando a que termine la carga de la región. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Comprobando el estado del navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Descargando el navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + El navmesh se ha modificado en el servidor. Descargando el último navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Se ha descargado el último navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + No se puede descargar el navmesh correctamente. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + El navmesh tiene cambios pendientes. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + El navmesh se está construyendo. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Algunas regiones del navmesh tienen cambios pendientes. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Algunas regiones del navmesh se están construyendo. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Algunas regiones del navmesh tienen cambios pendientes y otras se están construyendo. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + El navmesh está actualizado. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + No se encuentra la implementación de la biblioteca de localización de rutas. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Elige los puntos inicial y final. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Elige el punto inicial. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Elige el punto final. + </floater.string> + <floater.string name="pathing_path_valid"> + La ruta se muestra de color naranja. + </floater.string> + <floater.string name="pathing_path_invalid"> + No se encuentra una ruta entre los puntos seleccionados. + </floater.string> + <floater.string name="pathing_error"> + Error durante la generación de la ruta. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Vista" name="view_panel"> + <text name="show_label"> + Mostrar: + </text> + <check_box label="Mundo virtual" name="show_world"/> + <check_box label="Solamente los objetos movibles" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Mostrar el mapa de transitabilidad: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="No mostrar" name="show_heatmap_mode_none"/> + <combo_box.item label="Personaje de tipo A" name="show_heatmap_mode_a"/> + <combo_box.item label="Personaje de tipo B" name="show_heatmap_mode_b"/> + <combo_box.item label="Personaje de tipo C" name="show_heatmap_mode_c"/> + <combo_box.item label="Personaje de tipo D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Objetos transitables" name="show_walkables"/> + <check_box label="Volúmenes materiales" name="show_material_volumes"/> + <check_box label="Obstáculos estáticos" name="show_static_obstacles"/> + <check_box label="Volúmenes de exclusión" name="show_exclusion_volumes"/> + <check_box label="Plano de agua" name="show_water_plane"/> + <check_box label="Con visión de rayos X" name="show_xray"/> + </panel> + <panel label="Probar ruta" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl-clic para seleccionar el punto inicial. + </text> + <text name="shift_click_label"> + Mayús-clic para seleccionar el punto final. + </text> + <text name="character_width_label"> + Ancho del personaje + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Tipo de personaje + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Ninguno" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Borrar ruta" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..e6f864eef5 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Linksets de pathfinding"> + <floater.string name="messaging_get_inprogress"> + Consultando los linksets de pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Se ha detectado un error al consultar los linksets de pathfinding. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modificando los linksets de pathfinding seleccionados... + </floater.string> + <floater.string name="messaging_set_error"> + Se ha detectado un error al modificar los linksets de pathfinding seleccionados. + </floater.string> + <floater.string name="messaging_complete_none_found"> + No hay linksets de pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] linksets seleccionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + En esta región no está permitido el pathfinding. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terreno] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Cargando] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Desconocido] + </floater.string> + <floater.string name="linkset_owner_group"> + [grupo] + </floater.string> + <floater.string name="linkset_is_scripted"> + Sí + </floater.string> + <floater.string name="linkset_is_not_scripted"> + No + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Desconocido + </floater.string> + <floater.string name="linkset_use_walkable"> + Objeto transitable + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Obstáculo estático + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Obstáculo móvil + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volumen material + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volumen de exclusión + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Inmaterial móvil + </floater.string> + <floater.string name="linkset_is_terrain"> + [no modificable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restringido] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [cóncavo] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restringido,cóncavo] + </floater.string> + <floater.string name="linkset_choose_use"> + Elegir la utilización del linkset... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtrar por utilización de linkset..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Objeto transitable" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Obstáculo estático" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Obstáculo móvil" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volumen material" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volumen de exclusión" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Inmaterial móvil" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Aplicar" name="apply_filters"/> + <button label="Limpiar" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nombre (prim raíz)" name="name"/> + <scroll_list.columns label="Descripción (prim raíz)" name="description"/> + <scroll_list.columns label="Propietario" name="owner"/> + <scroll_list.columns label="Con scripts" name="scripted"/> + <scroll_list.columns label="Impacto" name="land_impact"/> + <scroll_list.columns label="Distancia" name="dist_from_you"/> + <scroll_list.columns label="Utilización de linkset" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Linksets: + </text> + <button label="Actualizar la lista" name="refresh_objects_list"/> + <button label="Seleccionar todo" name="select_all_objects"/> + <button label="No seleccionar ninguno" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Mostrar baliza" name="show_beacon"/> + <button label="Tomar" name="take_objects"/> + <button label="Tomar una copia" name="take_copy_objects"/> + <button label="Teleportarme a él" name="teleport_me_to_object"/> + <button label="Devolver" name="return_objects"/> + <button label="Eliminar" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Transitabilidad: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Transitabilidad de los personajes de tipo A. El tipo del personaje del ejemplo es humanoide."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Transitabilidad de los personajes de tipo B. El tipo del personaje del ejemplo es criatura."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Transitabilidad de los personajes de tipo C. El tipo del personaje del ejemplo es mecánico."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Transitabilidad de los personajes de tipo D. El tipo del personaje del ejemplo es otro."/> + <button label="Aplicar cambios" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoide) + </text> + <text name="suggested_use_b_label"> + (Criatura) + </text> + <text name="suggested_use_c_label"> + (Mecánico) + </text> + <text name="suggested_use_d_label"> + (Otro) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_postcard.xml b/indra/newview/skins/default/xui/es/floater_postcard.xml deleted file mode 100644 index b5b9805fe2..0000000000 --- a/indra/newview/skins/default/xui/es/floater_postcard.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="FOTO POR CORREO"> - <text name="to_label"> - Correo del destinatario: - </text> - <text name="from_label"> - Su correo: - </text> - <text name="name_label"> - Su nombre: - </text> - <text name="subject_label"> - Asunto: - </text> - <line_editor label="Escriba aquí el asunto." name="subject_form"/> - <text name="msg_label"> - Mensaje: - </text> - <text_editor name="msg_form"> - Escriba aquí el mensaje. - </text_editor> - <text name="fine_print"> - Si su destinatario se registra en [SECOND_LIFE], -usted conseguirá un bono de referido. - </text> - <button label="Cancelar" name="cancel_btn"/> - <button label="Enviar" name="send_btn"/> - <string name="default_subject"> - Postal desde [SECOND_LIFE]. - </string> - <string name="default_message"> - ¡Mira esto! - </string> - <string name="upload_message"> - Enviando... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/es/floater_spellcheck.xml b/indra/newview/skins/default/xui/es/floater_spellcheck.xml new file mode 100644 index 0000000000..b664b96928 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Configuración del corrector ortográfico"> + <check_box label="Habilitar la revisión ortográfica" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Diccionario principal: + </text> + <text label="Registros:" name="spellcheck_additional"> + Diccionarios adicionales: + </text> + <text name="spellcheck_available"> + Disponibles + </text> + <text name="spellcheck_active"> + Activos + </text> + <button label="Eliminar" name="spellcheck_remove_btn"/> + <button label="Importar..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml new file mode 100644 index 0000000000..bd86ed00da --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Importar diccionario"> + <button label="Examinar" label_selected="Examinar" name="dictionary_path_browse"/> + <button label="Importar" name="ok_btn"/> + <button label="Cancelar" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_stats.xml b/indra/newview/skins/default/xui/es/floater_stats.xml index d53ae88126..00601920f2 100644 --- a/indra/newview/skins/default/xui/es/floater_stats.xml +++ b/indra/newview/skins/default/xui/es/floater_stats.xml @@ -47,6 +47,12 @@ <stat_bar label="Objetos con bajo nivel de detalle" name="physicslodtasks"/> <stat_bar label="Memoria asignada" name="physicsmemoryallocated"/> </stat_view> + <stat_bar label="Scripts ejecutados" name="simpctscriptsrun"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="Tiempo de paso de IA" name="simsimaistepmsec"/> + <stat_bar label="Pasos de silueta omitidos" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personajes actualizados" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_view label="Tiempo (ms)" name="simperf"> <stat_bar label="Tiempo total de los frames" name="simframemsec"/> <stat_bar label="Tiempo de red" name="simnetmsec"/> diff --git a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml index 1e566e3e31..93bc9f293c 100644 --- a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml @@ -20,6 +20,8 @@ <button label="Blanca" label_selected="Blanca" name="Blank"/> <button label="Ninguna" label_selected="Ninguna" left="90" name="None"/> <button label="" label_selected="" name="Pipette"/> + <check_box initial_value="true" label="Vista previa inmediata" name="apply_immediate_check"/> + <text name="preview_disabled" value="Vista previa inhabilitada"/> <filter_editor label="Filtrar las texturas" name="inventory search editor"/> <check_box initial_value="false" label="Ver las carpetas" name="show_folders_check"/> <button label="Añadir" label_selected="Añadir" name="l_add_btn"/> @@ -31,5 +33,4 @@ </scroll_list> <button label="OK" label_selected="OK" name="Select"/> <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> - <check_box initial_value="true" label="Aplicarlo ahora" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml index 29fd2ab2a3..59aaf7f74a 100644 --- a/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, Volviendo a obtener visibles de la caché, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles </text> + <text name="total_time_refetch_all_cache_label"> + 16, Volviendo a obtener todas las texturas de caché, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles + </text> <text name="total_time_refetch_vis_http_label"> - 16, Volviendo a obtener visibles de HTTP, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles + 17, Volviendo a obtener visibles de HTTP, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles + </text> + <text name="total_time_refetch_all_http_label"> + 18, Volviendo a obtener todas las texturas de HTTP, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles + </text> + <spinner label="19, Proporción de texeles/píxeles:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Fuente de texturas: </text> - <spinner label="17, Proporción de texeles/píxeles:" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="Caché + HTTP" name="0"/> + <radio_item label="Solo HTTP" name="1"/> + </radio_group> <button label="Iniciar" name="start_btn"/> <button label="Restablecer" name="clear_btn"/> <button label="Cerrar" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="Descodificar" name="decode_btn"/> <button label="Textura GL" name="gl_btn"/> <button label="Volver a obtener caché de vis." name="refetchviscache_btn"/> + <button label="Volver a obtener toda la caché" name="refetchallcache_btn"/> <button label="Volver a obtener HTTP de vis." name="refetchvishttp_btn"/> + <button label="Volver a obtener todo el HTTP" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index 650b4b457d..15462c3726 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -128,6 +128,12 @@ <panel.string name="text modify info 4"> No puedes modificar estos objetos </panel.string> + <panel.string name="text modify info 5"> + No se puede modificar este objeto a través del límite de una región + </panel.string> + <panel.string name="text modify info 6"> + No se pueden modificar estos objetos a través del límite de una región + </panel.string> <panel.string name="text modify warning"> Para configurar los permisos, debes seleccionar el objeto completo </panel.string> @@ -177,12 +183,12 @@ <combo_box.item label="Zoom" name="Zoom"/> </combo_box> <check_box label="En venta:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Copia" name="Copy"/> <combo_box.item label="Contenidos" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Precio: L$" name="Edit Cost"/> <check_box label="Mostrar en la búsqueda" name="search_check" tool_tip="Dejar que la gente vea este objeto en los resultados de la búsqueda"/> <panel name="perms_build"> <text name="perm_modify"> @@ -218,6 +224,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Atributos de pathfinding: + </text> + </panel> </panel> <panel label="Objeto" name="Object"> <check_box label="Bloqueado" name="checkbox locked" tool_tip="Previene que el objeto sea movido o borrado. Suele ser útil mientras se construye, para prevenir que se modifique sin querer."/> diff --git a/indra/newview/skins/default/xui/es/floater_top_objects.xml b/indra/newview/skins/default/xui/es/floater_top_objects.xml index 033633bd22..bb53f116c2 100644 --- a/indra/newview/skins/default/xui/es/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/es/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Tiempo </floater.string> - <floater.string name="scripts_mono_time_label"> - Tiempo en Mono - </floater.string> <floater.string name="top_colliders_title"> Objetos que colisionan </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Nombre" name="name"/> <scroll_list.columns label="Propietario" name="owner"/> <scroll_list.columns label="Posición" name="location"/> + <scroll_list.columns label="Parcela" name="parcel"/> <scroll_list.columns label="Tiempo" name="time"/> - <scroll_list.columns label="Tiempo en Mono" name="mono_time"/> <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="Memoria (KB)" name="memory"/> </scroll_list> <text name="id_text"> ID del objeto: @@ -48,6 +46,10 @@ Propietario: </text> <button label="Filtro" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parcela: + </text> + <button label="Filtro" name="filter_parcel_btn"/> <button label="Actualizar" name="refresh_btn"/> <button label="Devolver lo seleccionado" name="return_selected_btn" width="170"/> <button label="Devolver todo" left="190" name="return_all_btn"/> diff --git a/indra/newview/skins/default/xui/es/menu_bottomtray.xml b/indra/newview/skins/default/xui/es/menu_bottomtray.xml deleted file mode 100644 index 40058a1749..0000000000 --- a/indra/newview/skins/default/xui/es/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Botón Hablar" name="EnableVoiceChat"/> - <menu_item_check label="Botón Gestos" name="ShowGestureButton"/> - <menu_item_check label="Botón Moverse" name="ShowMoveButton"/> - <menu_item_check label="Botón Vista" name="ShowCameraButton"/> - <menu_item_check label="Botón Foto" name="ShowSnapshotButton"/> - <menu_item_check label="Botón Construir" name="ShowBuildButton"/> - <menu_item_check label="Botón Buscar" name="ShowSearchButton"/> - <menu_item_check label="Botón Mapa" name="ShowWorldMapButton"/> - <menu_item_check label="Botón Minimapa" name="ShowMiniMapButton"/> - <menu_item_call label="Cortar" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copiar" name="NearbyChatBar_Copy"/> - <menu_item_call label="Pegar" name="NearbyChatBar_Paste"/> - <menu_item_call label="Borrar" name="NearbyChatBar_Delete"/> - <menu_item_call label="Seleccionar todo" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/es/menu_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml index 4a8f37dee4..803d3f1331 100644 --- a/indra/newview/skins/default/xui/es/menu_inventory.xml +++ b/indra/newview/skins/default/xui/es/menu_inventory.xml @@ -67,6 +67,7 @@ <menu_item_call label="Borrar carpeta del sistema" name="Delete System Folder"/> <menu_item_call label="Empezar multiconferencia" name="Conference Chat Folder"/> <menu_item_call label="Escuchar" name="Sound Play"/> + <menu_item_call label="Copiar la SLurl" name="url_copy"/> <menu_item_call label="Acerca del hito" name="About Landmark"/> <menu_item_call label="Escuchar en el mundo" name="Animation Play"/> <menu_item_call label="Ejecutarla para usted" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/es/menu_mode_change.xml b/indra/newview/skins/default/xui/es/menu_mode_change.xml deleted file mode 100644 index 608505d192..0000000000 --- a/indra/newview/skins/default/xui/es/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Básico" name="BasicMode"/> - <menu_item_check label="Avanzado" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/es/menu_object.xml b/indra/newview/skins/default/xui/es/menu_object.xml index d8c75eaf47..33ea8c88d8 100644 --- a/indra/newview/skins/default/xui/es/menu_object.xml +++ b/indra/newview/skins/default/xui/es/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Editar" name="Edit..."/> <menu_item_call label="Construir" name="Build"/> + <menu_item_call label="Mostrar en linksets" name="show_in_linksets"/> + <menu_item_call label="Mostrar en personajes" name="show_in_characters"/> <menu_item_call label="Abrir" name="Open"/> <menu_item_call label="Sentarme aquí" name="Object Sit"/> <menu_item_call label="Levantarme" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/es/menu_text_editor.xml b/indra/newview/skins/default/xui/es/menu_text_editor.xml index 095e461734..6253463725 100644 --- a/indra/newview/skins/default/xui/es/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/es/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(desconocido)" name="Suggestion 1"/> + <menu_item_call label="(desconocido)" name="Suggestion 2"/> + <menu_item_call label="(desconocido)" name="Suggestion 3"/> + <menu_item_call label="(desconocido)" name="Suggestion 4"/> + <menu_item_call label="(desconocido)" name="Suggestion 5"/> + <menu_item_call label="Añadir al diccionario" name="Add to Dictionary"/> + <menu_item_call label="Añadir a ignorados" name="Add to Ignore"/> <menu_item_call label="Cortar" name="Cut"/> <menu_item_call label="Copiar" name="Copy"/> <menu_item_call label="Pegar" name="Paste"/> diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index 740bd35cbb..d80150ef6d 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -27,6 +27,7 @@ <menu_item_call label="Preferencias..." name="Preferences"/> <menu_item_call label="Botones de la barra de herramientas..." name="Toolbars"/> <menu_item_call label="Ocultar todos los controles" name="Hide UI"/> + <menu_item_check label="Mostrar los HUD anexados" name="Show HUD Attachments"/> <menu_item_call label="Salir de [APP_NAME]" name="Quit"/> </menu> <menu label="Comunicarme" name="Communicate"> @@ -38,6 +39,7 @@ <menu_item_call label="Amigos" name="My Friends"/> <menu_item_call label="Grupos" name="My Groups"/> <menu_item_call label="Gente cerca" name="Active Speakers"/> + <menu_item_call label="Lista de ignorados" name="Block List"/> </menu> <menu label="Mundo" name="World"> <menu_item_call label="Crear un hito de este sitio" name="Create Landmark Here"/> @@ -123,6 +125,11 @@ <menu_item_call label="Definir los scripts a ejecutar" name="Set Scripts to Running"/> <menu_item_call label="Configurar scripts como no ejecutándose" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personajes..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Ver/probar..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Opciones" name="Options"> <menu_item_check label="Mostrar los permisos avanzados" name="DebugPermissions"/> <menu_item_check label="Seleccionar sólo mis objetos" name="Select Only My Objects"/> @@ -173,7 +180,6 @@ <menu_item_check label="Ocultar las partículas" name="Hide Particles"/> <menu_item_check label="Ocultar lo seleccionado" name="Hide Selected"/> <menu_item_check label="Realzar las transparencias" name="Highlight Transparent"/> - <menu_item_check label="Mostrar los HUD anexados" name="Show HUD Attachments"/> <menu_item_check label="Mostrar el Punto de Mira en la vista subjetiva" name="ShowCrosshairs"/> </menu> <menu label="Objetos representados" name="Rendering Types"> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index af7a7b088a..7dfb27717d 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -357,13 +363,19 @@ Tienes que volver a introducir el nombre de usuario de tu avatar. Necesitas una cuenta para acceder a [SECOND_LIFE]. ¿Te gustaría crear una ahora? <url name="url"> - https://join.secondlife.com/index.php?lang=es-ES + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Volver a intentarlo" yestext="Crear una cuenta nueva"/> </notification> <notification name="InvalidCredentialFormat"> Escribe el nombre de usuario o el nombre y el apellido de tu avatar en el campo Nombre de usuario e inicia sesión otra vez. </notification> + <notification name="InvalidGrid"> + '[GRID]' no es un identificador de cuadrícula válido. + </notification> + <notification name="InvalidLocationSLURL"> + Tu localización inicial no especifica una cuadrícula válida. + </notification> <notification name="DeleteClassified"> ¿Borrar el clasificado '[NAME]'? No se reembolsan las cuotas pagadas. @@ -467,8 +479,8 @@ El objeto debe de haber sido borrado o estar fuera de rango ('out of range& Al guardar un script compilado, hubo un problema por: [REASON]. Por favor, vuelve a intentar guardarlo más tarde.. </notification> <notification name="StartRegionEmpty"> - Perdón, no está definida tu Posición inicial. -Por favor, escribe el nombre de la región en el cajetín de Posición inicial, o elige para esa posición Mi Base o Mi última posición. + No está definida tu región inicial. +Por favor, escribe el nombre de la región en el cuadro de Posición inicial o elige para esa posición Mi Base o Mi última posición. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -599,6 +611,9 @@ todos los objetos. Por favor, asegúrate de que no hay ninguno bloqueado, y de que eres el propietario de todos. </notification> + <notification name="CannotLinkPermanent"> + No se pueden vincular objetos a través de límites de región. + </notification> <notification name="CannotLinkDifferentOwners"> Imposible enlazarlos, porque hay objetos de distintos propietarios. @@ -980,6 +995,41 @@ no tienes el permiso de comprar terreno para el grupo que tienes activado actual <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification label="Añadir lista de reemplazo automático" name="AddAutoReplaceList"> + Nombre de la nueva lista: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Cambiar nombre de la lista de reemplazo automático" name="RenameAutoReplaceList"> + El nombre '[DUPNAME]' ya se está utilizando. + Escribe un nombre nuevo que sea único: + <form name="form"> + <button name="ReplaceList" text="Reemplazar la lista actual"/> + <button name="SetName" text="Usar un nombre nuevo"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + La palabra clave debe ser una palabra única y el reemplazo no puede estar vacío. + </notification> + <notification name="InvalidAutoReplaceList"> + La lista de reemplazo no es válida. + </notification> + <notification name="SpellingDictImportRequired"> + Debes especificar un archivo, un nombre y un idioma. + </notification> + <notification name="SpellingDictIsSecondary"> + El diccionario [DIC_NAME] aparentemente no contiene un archivo "aff", lo cual significa que es un diccionario "secundario". +Puedes utilizarlo como un diccionario adicional, pero no como el diccionario principal. + +Consulta https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + No se puede copiar + [FROM_NAME] + a + [TO_NAME] + </notification> <notification label="Guardar el vestuario" name="SaveOutfitAs"> Guardar como un nuevo vestuario lo que estoy llevando: <form name="form"> @@ -1161,7 +1211,7 @@ a '[THIS_GPU]' Se te ha llevado a una región cercana. </notification> <notification name="AvatarMovedLast"> - En estos momentos no está disponible tu última posición. + En estos momentos no está disponible la posición solicitada. Se te ha llevado a una región cercana. </notification> <notification name="AvatarMovedHome"> @@ -1179,9 +1229,8 @@ Puedes usar [SECOND_LIFE] de forma normal; los demás residentes te verán corre <notification name="FirstRun"> Se ha completado la instalación de [SECOND_LIFE]. -Si es la primera vez que usas [SECOND_LIFE], debes crear una cuenta antes de poder iniciar una sesión. -¿Volver a [http://join.secondlife.com secondlife.com] para crear una cuenta nueva? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Cuenta nueva..."/> +Si es la primera vez que usas [SECOND_LIFE], debes crear una cuenta para poder iniciar una sesión. + <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Crear cuenta..."/> </notification> <notification name="LoginPacketNeverReceived"> Tenemos problemas de conexión. Puede deberse a un problema de tu conexión a Internet o de [SECOND_LIFE_GRID]. @@ -1703,83 +1752,128 @@ Se cambiarán miles de regiones, y se provocará un colapso en el espacio del se <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - No estás autorizado en esa región por su nivel de calificación. Puede deberse a que no hay información validada de tu edad. - -Por favor, comprueba que tienes instalado el último visor, y dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - No estás autorizado en esa región por su nivel de calificación. - -¿Quieres ir a la Base de Conocimientos para aprender más sobre el nivel de calificación? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="No puedo entrar a esta región dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + <usetemplate ignoretext="Paso a otra región: la región que intentas visitar tiene un contenido solo accesible para los adultos." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - No estás autorizado en esa región por su nivel de calificación. + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. </notification> <notification name="RegionEntryAccessBlocked_Change"> - No estás autorizado en esta región por tus preferencias sobre el nivel de calificación. - -Para entrar en la región que deseas, cambia tu preferencia de nivel de calificación. Esto te permitirá buscar contenidos [REGIONMATURITY] y tener acceso a ellos. Para deshacer los cambios, elige Yo > Preferencias > General. + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias o tú puedes cancelar la visita. Después de cambiar tus preferencias, intenta otra vez acceder a la región. <form name="form"> - <button name="OK" text="Cambiar las preferencias"/> - <button default="true" name="Cancel" text="Cerrar"/> - <ignore name="ignore" text="Mis preferencias sobre nivel de calificación me impiden entrar a esta región"/> + <button name="OK" text="Cambiar preferencias"/> + <button default="true" name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Paso a otra región: tus preferencias de contenido no te permiten visitar la región que has seleccionado."/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Estamos experimentando dificultades técnicas con el teleporte porque tus preferencias no están sincronizadas con el servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Teleportarme: la región que intentas visitar tiene un contenido solo accesible para los adultos." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y proceder a teleportarte o bien tú puedes cancelar el teleporte. + <form name="form"> + <button name="OK" text="Cambiar y continuar"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teleportar (reiniciable): tus preferencias de contenido no te permiten visitar la región que has seleccionado."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Puedes cambiar tus preferencias o bien cancelar el teleporte. Después de cambiar tus preferencias, intenta teleportarte otra vez. + <form name="form"> + <button name="OK" text="Cambiar preferencias"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teleportar (no reiniciable): tus preferencias de contenido no te permiten visitar la región que has seleccionado."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Estamos experimentando dificultades técnicas con el teleporte porque tus preferencias no están sincronizadas con el servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Tu preferencia de nivel de calificación actual es [RATING]. + No recibirás más notificaciones cuando vayas a visitar una región con un contenido [RATING]. En el futuro, puedes cambiar tus preferencias de contenido en Yo > Preferencias > General en la barra de menús. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + En este momento no se pueden cambiar tus preferencias para ver el contenido [PREFERRED_MATURITY]. Tus preferencias se han restablecido para que puedas ver el contenido [ACTUAL_MATURITY]. Si deseas cambiar las preferencias otra vez, en la barra de menús, selecciona Yo > Preferencias > General. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - No puedes reclamar este terreno por su nivel de calificación. Puede deberse a que no hay información validada de tu edad. - -Por favor, comprueba que tienes instalado el último visor, y dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias actuales de calificación de contenido te impiden reclamar el terreno que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - No puedes reclamar este terreno por su nivel de calificación. - -¿Quieres ir a la Base de Conocimientos para más información sobre el nivel de calificación? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Solo los adultos pueden reclamar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="No puedo reclamar este terreno dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + <usetemplate ignoretext="Solo los adultos pueden reclamar este terreno." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - No puedes reclamar este terreno debido a su nivel de calificación. + El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. </notification> <notification name="LandClaimAccessBlocked_Change"> - No puedes reclamar este terreno por tus preferencias sobre el nivel de calificación. - -Puedes pulsar 'Cambiar las Preferencias' para incrementar las preferencias del nivel de calificación y, así, poder entrar. En adelante, podrás buscar y acceder a contenido [REGIONMATURITY]. Si más adelante quieres deshacer este cambio, ve a Yo > Preferencias > General. - <usetemplate ignoretext="Mis preferencias sobre el nivel de calificación me impiden reclamar este terreno" name="okcancelignore" notext="Cerrar" yestext="Cambiar preferencia"/> + El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y después puedes volver a intentar reclamar el terreno. + <form name="form"> + <button name="OK" text="Cambiar preferencias"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Tus preferencias de contenido no te permiten reclamar el terreno que has seleccionado."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - No puedes comprar este terreno por su nivel de calificación. Puede deberse a que no hay información validada de tu edad. - -Por favor, comprueba que tienes instalado el último visor, y dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias actuales de calificación de contenido te impiden comprar el terreno que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - No puedes comprar este terreno por tus preferencias de nivel de calificación. - -¿Quieres ir a la Base de Conocimientos para más información sobre el nivel de calificación? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Solo los adultos pueden comprar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="No puedo comprar este terreno dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> + <usetemplate ignoretext="Solo los adultos pueden comprar este terreno." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - No puedes comprar este terreno por su nivel de calificación. + El terreno que intentas comprar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + El terreno que intentas comprar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos. </notification> <notification name="LandBuyAccessBlocked_Change"> - No puedes comprar este terreno por tus preferencias sobre el nivel de calificación. - -Puedes pulsar 'Cambiar las Preferencias' para incrementar las preferencias del nivel de calificación y, así, poder entrar. En adelante, podrás buscar y acceder a contenido [REGIONMATURITY]. Si más adelante quieres deshacer este cambio, ve a Yo > Preferencias > General. - <usetemplate ignoretext="Mis preferencias sobre el nivel de calificación me impiden comprar el terreno" name="okcancelignore" notext="Cerrar" yestext="Cambiar preferencia"/> + El terreno que intentas comprar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y después puedes volver a intentar comprar el terreno. + <form name="form"> + <button name="OK" text="Cambiar preferencias"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Tus preferencias de contenido no te permiten comprar el terreno que has seleccionado."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Hay demasiados prims seleccionados. Por favor, selecciona [MAX_PRIM_COUNT] o menos y vuelve a intentarlo @@ -1834,10 +1928,9 @@ Puedes pulsar 'Cambiar las Preferencias' para incrementar las preferen </form> </notification> <notification label="Cambiada la calificación de la región" name="RegionMaturityChange"> - Se ha actualizado el nivel de calificación de esta región. + Se ha cambiando el nivel de calificación de esta región. Puede que lleve algún tiempo hasta que el cambio se vea reflejado en el mapa. - -Para entrar a regiones Adultas, los Residentes deben haber verificado su cuenta, bien verificando la edad o bien verificando una forma de pago. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Desajuste en la versión de voz" name="VoiceVersionMismatch"> Esta versión de [APP_NAME] no es compatible con la prestación de voz de esta región. Para que el chat de voz funcione correctamente debes actualizar [APP_NAME]. @@ -2126,14 +2219,11 @@ Publícala en una página web para que otros puedan acceder fácilmente a esta p <usetemplate ignoretext="Ponerme la ropa que estoy creando mientras modifico mi apariencia" name="okcancelignore" notext="No" yestext="Sí"/> </notification> <notification name="NotAgeVerified"> - Para acceder al contenido Adulto y los lugares de Second Life con dicho carácter, debes tener por lo menos 18 años. Visita la página de verificación de edad para confirmar que tienes más de 18 años. -Al hacerlo se iniciará el navegador web. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="No he verificado mi edad" name="okcancelignore" notext="Cancelar" yestext="Ir a Verificación de la edad"/> + El lugar que intentas visitar tiene el acceso restringido a los Residentes mayores de 18 años. + <usetemplate ignoretext="No tengo la edad suficiente para visitar áreas restringidas por edad." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Localización restringida para mayores de 18 años. </notification> <notification name="Cannot enter parcel: no payment info on file"> Para visitar este sitio debes haber aportado información de pago en tu cuenta. ¿Quieres ir al sitio web de [SECOND_LIFE] y configurar esto? @@ -2394,6 +2484,23 @@ Aquí no puedes volar. <notification name="NoBuild"> Este terreno tiene desactivado el poder construir. Aquí no puedes ni construir ni crear objetos. </notification> + <notification name="PathfindingDirty"> + La región contiene cambios de pathfinding pendientes. Si tienes derechos de construcción, puedes recargarla pulsando el botón “Recargar región”. + </notification> + <notification name="DynamicPathfindingDisabled"> + Esta región no tiene activado el pathfinding dinámico. Los objetos programados que utilicen llamadas LSL de pathfinding pueden tener un comportamiento inesperado en ella. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Si cambias ciertos objetos en esta región, otros objetos móviles podrían tener un comportamiento incorrecto. Para que los objetos móviles se comporten correctamente, pulsa el botón “Recargar la región”. Si quieres más información, elige “Ayuda”. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Ayuda" ignoretext="Si cambias ciertos objetos en esta región, otros objetos móviles podrían tener un comportamiento incorrecto." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Se ha producido un error. Puede haber ocurrido un problema en la red o el servidor, o quizás no tengas derechos de construcción. Este problema podría resolverse cerrando la sesión e iniciando una sesión nueva. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Esta parcela oculta los avatares y el chat de texto de otras parcelas. No podrás ver a los residentes que estén fuera la parcela ni ellos podrán verte a ti. El chat de texto regular del canal 0 también está bloqueado. </notification> @@ -2412,9 +2519,7 @@ Los scripts no funcionan aquí, excepto los pertenecientes al propietario del te Sólo puedes reclamar terreno público de la región en que estás. </notification> <notification name="RegionTPAccessBlocked"> - No estás autorizado en esa región por su nivel de calificación. Debes validar tu edad y/o instalar el último visor. - -Por favor, dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación. + Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo > Preferencias > General. </notification> <notification name="URBannedFromRegion"> Se te ha prohibido el acceso a la región. @@ -2425,11 +2530,11 @@ Por favor, dirígete a la Base de Conocimientos para más detalles sobre el acce <notification name="ImproperPaymentStatus"> No tienes el estado de pago adecuado para entrar a esta región. </notification> - <notification name="MustGetAgeRgion"> - Debes tener verificada la edad para entrar a esta región + <notification name="MustGetAgeRegion"> + Solo pueden acceder a esta región los mayores de 18 años. </notification> <notification name="MustGetAgeParcel"> - Debes haber verificado tu edad para entrar a esta parcela. + Para acceder a esta parcela debes ser mayor de 18 años. </notification> <notification name="NoDestRegion"> No se ha encontrada la región de destino. @@ -2529,14 +2634,35 @@ Por favor, vuelve a intentarlo en unos momentos. </form> </notification> <notification name="TeleportOffered"> - [NAME_SLURL] te ha ofrecido teleportarte a su posición: + [NAME_SLURL] te ofrece teleportarte a su localización: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teleportar"/> <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] te ofrece teleportarte a su localización: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Esta región tiene un contenido [REGION_CONTENT_MATURITY, pero tus preferencias actuales no te autorizan a ver los contenidos [REGION_CONTENT_MATURITY]. Podemos cambiar tus preferencias y proceder a teleportarte o bien tú puedes cancelar el teleporte. + <form name="form"> + <button name="Teleport" text="Cambiar y continuar"/> + <button name="Cancel" text="Cancelar"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] te ofrece teleportarte a su localización: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +No obstante, el contenido de esta región solo es accesible para los adultos. + </notification> <notification name="TeleportOfferSent"> Teleporte ofrecido a [TO_NAME] </notification> @@ -2933,6 +3059,10 @@ Has actualizado una textura obtenida mediante bake de [RESOLUTION] para '[B ( [EXISTENCE] segundos con vida ) Has actualizado de manera local una textura obtenida mediante bake de [RESOLUTION] para '[BODYREGION]' después de [TIME] segundos. </notification> + <notification name="LivePreviewUnavailable"> + No se puede mostrar una vista previa de esta textura porque es de tipo 'no copiable' y/o 'no transferible'. + <usetemplate ignoretext="Advertirme si el modo Vista previa inmediata no está disponible para las texturas 'no copiable' y/o 'no transferible'" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> ¿Estás seguro de que deseas salir de esta multiconferencia? <usetemplate ignoretext="Confirma antes de salir de la llamada" name="okcancelignore" notext="No" yestext="Sí"/> @@ -3101,6 +3231,62 @@ Al ocultar el botón Hablar se desactiva la función de voz. Esta acción ocultará todos los botones y elementos de menú. Para restaurarlos, pulsa otra vez en [SHORTCUT]. <usetemplate ignoretext="Confirmar antes de ocultar la IU" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +¿Quieres continuar? + <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse debido a restricciones de los permisos del linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. + +¿Quieres continuar? + <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer debido a restricciones de los permisos del linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer porque la forma no es convexa" name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. Los tipos de utilización de estos linksets no cambiarán. + +¿Quieres continuar? + <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse debido a restricciones de los permisos del linkset y porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + El indicador de inmaterial de algunos linksets seleccionados se conmutará. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' debido a restricciones de los permisos del linkset. Estos linksets se configurarán como '[RESTRICTED_TYPE]'. + +Algunos de los linksets seleccionados no pueden configurarse como '[REQUESTED_TYPE]' porque su forma no es convexa. Los tipos de utilización de estos linksets no cambiarán. + +¿Quieres continuar? + <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer debido a restricciones de los permisos del linkset y porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + El objeto que has seleccionado afecta al navmesh. Al cambiarlo a una Ruta flexible se eliminará del navmesh. + <usetemplate ignoretext="El objeto que has seleccionado afecta al navmesh. Al cambiarlo a una Ruta flexible se eliminará del navmesh." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Parece que no tienes el hardware apropiado para [APP_NAME]. [APP_NAME] requiere una tarjeta gráfica OpenGL que admita texturas múltiples ('multitexture support'). Si la tienes, comprueba que tienes los últimos 'drivers' para tu tarjeta gráfica, así como los últimos parches y 'service packs' para tu sistema operativo. @@ -3137,4 +3323,12 @@ Desactivando futuras actualizaciones de este archivo. Se ha intentado añadir un archivo de imagen [FNAME] no válido o ilegible, que no se puede abrir ni descodificar. Intento cancelado. </notification> + <notification name="PathfindingReturnMultipleItems"> + Vas a devolver [NUM_ITEMS] objetos. ¿Estás seguro de que deseas continuar? + <usetemplate ignoretext="¿Estás seguro de que quieres devolver varios objetos?" name="okcancelignore" notext="No" yestext="Sí"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Vas a eliminar [NUM_ITEMS] objetos. ¿Estás seguro de que deseas continuar? + <usetemplate ignoretext="¿Estás seguro de que quieres eliminar varios elementos?" name="okcancelignore" notext="No" yestext="Sí"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/es/panel_bottomtray.xml b/indra/newview/skins/default/xui/es/panel_bottomtray.xml deleted file mode 100644 index 2b1d017a2d..0000000000 --- a/indra/newview/skins/default/xui/es/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Activa/Desactiva el micrófono"/> - <string name="VoiceControlBtnToolTip" value="Muestra/Oculta el panel del control de voz"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Hablar" label_selected="Hablar" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gestos" name="Gesture" tool_tip="Muestra/Oculta los gestos"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Moverme" name="movement_btn" tool_tip="Muestra/Oculta los controles del movimiento"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Visión" name="camera_btn" tool_tip="Muestra/Oculta los controles de la cámara"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Hacer una foto"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Construir" name="build_btn" tool_tip="Muestra/Oculta las herramientas de construcción"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Buscar" name="search_btn" tool_tip="Muestra/Oculta la búsqueda"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Mapa" name="world_map_btn" tool_tip="Muestra/Oculta el mapa del mundo"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Minimapa" name="mini_map_btn" tool_tip="Muestra/Oculta el minimapa"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversaciones"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notificaciones"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_group_invite.xml b/indra/newview/skins/default/xui/es/panel_group_invite.xml index 0d877f78f2..319e9d0f1b 100644 --- a/indra/newview/skins/default/xui/es/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/es/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Alguno de los Residentes que has elegido ya están en el grupo: no se les enviará la invitación. </panel.string> + <panel.string name="invite_selection_too_large"> + Las invitaciones al grupo no se han enviado: has seleccionado demasiados Residentes. Solo se permiten 100 invitaciones al grupo por solicitud. + </panel.string> <text bottom_delta="-96" height="72" name="help_text" width="214"> Puedes elegir a varios Residentes para invitarles a tu grupo. Para empezar, pulsa 'Abrir el selector de residentes'. </text> diff --git a/indra/newview/skins/default/xui/es/panel_login.xml b/indra/newview/skins/default/xui/es/panel_login.xml index 0e94cbe70b..1d7f077fe7 100644 --- a/indra/newview/skins/default/xui/es/panel_login.xml +++ b/indra/newview/skins/default/xui/es/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/index.php?lang=es-ES - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=es </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + INICIAR SESIÓN + </text> <text name="username_text"> Nombre de usuario: </text> @@ -15,34 +15,32 @@ <text name="password_text"> Contraseña: </text> - <check_box label="Recordar la contraseña" name="remember_check"/> - <button label="Iniciar sesión" name="connect_btn"/> - <text name="mode_selection_text"> - Modo: - </text> - <combo_box name="mode_combo" tool_tip="Selecciona el modo. Elige Básico para una exploración rápida y fácil y para chatear. Elige Avanzado para tener acceso a más funciones."> - <combo_box.item label="Básico" name="Basic"/> - <combo_box.item label="Avanzado" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Empezar en: </text> <combo_box name="start_location_combo"> <combo_box.item label="Mi última posición" name="MyLastLocation"/> <combo_box.item label="Mi Base" name="MyHome"/> - <combo_box.item label="<Escribe en qué región>" name="Typeregionname"/> + <combo_box.item label="<Escribe el nombre de la región>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Registrarme + <layout_panel name="links_login_panel"> + <text name="login_help"> + ¿Necesitas ayuda para conectarte? </text> <text name="forgot_password_text"> ¿Olvidaste el nombre de usuario o la contraseña? </text> - <text name="login_help"> - ¿Necesitas ayuda para conectarte? + <button label="Iniciar sesión" name="connect_btn"/> + <check_box label="Recordar la contraseña" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREA TU CUENTA </text> + <button label="Iniciar ahora" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/es/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..96df844512 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="Recargar la región" name="navmesh_btn" tool_tip="Pulsa para recargar el navmesh de la región."/> + <button label="Solicitando recarga" name="navmesh_btn_sending" tool_tip="Enviando la solicitud de recarga al servidor."/> + <button label="La región se está recargando" name="navmesh_btn_baking" tool_tip="La región se está recargando. Este botón desaparecerá cuando finalice la recarga."/> +</panel> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml index aea9b9ce4a..b0b6114e88 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="Chats de MI" name="EnableIMChatPopups" tool_tip="Activa esta casilla para ver una ventana emergente cada vez que recibas un mensaje instantáneo"/> <spinner label="Duración de los interlocutores favoritos:" name="nearby_toasts_lifetime"/> <spinner label="Tiempo de los otros interlocutores:" name="nearby_toasts_fadingtime"/> - <button label="Configuración de la traducción del chat" name="ok_btn"/> + <button label="Traducción…" name="ok_btn"/> + <button label="Reemplazo automático..." name="autoreplace_showgui"/> + <button label="Revisión ortográfica..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_region_debug.xml b/indra/newview/skins/default/xui/es/panel_region_debug.xml index 64162220a6..71bdba1a25 100644 --- a/indra/newview/skins/default/xui/es/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/es/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" left="297" name="top_scripts_help"/> <button label="Reiniciar la región" name="restart_btn" tool_tip="Cuenta atrás de 2 minutos y reiniciar la región"/> <button label="?" name="restart_help"/> - <button label="Retrasar el reinicio" name="cancel_restart_btn" tool_tip="Retrasar una hora el reinicio de la región"/> + <button label="Cancelar reinicio" name="cancel_restart_btn" tool_tip="Cancelar el reinicio de región"/> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_region_estate.xml b/indra/newview/skins/default/xui/es/panel_region_estate.xml index 84c1ed7686..6089dfb8db 100644 --- a/indra/newview/skins/default/xui/es/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/es/panel_region_estate.xml @@ -26,7 +26,7 @@ Permitir únicamente el acceso a los Residentes que: </text> <check_box label="Han aportado la información de pago." name="limit_payment" tool_tip="Para poder acceder a este estado los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/> - <check_box label="Han verificado su edad" name="limit_age_verified" tool_tip="Para poder acceder a este estado los Residentes deben haber verificado su edad. Para más información, ver [SUPPORT_SITE]."/> + <check_box label="Son mayores de 18 años" name="limit_age_verified" tool_tip="Para poder acceder a este estado, los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/> <check_box label="Permitir el chat de voz" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <check_box label="Permitir el teleporte a cualquier punto" name="allow_direct_teleport"/> diff --git a/indra/newview/skins/default/xui/es/panel_region_texture.xml b/indra/newview/skins/default/xui/es/panel_region_texture.xml deleted file mode 100644 index 047e8f2f30..0000000000 --- a/indra/newview/skins/default/xui/es/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Texturas del terreno" name="Textures"> - <text name="region_text_lbl"> - Región: - </text> - <text name="region_text"> - desconocida - </text> - <text name="detail_texture_text" width="380"> - Texturas del terreno (se requieren archivos .tga de 512x512 y 24 bites) - </text> - <text name="height_text_lbl"> - 1 (Baja) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Alta) - </text> - <text name="height_text_lbl5"> - Rangos de la elevación de la textura - </text> - <text name="height_text_lbl6"> - Noroeste - </text> - <text name="height_text_lbl7"> - Noreste - </text> - <text name="height_text_lbl8"> - Suroeste - </text> - <text name="height_text_lbl9"> - Sureste - </text> - <spinner label="Baja" name="height_start_spin_0"/> - <spinner label="Baja" name="height_start_spin_1"/> - <spinner label="Baja" name="height_start_spin_2"/> - <spinner label="Baja" name="height_start_spin_3"/> - <spinner label="Alta" name="height_range_spin_0"/> - <spinner label="Alta" name="height_range_spin_1"/> - <spinner label="Alta" name="height_range_spin_2"/> - <spinner label="Alta" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Estos valores representan la gama de mezclas para las texturas superiores. - </text> - <text name="height_text_lbl11"> - Midiendo en metros, el valor BAJA es la altura MÁXIMA de la textura #1, y el valor ALTA es la altura MÍNIMA de la textura #4. - </text> - <text name="height_text_lbl12"> - y el valor ALTA es la altura MÍNIMA de la textura #4. - </text> - <button label="Aplicar" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_side_tray.xml b/indra/newview/skins/default/xui/es/panel_side_tray.xml deleted file mode 100644 index cf5afb3cd1..0000000000 --- a/indra/newview/skins/default/xui/es/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Manejar la barra lateral." name="sidebar_openclose" tab_title="Barra lateral"/> - <sidetray_tab description="Inicio." name="sidebar_home" tab_title="Inicio"> - <panel label="Inicio" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Edita tu perfil público y tus destacados." name="sidebar_me" tab_title="Mi perfil"> - <panel_container name="panel_container"> - <panel label="Yo" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encuentra a tus amigos, contactos y gente que esté cerca." name="sidebar_people" tab_title="Gente"> - <panel_container name="panel_container"> - <panel label="Perfil del grupo" name="panel_group_info_sidetray"/> - <panel label="Residentes y objetos ignorados" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encontrar lugares donde ir o que ya visitaste." label="Lugares" name="sidebar_places" tab_title="Lugares"> - <panel label="Lugares" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Mira tu inventario." name="sidebar_inventory" tab_title="Mi inventario"> - <panel label="Modificar el inventario" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Cambia tu apariencia y tu 'look' actual." name="sidebar_appearance" tab_title="Mi apariencia"> - <panel label="Modificar la apariencia" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml new file mode 100644 index 0000000000..426783aa8e --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater" width="215"> + <slider label="General" label_width="55" name="System Volume" width="155"/> + <slider label="Botones" label_width="55" name="UI Volume" width="155"/> + <slider label="Ambiental" label_width="55" name="Wind Volume" width="155"/> + <slider label="Sonidos" label_width="55" name="SFX Volume" width="155"/> + <check_box name="gesture_audio_play_btn" tool_tip="Activar sonidos de los gestos"/> + <slider label="Música" label_width="55" name="Music Volume" width="155"/> + <check_box name="enable_music" tool_tip="Activar música en streaming"/> + <slider label="Media" label_width="55" name="Media Volume" width="155"/> + <check_box name="enable_media" tool_tip="Activar media en streaming"/> + <slider label="Voz" label_width="55" name="Voice Volume" width="155"/> + <check_box name="enable_voice_check" tool_tip="Activar el chat de voz"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml index ef7c6781be..176247f90e 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (desconocidas) </panel.string> + <panel.string name="unknown_multiple"> + (desconocido/múltiple) + </panel.string> <panel.string name="public"> (público) </panel.string> diff --git a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml index bd814ecc66..9da2958953 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> No puedes modificar estos objetos </panel.string> + <panel.string name="text modify info 5"> + No se puede modificar este objeto a través del límite de una región + </panel.string> + <panel.string name="text modify info 6"> + No se pueden modificar estos objetos a través del límite de una región + </panel.string> <panel.string name="text modify warning"> Este objeto tiene partes enlazadas </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Precio: L$" name="Edit Cost"/> <check_box label="Mostrar en la búsqueda" name="search_check" tool_tip="Permitir que la gente vea este objeto en los resultados de la búsqueda"/> + <text name="pathfinding_attributes_label"> + Atributos de pathfinding: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index adc32ba168..52bcab54e5 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -128,7 +128,7 @@ Salir </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=es-ES + http://join.secondlife.com/index.php?lang=es-ES&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Ya no puedes acceder a Second Life con el visor que estás utilizando. Visita la siguiente página para descargar un nuevo visor: @@ -988,6 +988,9 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="script_files"> Scripts </string> + <string name="dictionary_files"> + Diccionarios + </string> <string name="AvatarSetNotAway"> Salir del estado ausente </string> @@ -1387,6 +1390,12 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="InvFolder favorite"> Mis Favoritos </string> + <string name="InvFolder Favorites"> + Mis Favoritos + </string> + <string name="InvFolder favorites"> + Mis Favoritos + </string> <string name="InvFolder Current Outfit"> Vestuario actual </string> @@ -1402,6 +1411,12 @@ Intenta iniciar sesión de nuevo en unos instantes. <string name="InvFolder Meshes"> Redes </string> + <string name="InvFolder Received Items"> + Objetos recibidos + </string> + <string name="InvFolder Merchant Outbox"> + Buzón de salida de comerciante + </string> <string name="InvFolder Friends"> Amigos </string> @@ -3780,6 +3795,12 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Los avatares están visibles y está permitido el chat fuera de esta parcela </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Los objetos que se mueven pueden presentar un comportamiento incorrecto en la región hasta que ésta se recargue. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Esta región no tiene activado el pathfinding dinámico. + </string> <string name="UpdaterWindowTitle"> Actualizar [APP_NAME] </string> @@ -4913,6 +4934,21 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Ninguno + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Afecta al navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personaje + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Múltiple) + </string> <string name="snapshot_quality_very_low"> Muy bajo </string> @@ -4928,4 +4964,10 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas <string name="snapshot_quality_very_high"> Muy alto </string> + <string name="TeleportMaturityExceeded"> + El Residente no puede visitar esta región. + </string> + <string name="UserDictionary"> + [Usuario] + </string> </strings> diff --git a/indra/newview/skins/default/xui/es/teleport_strings.xml b/indra/newview/skins/default/xui/es/teleport_strings.xml index a23d9c43d0..94975a83f8 100644 --- a/indra/newview/skins/default/xui/es/teleport_strings.xml +++ b/indra/newview/skins/default/xui/es/teleport_strings.xml @@ -44,6 +44,9 @@ Para repetir el tutorial, visita la isla de bienvenida pública. <message name="no_inventory_host"> En estos momentos no está disponible el sistema del inventario. </message> + <message name="MustGetAgeRegion"> + Solo pueden acceder a esta región los mayores de 18 años. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -79,5 +82,8 @@ Para repetir el tutorial, visita la isla de bienvenida pública. <message name="requesting"> Solicitando teleporte... </message> + <message name="pending"> + Teleporte pendiente... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index 4409949584..a659cb4245 100644 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -66,27 +66,26 @@ Version serveur vocal : [VOICE_VERSION] </panel> <panel label="Licences" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion - APR Copyright (C) 2000-2004 The Apache Software Foundation - Collada DOM Copyright 2005 Sony Computer Entertainment Inc. - cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. - FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). + FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm et Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University et David Luebke, Brenden Schubert, University of Virginia. + GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University, et David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. - ogg/vorbis Copyright (C) 2001, Xiphophorus - OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. - PCRE Copyright (c) 1997-2008 University of Cambridge + ogg/vorbis Copyright (C) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. - zlib Copyright (C) 1995-2002 Jean-loup Gailly et Mark Adler. - google-perftools Copyright (c) 2005, Google Inc. + zlib Copyright (C) 1995-2012 Jean-Loup Gailly et Mark Adler. Le client Second Life utilise Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (et ses concédants de licence). Tous droits réservés. Pour plus de détails, consultez le site Web www.havok.com. diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml index 49af1a87e1..25c49b97b5 100644 --- a/indra/newview/skins/default/xui/fr/floater_about_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml @@ -134,7 +134,7 @@ <text name="DwellText"> Chargement... </text> - <button label="Acheter du terrain" label_selected="Acheter le terrain..." left_delta="60" name="Buy Land..." width="125"/> + <button label="Acheter le terrain" label_selected="Acheter le terrain..." left_delta="60" name="Buy Land..." width="125"/> <button label="Vente Linden" label_selected="Vente Linden..." name="Linden Sale..." tool_tip="Le terrain doit être la propriété d'un résident, avoir un contenu défini et ne pas être aux enchères."/> <button label="Infos sur les scripts" name="Scripts..." width="110"/> <button label="Acheter pour le groupe" label_selected="Acheter pour le groupe..." name="Buy For Group..."/> @@ -339,7 +339,7 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche. <check_box label="Groupe" name="check group scripts"/> <check_box label="Sécurisé (pas de dégâts)" name="check safe" tool_tip="Si cette option est cochée, le terrain est sécurisé et il n'y pas de risques de dommages causés par des combats. Si elle est décochée, des dommages causés par les combats peuvent avoir lieu."/> <check_box label="Pas de bousculades" name="PushRestrictCheck" tool_tip="Empêche l'utilisation de scripts causant des bousculades. Cette option est utile pour empêcher les comportements abusifs sur votre terrain."/> - <check_box label="Afficher le lieu dans la recherche (30 L$/semaine)" name="ShowDirectoryCheck" tool_tip="Afficher la parcelle dans les résultats de recherche"/> + <check_box label="Voir le lieu dans la recherche (30 L$/sem.)" name="ShowDirectoryCheck" tool_tip="Afficher la parcelle dans les résultats de recherche"/> <combo_box name="land category with adult"> <combo_box.item label="Toutes catégories" name="item0"/> <combo_box.item label="Appartenant aux Lindens" name="item1"/> @@ -377,7 +377,7 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche. </text> <texture_picker label="" name="snapshot_ctrl" tool_tip="Cliquez pour sélectionner une image"/> <text name="allow_label5"> - Les avatars présents sur d'autres parcelles peuvent voir et chatter avec les avatars présents sur cette parcelle. + Les avatars sur d'autres parcelles peuvent voir et chatter avec les avatars sur cette parcelle. </text> <check_box label="Voir les avatars" name="SeeAvatarsCheck" tool_tip="Permettre aux avatars présents sur d'autres parcelles de voir et chatter avec les avatars présents sur cette parcelle et à vous de les voir et de chatter avec eux."/> <text name="landing_point"> @@ -470,7 +470,7 @@ musique : Conditions d'accès des résidents : </text> <check_box label="Informations de paiement enregistrées [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Pour pouvoir accéder à cette parcelle, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d'informations."/> - <check_box label="Âge vérifié [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Pour que les résidents puissent accéder à cette parcelle, leur âge doit avoir fait l'objet d'une vérification. Consultez le [SUPPORT_SITE] pour plus d'informations."/> + <check_box label="Avoir plus de 18 ans [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Pour accéder à cette parcelle, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d'informations."/> <check_box label="Autoriser l'accès au groupe : [GROUP]" name="GroupCheck" tool_tip="Définir le groupe à l'onglet Général."/> <check_box label="Vendre des pass à :" name="PassCheck" tool_tip="Autoriser un accès temporaire à cette parcelle"/> <combo_box name="pass_combo" width="110"> diff --git a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_preview.xml deleted file mode 100644 index aa42fe6150..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml +++ /dev/null @@ -1,189 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> - <floater.string name="failed_to_initialize"> - Echec de l'initialisation du mouvement - </floater.string> - <floater.string name="anim_too_long"> - Le fichier d'animation fait [LENGTH] secondes. - -La longueur maximale est de [MAX_LENGTH] secondes. - </floater.string> - <floater.string name="failed_file_read"> - Impossible de lire le fichier d'animation. - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - Ok - </floater.string> - <floater.string name="E_ST_EOF"> - Fichier incomplet. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Impossible de lire la définition des contraintes. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - Impossible d'ouvrir le fichier BVH. - </floater.string> - <floater.string name="E_ST_NO_HIER"> - En-tête HIERARCHY non valide. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - Impossible de trouver ROOT ou JOINT. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - Impossible de trouver le nom JOINT. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - Impossible de trouver OFFSET. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - Impossible de trouver les CHANNELS. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Impossible d'obtenir l'ordre de rotation. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Impossible d'obtenir l'axe de rotation. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - Impossible de trouver MOTION. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - Impossible d'obtenir le nombre de cadres. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Impossible d'obtenir le temps du cadre. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Impossible de trouver les valeurs de la position. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Impossible de trouver les valeurs de rotation. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Impossible d'ouvrir le fichier de traduction. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Impossible de lire l'en-tête de traduction. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Impossible de lire la traduction. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Impossible de lire la traduction. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Impossible de lire la valeur de traduction relative. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Impossible de lire la traduction. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Impossible de lire la matrice de traduction. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Impossible de trouver le nom mergechild. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Impossible de trouver le nom mergeparent. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Impossible de définir la valeur de la priorité. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Impossible de définir la valeur de la boucle - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Impossible de trouver les valeurs easeIn. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - Impossible de trouver les valeurs easeOut. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Impossible d'obtenir la valeur hand morph. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Impossible de lire le nom emote. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Nom de racine incorrect. - </floater.string> - <text name="name_label"> - Nom : - </text> - <text name="description_label"> - Description : - </text> - <spinner label="Priorité" name="priority" tool_tip="Contrôle quelles autres animations peuvent être remplacées par cette animation"/> - <check_box label="Boucle" left="6" name="loop_check" tool_tip="Lit cette animation en boucle"/> - <spinner label="Début (%)" label_width="65" name="loop_in_point" tool_tip="Définit un point de l'animation auquel retourne la boucle" width="105"/> - <spinner label="Fin (%)" name="loop_out_point" tool_tip="Définit un point de l'animation qui met fin à la boucle"/> - <text name="hand_label"> - Mouvement de -main - </text> - <combo_box label="" name="hand_pose_combo" tool_tip="Contrôle ce que font les mains pendant l'animation"> - <combo_box.item label="Espacement" name="Spread"/> - <combo_box.item label="Détendues" name="Relaxed"/> - <combo_box.item label="Pointer (les deux)" name="PointBoth"/> - <combo_box.item label="Poing" name="Fist"/> - <combo_box.item label="Détendue (gauche)" name="RelaxedLeft"/> - <combo_box.item label="Pointer (gauche)" name="PointLeft"/> - <combo_box.item label="Poing (gauche)" name="FistLeft"/> - <combo_box.item label="Détendue (droite)" name="RelaxedRight"/> - <combo_box.item label="Pointer (droite)" name="PointRight"/> - <combo_box.item label="Poing (droite)" name="FistRight"/> - <combo_box.item label="Saluer (droite)" name="SaluteRight"/> - <combo_box.item label="Taper" name="Typing"/> - <combo_box.item label="Paix (main droite)" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Expression - </text> - <combo_box label="" name="emote_combo" tool_tip="Contrôle ce que fait le visage pendant l'animation"> - <item label="(aucun)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Effrayé" name="Afraid" value="Effrayé"/> - <item label="En colère" name="Angry" value="En colère"/> - <item label="Grand sourire" name="BigSmile" value="Grand sourire"/> - <item label="Ennui" name="Bored" value="Ennui"/> - <item label="Pleurer" name="Cry" value="Pleurer"/> - <item label="Mépris" name="Disdain" value="Mépris"/> - <item label="Gêne" name="Embarrassed" value="Gêne"/> - <item label="Froncer les sourcils" name="Frown" value="Froncer les sourcils"/> - <item label="Embrasser" name="Kiss" value="Embrasser"/> - <item label="Rire" name="Laugh" value="Rire"/> - <item label="Plllppt" name="Plllppt" value="Tirer la langue"/> - <item label="Dégoût" name="Repulsed" value="Dégoût"/> - <item label="Triste" name="Sad" value="Triste"/> - <item label="Hausser les épaules" name="Shrug" value="Hausser les épaules"/> - <item label="Sourire" name="Smile" value="Sourire"/> - <item label="Surprise" name="Surprise" value="Surprise"/> - <item label="Clin d'œil" name="Wink" value="Clin d'œil"/> - <item label="Soucis" name="Worry" value="Inquiétude"/> - </combo_box> - <text name="preview_label"> - Prévisualiser -pendant - </text> - <combo_box label="" name="preview_base_anim" tool_tip="Utilisez cette option pour tester votre animation pendant que votre avatar fait des choses banales."> - <item label="Debout" name="Standing" value="Debout"/> - <item label="Marche" name="Walking" value="Marche"/> - <item label="Assis" name="Sitting" value="Assis"/> - <item label="Vol" name="Flying" value="Vol"/> - </combo_box> - <spinner label="Transition début (s)" name="ease_in_time" tool_tip="Durée (en secondes) de l'entrée en fondu de l'animation"/> - <spinner label="Transition fin (s)" name="ease_out_time" tool_tip="Durée (en secondes) de la sortie en fondu de l'animation"/> - <button label="" name="play_btn" tool_tip="Lire votre animation"/> - <button name="pause_btn" tool_tip="Pauser votre animation"/> - <button label="" name="stop_btn" tool_tip="Arrêter le playback"/> - <slider label="" name="playback_slider"/> - <text name="bad_animation_text"> - Impossible de lire le fichier d'animation. - -Nous recommandons les fichiers BVH extraits de Poser 4. - </text> - <button label="Charger ([AMOUNT] L$)" name="ok_btn"/> - <button label="Annuler" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_autoreplace.xml b/indra/newview/skins/default/xui/fr/floater_autoreplace.xml new file mode 100644 index 0000000000..1d19181692 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Paramètres Rechercher/Remplacer"> + <check_box label="Activer la fonction Rechercher/Remplacer" name="autoreplace_enable" tool_tip="Lors de la saisie du texte d'un chat, remplace chaque mot-clé spécifié par la valeur correspondante."/> + <button label="Importer une liste..." name="autoreplace_import_list" tool_tip="Charger une liste précédemment exportée à partir d'un fichier."/> + <button label="Exporter la liste..." name="autoreplace_export_list" tool_tip="Enregistrer la liste sélectionnée dans un fichier afin de pouvoir la partager."/> + <button label="Nouvelle liste..." name="autoreplace_new_list" tool_tip="Créer une nouvelle liste."/> + <button label="Supprimer la liste" name="autoreplace_delete_list" tool_tip="Supprimer la liste sélectionnée."/> + <button name="autoreplace_list_up" tool_tip="Augmenter la priorité de cette liste."/> + <button name="autoreplace_list_down" tool_tip="Diminuer la priorité de cette liste."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Mot-clé" name="keyword"/> + <scroll_list.columns label="Remplacement" name="replacement"/> + </scroll_list> + <button label="Ajouter..." name="autoreplace_add_entry"/> + <button label="Supprimer" name="autoreplace_delete_entry"/> + <button label="Enregistrer" name="autoreplace_save_entry" tool_tip="Enregistrer cette entrée."/> + <button label="Enregistrer les modifications" name="autoreplace_save_changes" tool_tip="Enregistrer toutes les modifications."/> + <button label="Annuler" name="autoreplace_cancel" tool_tip="Ignorer toutes les modifications."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/fr/floater_camera.xml b/indra/newview/skins/default/xui/fr/floater_camera.xml index f2b0ee8af3..893e389f69 100644 --- a/indra/newview/skins/default/xui/fr/floater_camera.xml +++ b/indra/newview/skins/default/xui/fr/floater_camera.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="camera_floater" title="PARAMÈTRES DE LA CAMÉRA"> +<floater name="camera_floater" title="CONTRÔLE DE LA CAMÉRA"> <floater.string name="rotate_tooltip"> Faire tourner la caméra autour du point central </floater.string> diff --git a/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml index 0100419bc5..5ec68458e1 100644 --- a/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml +++ b/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml @@ -22,13 +22,13 @@ Remarque : si vous changez votre préréglage de nom, un nouveau préréglage sera créé et celui existant restera tel quel. </text> <text name="hint_item1"> - - Cliquez sur un repère pour modifier le réglage du ciel et l'heure associés. + - Modifier un réglage de ciel/heure : clic sur le repère </text> <text name="hint_item2"> - - Cliquez sur les repères et faites-les glisser afin de définir les heures de transition. + - Heures de transition : clic-glissement des repères </text> <text name="hint_item3"> - - Déplacez le marqueur en forme de triangle pour afficher un aperçu du cycle du jour. + - Aperçu du cycle du jour : déplacement du triangle </text> <panel name="day_cycle_slider_panel"> <multi_slider initial_value="0" name="WLTimeSlider"/> @@ -91,11 +91,11 @@ </text> </panel> <text name="WLCurKeyPresetText"> - Réglage du ciel : + Régl. ciel : </text> <combo_box label="Préréglage" name="WLSkyPresets"/> <text name="WLCurKeyTimeText"> - Heure : + H. : </text> <time name="time" value="6h"/> <check_box label="Appliquer ce nouveau cycle du jour" name="make_default_cb"/> diff --git a/indra/newview/skins/default/xui/fr/floater_environment_settings.xml b/indra/newview/skins/default/xui/fr/floater_environment_settings.xml index 9ea47a3dd7..ea12749d27 100644 --- a/indra/newview/skins/default/xui/fr/floater_environment_settings.xml +++ b/indra/newview/skins/default/xui/fr/floater_environment_settings.xml @@ -18,7 +18,7 @@ <combo_box.item label="-Effectuer une sélection-" name="item0"/> </combo_box> <text name="sky_dayc_settings_title"> - Ciel / Cycle du jour + Ciel/Cycle du jour </text> <radio_group name="sky_dayc_settings_radio_group"> <radio_item label="Ciel fixe" name="my_sky_settings"/> diff --git a/indra/newview/skins/default/xui/fr/floater_god_tools.xml b/indra/newview/skins/default/xui/fr/floater_god_tools.xml index e4c53d866c..0d21a8af32 100644 --- a/indra/newview/skins/default/xui/fr/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_god_tools.xml @@ -71,8 +71,8 @@ <button label="Supprimer tous les objets scriptés de la cible sur les terrains des autres" label_selected="Supprimer tous les objets scriptés de la cible sur les terrains des autres" name="Delete Target's Scripted Objects On Others Land" tool_tip="Supprimer tous les objets scriptés appartenant à la cible sur les terrains ne lui appartenant pas. Les objets non copiables seront renvoyés."/> <button label="Supprimer les objets scriptés de la cible sur *tous* les terrains" label_selected="Supprimer les objets scriptés de la cible sur *tous* les terrains" name="Delete Target's Scripted Objects On *Any* Land" tool_tip="Supprimer les objets scriptés appartenant à la cible dans cette région. Les objets non copiables seront renvoyés."/> <button label="Supprimer *tous* les objets de la cible" label_selected="Supprimer *tous* les objets de la cible" name="Delete *ALL* Of Target's Objects" tool_tip="Supprimer tous les objets appartenant à la cible dans cette région. Les objets non copiables seront renvoyés."/> - <button label="Afficher les collisions les plus consommatrices" label_selected="Afficher les collisions les plus consommatrices" name="Get Top Colliders" tool_tip="Dresse une liste des objets avec les callbacks les plus fréquents. " width="300"/> - <button label="Afficher les objets scriptés les plus consommateurs" label_selected="Afficher les objets scriptés les plus consommateurs" name="Get Top Scripts" tool_tip="Dresse une liste des objets qui passent le plus de temps à exécuter des scripts." width="300"/> + <button label="Collisions les plus consommatrices" label_selected="Collisions les plus consommatrices" name="Get Top Colliders" tool_tip="Liste des objets avec les callbacks les plus fréquents. " width="300"/> + <button label="Scripts les plus consommateurs" label_selected="Scripts les plus consommateurs" name="Get Top Scripts" tool_tip="Liste des objets passant le plus de temps à exécuter des scripts." width="300"/> <button label="Résumé des scripts" label_selected="Résumé des scripts" name="Scripts digest" tool_tip="Dresse une liste des scripts et de leurs occurrences." width="300"/> </panel> <panel label="Requête" name="request"> diff --git a/indra/newview/skins/default/xui/fr/floater_inventory.xml b/indra/newview/skins/default/xui/fr/floater_inventory.xml deleted file mode 100644 index 200c07e522..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MON INVENTAIRE"> - <floater.string name="Title"> - MON INVENTAIRE - </floater.string> - <floater.string name="TitleFetching"> - MON INVENTAIRE (récupération de [ITEM_COUNT] articles en cours) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MON INVENTAIRE ([ITEM_COUNT] articles) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Récupéré - </floater.string> - <panel label="Panneau Inventaire" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_land_holdings.xml b/indra/newview/skins/default/xui/fr/floater_land_holdings.xml index 10fe132623..ff728e3aaa 100644 --- a/indra/newview/skins/default/xui/fr/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/fr/floater_land_holdings.xml @@ -7,7 +7,7 @@ <column label="Surface" name="area"/> <column label="" name="hidden"/> </scroll_list> - <button label="Téléporter" label_selected="Téléporter" name="Teleport" tool_tip="Téléportez-vous au milieu de ce terrain."/> + <button label="Téléportation" label_selected="Téléportation" name="Teleport" tool_tip="Téléportez-vous au milieu de ce terrain."/> <button label="Carte" label_selected="Carte" name="Show on Map" tool_tip="Afficher ce terrain sur la carte du monde"/> <text name="contrib_label"> Vos contributions : diff --git a/indra/newview/skins/default/xui/fr/floater_model_preview.xml b/indra/newview/skins/default/xui/fr/floater_model_preview.xml index 0f272891c7..bd3dae6599 100644 --- a/indra/newview/skins/default/xui/fr/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/fr/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="Triangles" name="triangles" value="Triangles"/> <text initial_value="Sommets" name="vertices" value="Sommets"/> <text initial_value="Élevé" name="high_label" value="Élevé"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + </combo_box> <button label="Parcourir..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Moyen" name="medium_label" value="Moyen"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + <item name="Use LoD above" value="Niveau de détail du dessus"/> + </combo_box> <button label="Parcourir..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Faible" name="low_label" value="Faible"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + <item name="Use LoD above" value="Niveau de détail du dessus"/> + </combo_box> <button label="Parcourir..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Le plus faible" name="lowest_label" value="Le plus faible"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Depuis un fichier"/> + <item name="Generate" value="Génération"/> + <item name="Use LoD above" value="Niveau de détail du dessus"/> + </combo_box> <button label="Parcourir..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Triangles max"/> + <item name="Error Threshold" value="Seuil d'erreur"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Génération de normales" name="gen_normals"/> @@ -166,7 +201,7 @@ Passes : </text> <text name="Detail Scale label"> - Échelle de détail : + Échelle détail : </text> <text name="Retain%_label"> Retenue : @@ -192,7 +227,7 @@ </panel> <panel label="Option de chargement" name="modifiers_panel"> <text name="scale_label"> - Echelle (1 = pas d'échelle) : + Échelle (1 = aucune) : </text> <spinner name="import_scale" value="1.0"/> <text name="dimensions_label"> @@ -203,12 +238,12 @@ </text> <check_box label="Inclure les textures" name="upload_textures"/> <text name="include_label"> - Pour les modèles d'avatar uniquement : + Modèles d'avatar uniquement : </text> - <check_box label="Inclure la pondération de la peau :" name="upload_skin"/> - <check_box label="Inclure la position des articulations :" name="upload_joints"/> + <check_box label="Inclure pondération de la peau :" name="upload_skin"/> + <check_box label="Inclure position des articulations :" name="upload_joints"/> <text name="pelvis_offset_label"> - Décalage Z (élever ou abaisser l'avatar) : + Décalage Z (élever/abaisser l'avatar) : </text> <spinner name="pelvis_offset" value="0.0"/> </panel> @@ -217,7 +252,7 @@ <button label="Calculer les poids et les frais" name="calculate_btn" tool_tip="Calculer les poids et les frais."/> <button label="Annuler" name="cancel_btn"/> <button label="Charger le modèle" name="ok_btn" tool_tip="Charger dans le simulateur"/> - <button label="Effacer les paramètres et réinitialiser le formulaire" name="reset_btn"/> + <button label="Effacer les paramètres / réinitialiser le formulaire" name="reset_btn"/> <text name="upload_fee"> Frais de chargement : [FEE] L$ </text> diff --git a/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml b/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml deleted file mode 100644 index 8bbd34baae..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT PRÈS DE MOI"> - <check_box label="Traduction du chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..7c9109c011 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personnages de recherche de chemin"> + <floater.string name="messaging_get_inprogress"> + Requête relative aux personnages de recherche de chemin en cours... + </floater.string> + <floater.string name="messaging_get_error"> + Erreur lors de la requête relative aux personnages de recherche de chemin. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Aucun personnage de recherche de chemin. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personnages sélectionnés sur [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Chargement] + </floater.string> + <floater.string name="character_owner_unknown"> + [Inconnu] + </floater.string> + <floater.string name="character_owner_group"> + [Groupe] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nom" name="name"/> + <scroll_list.columns label="Description" name="description"/> + <scroll_list.columns label="Propriétaire" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitude" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personnages : + </text> + <button label="Actualiser" name="refresh_objects_list"/> + <button label="Tout sélectionner" name="select_all_objects"/> + <button label="Ne rien sélectionner" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Actions sur les personnages sélectionnés : + </text> + <check_box label="Afficher la balise" name="show_beacon"/> + <check_box label="Afficher la capsule physique" name="show_physics_capsule"/> + <button label="Prendre" name="take_objects"/> + <button label="Prendre une copie" name="take_copy_objects"/> + <button label="M'y téléporter" name="teleport_me_to_object" tool_tip="Activé uniquement lorsqu'un personnage est sélectionné."/> + <button label="Renvoyer" name="return_objects"/> + <button label="Supprimer" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml new file mode 100644 index 0000000000..02d969dc08 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Vue/Test de recherche de chemin"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Implémentation de la bibliothèque de recherche de chemin introuvable + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + En attente de fin de chargement de la région. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Vérification de l'état du maillage de navigation. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Téléchargement du maillage de navigation. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Maillage de navigation modifié sur le serveur. Téléchargement du plus récent. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Le maillage de navigation le plus récent a été téléchargé. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Impossible de télécharger le maillage de navigation. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Des modifications sont en attente concernant le maillage de navigation. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Maillage de navigation en cours de création. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Des modifications sont en attente pour certaines régions de maillage de navigation. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Certaines régions de maillage de navigation sont en cours de création. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Des modifications sont en attente pour certaines régions de maillage de navigation et d'autres sont en cours de création. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Maillage de navigation à jour. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Implémentation de la bibliothèque de recherche de chemin introuvable + </floater.string> + <floater.string name="pathing_region_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Choisissez un point de départ et un point d'arrivée. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Choisissez un point de départ. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Choisissez un point d'arrivée. + </floater.string> + <floater.string name="pathing_path_valid"> + Le chemin s'affiche en orange. + </floater.string> + <floater.string name="pathing_path_invalid"> + Impossible de trouver un chemin entre les points choisis. + </floater.string> + <floater.string name="pathing_error"> + Erreur lors de la génération du chemin. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Vue" name="view_panel"> + <text name="show_label"> + Afficher : + </text> + <check_box label="Monde" name="show_world"/> + <check_box label="Mobiles uniquement" name="show_world_movables_only"/> + <check_box label="Maillage de navigation" name="show_navmesh"/> + <text name="show_walkability_label"> + Où marcher est possible : + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Ne pas afficher" name="show_heatmap_mode_none"/> + <combo_box.item label="Type de personnage A" name="show_heatmap_mode_a"/> + <combo_box.item label="Type de personnage B" name="show_heatmap_mode_b"/> + <combo_box.item label="Type de personnage C" name="show_heatmap_mode_c"/> + <combo_box.item label="Type de personnage D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Marche possible" name="show_walkables"/> + <check_box label="Volumes de matériau" name="show_material_volumes"/> + <check_box label="Obstacles statiques" name="show_static_obstacles"/> + <check_box label="Volumes d'exclusion" name="show_exclusion_volumes"/> + <check_box label="Plan de l'eau" name="show_water_plane"/> + <check_box label="Mode rayons X" name="show_xray"/> + </panel> + <panel label="Chemin test" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl-clic : sélection point de départ + </text> + <text name="shift_click_label"> + Maj-clic : sélection point d'arrivée + </text> + <text name="character_width_label"> + Largeur du personnage + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Type de personnage + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Aucun" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Effacer chemin" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..894ec6dd9c --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Groupes de liens de recherche de chemin"> + <floater.string name="messaging_get_inprogress"> + Requête relative aux groupes de liens de recherche de chemin en cours... + </floater.string> + <floater.string name="messaging_get_error"> + Erreur lors de la requête relative aux groupes de liens de recherche de chemin. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modification des groupes de liens de recherche de chemin sélectionnés... + </floater.string> + <floater.string name="messaging_set_error"> + Erreur lors de la modification des groupes de liens de recherche de chemin sélectionnés. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Aucun groupe de liens de recherche de chemin. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] groupes de liens sélectionnés sur [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + La recherche de chemin n'a pas été activée pour cette région. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Chargement] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Inconnu] + </floater.string> + <floater.string name="linkset_owner_group"> + [Groupe] + </floater.string> + <floater.string name="linkset_is_scripted"> + Oui + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Non + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Inconnu + </floater.string> + <floater.string name="linkset_use_walkable"> + Marche possible + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Obstacle statique + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Obstacle mobile + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volume de matériau + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volume d'exclusion + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Fantôme mobile + </floater.string> + <floater.string name="linkset_is_terrain"> + [Non modifiable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [Restriction] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [Concave] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [Restriction,Concave] + </floater.string> + <floater.string name="linkset_choose_use"> + Choisir un usage de groupe de liens... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtrer par usage..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Marche possible" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Obstacle statique" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Obstacle mobile" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volume de matériau" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volume d'exclusion" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Fantôme mobile" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Appliquer" name="apply_filters"/> + <button label="Effacer" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nom (prim racine)" name="name"/> + <scroll_list.columns label="Description (prim racine)" name="description"/> + <scroll_list.columns label="Propriétaire" name="owner"/> + <scroll_list.columns label="Scripté" name="scripted"/> + <scroll_list.columns label="Impact" name="land_impact"/> + <scroll_list.columns label="Distance" name="dist_from_you"/> + <scroll_list.columns label="Usage du groupe de liens" name="linkset_use"/> + <scroll_list.columns label="% A" name="a_percent"/> + <scroll_list.columns label="% B" name="b_percent"/> + <scroll_list.columns label="% C" name="c_percent"/> + <scroll_list.columns label="% D" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Groupes de liens : + </text> + <button label="Actualiser" name="refresh_objects_list"/> + <button label="Tout sélectionner" name="select_all_objects"/> + <button label="Ne rien sélectionner" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Afficher la balise" name="show_beacon"/> + <button label="Prendre" name="take_objects"/> + <button label="Prendre une copie" name="take_copy_objects"/> + <button label="M'y téléporter" name="teleport_me_to_object"/> + <button label="Renvoyer" name="return_objects"/> + <button label="Supprimer" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Marche possible : + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Marche possible pour les personnages de type A. Exemple de type de personnage : humanoïde."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Marche possible pour les personnages de type B. Exemple de type de personnage : créature."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Marche possible pour les personnages de type C. Exemple de type de personnage : mécanique."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Marche possible pour les personnages de type D. Exemple de type de personnage : autre."/> + <button label="Appliquer les changements" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoïde) + </text> + <text name="suggested_use_b_label"> + (Créature) + </text> + <text name="suggested_use_c_label"> + (Mécanique) + </text> + <text name="suggested_use_d_label"> + (Autre) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_postcard.xml b/indra/newview/skins/default/xui/fr/floater_postcard.xml deleted file mode 100644 index e65dfb09b4..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_postcard.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ENVOYER LA PHOTO PAR E-MAIL"> - <text name="to_label"> - E-mail du destinataire : - </text> - <text name="from_label"> - Votre e-mail : - </text> - <text name="name_label"> - Votre nom : - </text> - <text name="subject_label"> - Objet : - </text> - <line_editor label="Saisir ici votre objet" name="subject_form"/> - <text name="msg_label"> - Message : - </text> - <text_editor name="msg_form"> - Saisir ici votre message - </text_editor> - <text name="fine_print"> - Si le destinataire s'inscrit sur [SECOND_LIFE], vous recevrez un bonus. - </text> - <button label="Annuler" name="cancel_btn"/> - <button label="Envoyer" name="send_btn"/> - <string name="default_subject"> - Carte postale de [SECOND_LIFE]. - </string> - <string name="default_message"> - Ouvrez-moi ! - </string> - <string name="upload_message"> - Envoi en cours... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml index f2cb1d5e70..6488089c06 100644 --- a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Description : </text> - <button label="Exécuter dans Second Life" label_selected="Arrêter" name="Inworld" tool_tip="Lire cette animation de façon à ce que les autres la voient."/> + <button label="Exécuter dans SL" label_selected="Arrêter" name="Inworld" tool_tip="Lire cette animation de façon à ce que les autres la voient dans Second Life."/> <button label="Exécuter localement" label_selected="Arrêter" name="Locally" tool_tip="Lire cette animation de façon à ce que vous soyez la seule personne à la voir."/> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_spellcheck.xml b/indra/newview/skins/default/xui/fr/floater_spellcheck.xml new file mode 100644 index 0000000000..635db52ffa --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Paramètres du vérificateur orthographique"> + <check_box label="Activer le vérificateur orthographique" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Diction. principal : + </text> + <text label="Journaux :" name="spellcheck_additional"> + Dictionnaires supplémentaires : + </text> + <text name="spellcheck_available"> + Disponibles + </text> + <text name="spellcheck_active"> + Actifs + </text> + <button label="Supprimer" name="spellcheck_remove_btn"/> + <button label="Importer..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml new file mode 100644 index 0000000000..c8c76c672d --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Importation d'un dictionnaire"> + <button label="Parcourir" label_selected="Parcourir" name="dictionary_path_browse"/> + <button label="Importer" name="ok_btn"/> + <button label="Annuler" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_stats.xml b/indra/newview/skins/default/xui/fr/floater_stats.xml index 56fa062d46..d6bd187956 100644 --- a/indra/newview/skins/default/xui/fr/floater_stats.xml +++ b/indra/newview/skins/default/xui/fr/floater_stats.xml @@ -53,7 +53,13 @@ <stat_bar label="Objets" name="simobjects"/> <stat_bar label="Objets actifs" name="simactiveobjects"/> <stat_bar label="Scripts actifs" name="simactivescripts"/> + <stat_bar label="Scripts exécutés" name="simpctscriptsrun"/> <stat_bar label="Événements de scripts" name="simscripteps"/> + <stat_view label="Recherche de chemin" name="simpathfinding"> + <stat_bar label="Durée de l'étape IA" name="simsimaistepmsec"/> + <stat_bar label="Étapes de silhouette ignorées" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personnages mis à jour" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="Paquets en entrée" name="siminpps"/> <stat_bar label="Paquets en sortie" name="simoutpps"/> <stat_bar label="Téléchargements en attente" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml index ca0fbd3589..f86c1a4217 100644 --- a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml @@ -20,6 +20,8 @@ <button label="Vierge" label_selected="Vierge" name="Blank" width="60"/> <button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/> <button bottom="-240" label="" label_selected="" name="Pipette"/> + <check_box initial_value="true" label="Aperçu direct" name="apply_immediate_check"/> + <text name="preview_disabled" value="Aperçu désactivé"/> <filter_editor label="Filtrer les textures" name="inventory search editor"/> <check_box initial_value="false" label="Afficher les dossiers" name="show_folders_check"/> <button label="Ajouter" label_selected="Ajouter" name="l_add_btn"/> @@ -31,5 +33,4 @@ </scroll_list> <button label="OK" label_selected="OK" name="Select"/> <button label="Annuler" label_selected="Annuler" name="Cancel"/> - <check_box initial_value="true" label="Appliquer maintenant" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml index f0cc95319d..caae15ea17 100644 --- a/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, nouvelle récupération des données visibles du cache, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels </text> + <text name="total_time_refetch_all_cache_label"> + 16, nouvelle récupération de toutes les textures du cache, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + </text> <text name="total_time_refetch_vis_http_label"> - 16, nouvelle récupération des données visibles de la requête HTTP, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + 17, nouvelle récupération des données visibles de la requête HTTP, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + </text> + <text name="total_time_refetch_all_http_label"> + 18, nouvelle récupération de toutes les textures de la requête HTTP, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels + </text> + <spinner label="19, taux de texels/pixels :" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, source des textures : </text> - <spinner label="17, taux de texels/pixels :" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="HTTP uniquement" name="1"/> + </radio_group> <button label="Démarrer" name="start_btn"/> <button label="Réinitialiser" name="clear_btn"/> <button label="Fermer" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="Décoder" name="decode_btn"/> <button label="Texture GL" name="gl_btn"/> <button label="Récupérer à nouveau les données visibles du cache" name="refetchviscache_btn"/> + <button label="Récupérer cache" name="refetchallcache_btn"/> <button label="Récupérer à nouveau les données visibles de la requête HTTP" name="refetchvishttp_btn"/> + <button label="Récupérer HTTP" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml index e21c6f4c08..bcc3423862 100644 --- a/indra/newview/skins/default/xui/fr/floater_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_tools.xml @@ -99,7 +99,7 @@ <button label="" label_selected="" name="ToolRing" tool_tip="Anneau"/> <button label="" label_selected="" name="ToolTree" tool_tip="Arbre"/> <button label="" label_selected="" name="ToolGrass" tool_tip="Herbe"/> - <check_box label="Maintenir l'outil sélectionné" name="checkbox sticky"/> + <check_box label="Maintenir l'outil sélect." name="checkbox sticky"/> <check_box label="Copier la sélection" name="checkbox copy selection"/> <check_box initial_value="true" label="Centrer" name="checkbox copy centers"/> <check_box label="Pivoter" name="checkbox copy rotates"/> @@ -148,6 +148,12 @@ <panel.string name="text modify info 4"> Vous ne pouvez pas modifier ces objets </panel.string> + <panel.string name="text modify info 5"> + Impossible de modifier cet objet au-delà de la frontière d'une région + </panel.string> + <panel.string name="text modify info 6"> + Impossible de modifier ces objets au-delà de la frontière d'une région + </panel.string> <panel.string name="text modify warning"> Sélectionnez l'objet en entier </panel.string> @@ -197,12 +203,12 @@ <combo_box.item label="Zoomer" name="Zoom"/> </combo_box> <check_box label="À vendre :" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Copie" name="Copy"/> <combo_box.item label="Contenus" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Prix : L$" name="Edit Cost"/> <check_box label="Afficher dans la recherche" name="search_check" tool_tip="Afficher l'objet dans les résultats de recherche"/> <panel name="perms_build"> <text name="perm_modify"> @@ -238,6 +244,11 @@ F : </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Attributs de recherche de chemin : + </text> + </panel> </panel> <panel label="Objet" name="Object"> <check_box label="Verrouillé" name="checkbox locked" tool_tip="Empêche l'objet d'être déplacé ou supprimé. Utile pendant la construction pour éviter les modifications involontaires."/> diff --git a/indra/newview/skins/default/xui/fr/floater_top_objects.xml b/indra/newview/skins/default/xui/fr/floater_top_objects.xml index 42352e7c1e..eb084d9184 100644 --- a/indra/newview/skins/default/xui/fr/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/fr/floater_top_objects.xml @@ -1,16 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="top_objects" title="Objets les plus utilisés"> +<floater name="top_objects" title="Objets les plus consommateurs"> <floater.string name="top_scripts_title"> - Scripts principaux + Scripts les plus consommateurs </floater.string> <floater.string name="top_scripts_text"> [COUNT] scripts prenant un total de [TIME] ms </floater.string> <floater.string name="scripts_score_label"> - Heure - </floater.string> - <floater.string name="scripts_mono_time_label"> - Heure Mono + Temps </floater.string> <floater.string name="top_colliders_title"> Collisions les plus consommatrices @@ -32,9 +29,10 @@ <scroll_list.columns label="Nom" name="name"/> <scroll_list.columns label="Propriétaire" name="owner"/> <scroll_list.columns label="Lieu" name="location"/> - <scroll_list.columns label="Heure" name="time"/> - <scroll_list.columns label="Heure Mono" name="mono_time"/> + <scroll_list.columns label="Parcelle" name="parcel"/> + <scroll_list.columns label="Temps" name="time"/> <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="Mémoire (Ko)" name="memory"/> </scroll_list> <text name="id_text"> ID de l'objet : @@ -43,11 +41,15 @@ <text name="obj_name_text"> Nom : </text> - <button label="Filtre" name="filter_object_btn"/> + <button label="Filtrer" name="filter_object_btn"/> <text name="owner_name_text"> Propriétaire : </text> - <button label="Filtre" name="filter_owner_btn"/> + <button label="Filtrer" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parcelle : + </text> + <button label="Filtrer" name="filter_parcel_btn"/> <button label="Rafraîchir" name="refresh_btn"/> <button label="Renvoyer" name="return_selected_btn"/> <button label="Tout renvoyer" name="return_all_btn"/> diff --git a/indra/newview/skins/default/xui/fr/menu_bottomtray.xml b/indra/newview/skins/default/xui/fr/menu_bottomtray.xml deleted file mode 100644 index d0d245b286..0000000000 --- a/indra/newview/skins/default/xui/fr/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Bouton Parler" name="EnableVoiceChat"/> - <menu_item_check label="Bouton Geste" name="ShowGestureButton"/> - <menu_item_check label="Bouton Bouger" name="ShowMoveButton"/> - <menu_item_check label="Bouton Affichage" name="ShowCameraButton"/> - <menu_item_check label="Bouton Photo" name="ShowSnapshotButton"/> - <menu_item_check label="Bouton Construire" name="ShowBuildButton"/> - <menu_item_check label="Bouton Rechercher" name="ShowSearchButton"/> - <menu_item_check label="Bouton Carte" name="ShowWorldMapButton"/> - <menu_item_check label="Bouton Mini-carte" name="ShowMiniMapButton"/> - <menu_item_call label="Couper" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copier" name="NearbyChatBar_Copy"/> - <menu_item_call label="Coller" name="NearbyChatBar_Paste"/> - <menu_item_call label="Supprimer" name="NearbyChatBar_Delete"/> - <menu_item_call label="Tout sélectionner" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/fr/menu_inventory.xml b/indra/newview/skins/default/xui/fr/menu_inventory.xml index 59dcff9075..627d3068c3 100644 --- a/indra/newview/skins/default/xui/fr/menu_inventory.xml +++ b/indra/newview/skins/default/xui/fr/menu_inventory.xml @@ -68,6 +68,7 @@ <menu_item_call label="Supprimer le dossier système" name="Delete System Folder"/> <menu_item_call label="Démarrer le chat conférence" name="Conference Chat Folder"/> <menu_item_call label="Jouer" name="Sound Play"/> + <menu_item_call label="Copier la SLurl" name="url_copy"/> <menu_item_call label="À propos du repère" name="About Landmark"/> <menu_item_call label="Jouer dans Second Life" name="Animation Play"/> <menu_item_call label="Jouer localement" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/fr/menu_mode_change.xml b/indra/newview/skins/default/xui/fr/menu_mode_change.xml deleted file mode 100644 index 982a331c5b..0000000000 --- a/indra/newview/skins/default/xui/fr/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Basique" name="BasicMode"/> - <menu_item_check label="Avancé" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/fr/menu_object.xml b/indra/newview/skins/default/xui/fr/menu_object.xml index c6db48a31c..573b6da582 100644 --- a/indra/newview/skins/default/xui/fr/menu_object.xml +++ b/indra/newview/skins/default/xui/fr/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Modifier" name="Edit..."/> <menu_item_call label="Construire" name="Build"/> + <menu_item_call label="Voir parmi les groupes de liens" name="show_in_linksets"/> + <menu_item_call label="Voir parmi les personnages" name="show_in_characters"/> <menu_item_call label="Ouvrir" name="Open"/> <menu_item_call label="M'asseoir ici" name="Object Sit"/> <menu_item_call label="Me lever" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/fr/menu_text_editor.xml b/indra/newview/skins/default/xui/fr/menu_text_editor.xml index b6f429aec9..c31b0c8556 100644 --- a/indra/newview/skins/default/xui/fr/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/fr/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(inconnu)" name="Suggestion 1"/> + <menu_item_call label="(inconnu)" name="Suggestion 2"/> + <menu_item_call label="(inconnu)" name="Suggestion 3"/> + <menu_item_call label="(inconnu)" name="Suggestion 4"/> + <menu_item_call label="(inconnu)" name="Suggestion 5"/> + <menu_item_call label="Ajouter au dictionnaire" name="Add to Dictionary"/> + <menu_item_call label="Ajouter aux éléments à ignorer" name="Add to Ignore"/> <menu_item_call label="Couper" name="Cut"/> <menu_item_call label="Copier" name="Copy"/> <menu_item_call label="Coller" name="Paste"/> diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 2a26ed7a70..85020afe25 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -8,7 +8,7 @@ <menu_item_call label="Nouvelle fenêtre d'inventaire" name="NewInventoryWindow"/> <menu_item_call label="Endroits..." name="Places"/> <menu_item_call label="Favoris..." name="Picks"/> - <menu_item_call label="Paramètres de la caméra..." name="Camera Controls"/> + <menu_item_call label="Contrôles de la caméra..." name="Camera Controls"/> <menu label="Déplacement" name="Movement"> <menu_item_call label="M'asseoir" name="Sit Down Here"/> <menu_item_check label="Voler" name="Fly"/> @@ -28,6 +28,7 @@ <menu_item_call label="Préférences..." name="Preferences"/> <menu_item_call label="Boutons des barres d'outils..." name="Toolbars"/> <menu_item_call label="Masquer tous les contrôles" name="Hide UI"/> + <menu_item_check label="Afficher les éléments HUD" name="Show HUD Attachments"/> <menu_item_call label="Quitter [APP_NAME]" name="Quit"/> </menu> <menu label="Communiquer" name="Communicate"> @@ -39,6 +40,7 @@ <menu_item_call label="Amis" name="My Friends"/> <menu_item_call label="Groupes" name="My Groups"/> <menu_item_call label="Personnes près de vous" name="Active Speakers"/> + <menu_item_call label="Liste des ignorés" name="Block List"/> </menu> <menu label="Monde" name="World"> <menu_item_call label="Créer un repère pour ce lieu" name="Create Landmark Here"/> @@ -124,6 +126,11 @@ <menu_item_call label="Définir les scripts sur Exécution" name="Set Scripts to Running"/> <menu_item_call label="Définir les scripts sur Pas d'exécution" name="Set Scripts to Not Running"/> </menu> + <menu label="Recherche de chemin" name="Pathfinding"> + <menu_item_call label="Groupes de liens..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personnages..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Vue / test..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Options" name="Options"> <menu_item_check label="Afficher les droits avancés" name="DebugPermissions"/> <menu_item_check label="Sélectionner mes objets uniquement" name="Select Only My Objects"/> @@ -171,10 +178,9 @@ </menu> <menu label="Surbrillance et visibilité" name="Highlighting and Visibility"> <menu_item_check label="Balise animée" name="Cheesy Beacon"/> - <menu_item_check label="Cacher les particules" name="Hide Particles"/> + <menu_item_check label="Masquer les particules" name="Hide Particles"/> <menu_item_check label="Masquer la sélection" name="Hide Selected"/> <menu_item_check label="Mettre la transparence en surbrillance" name="Highlight Transparent"/> - <menu_item_check label="Afficher les éléments HUD" name="Show HUD Attachments"/> <menu_item_check label="Afficher le réticule de la vue subjective" name="ShowCrosshairs"/> </menu> <menu label="Types de rendu" name="Rendering Types"> @@ -377,7 +383,6 @@ <menu_item_call label="Basculer la géométrie des personnages" name="Toggle Character Geometry"/> <menu_item_call label="Test homme" name="Test Male"/> <menu_item_call label="Test femme" name="Test Female"/> - <menu_item_call label="Activer/désactiver PG" name="Toggle PG"/> <menu_item_check label="Autoriser la sélection de l'avatar" name="Allow Select Avatar"/> </menu> <menu_item_call label="Forcer les paramètres par défaut" name="Force Params to Default"/> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 0cdfc61e8e..30154d1873 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -359,13 +365,19 @@ Vous devez saisir le nom d'utilisateur de votre avatar. Pour entrer dans [SECOND_LIFE], vous devez disposer d'un compte. Voulez-vous en créer un maintenant ? <url name="url"> - https://join.secondlife.com/index.php?lang=fr-FR + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Réessayer" yestext="Créer un compte"/> </notification> <notification name="InvalidCredentialFormat"> Saisissez soit le nom d'utilisateur soit à la fois le prénom et le nom de votre avatar dans le champ Nom d'utilisateur, puis connectez-vous. </notification> + <notification name="InvalidGrid"> + [GRID] n'est pas un identifiant de grille valide. + </notification> + <notification name="InvalidLocationSLURL"> + Grille non valide spécifiée au niveau du lieu de départ. + </notification> <notification name="DeleteClassified"> Supprimer l'annonce [NAME] ? Une fois payés, les frais ne sont pas remboursables. @@ -472,7 +484,7 @@ L'objet est peut-être inaccessible ou a peut-être été supprimé. </notification> <notification name="StartRegionEmpty"> Vous n'avez pas défini de région de départ. -Veuillez saisir le nom de la région dans la case Lieu de départ, ou choisissez Dernier emplacement ou Domicile comme Lieu de départ. +Saisissez le nom de la région voulue dans la case Lieu de départ ou choisissez Dernier emplacement ou Domicile comme lieu de départ. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -599,6 +611,9 @@ Vous pouvez lier un maximum de [MAX] objets. Assurez-vous que vous êtes le propriétaire de tous les objets et qu'aucun d'eux n'est verrouillé. </notification> + <notification name="CannotLinkPermanent"> + Impossible de lier des objets d'une région à une autre. + </notification> <notification name="CannotLinkDifferentOwners"> Impossible de lier car les objets n'ont pas tous le même propriétaire. @@ -979,6 +994,41 @@ Proposer à [NAME] de devenir votre ami(e) ? <button name="Cancel" text="Annuler"/> </form> </notification> + <notification label="Ajouter une liste Rechercher/Remplacer" name="AddAutoReplaceList"> + Nom de la nouvelle liste : + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Renommer la liste Rechercher/Remplacer" name="RenameAutoReplaceList"> + Le nom [DUPNAME] est déjà utilisé. + Saisissez un nouveau nom unique : + <form name="form"> + <button name="ReplaceList" text="Remplacer la liste actuelle"/> + <button name="SetName" text="Utiliser le nouveau nom"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Le mot-clé doit être constitué d'un seul mot et sa valeur de remplacement doit être renseignée. + </notification> + <notification name="InvalidAutoReplaceList"> + Liste de remplacement non valide. + </notification> + <notification name="SpellingDictImportRequired"> + Spécifiez un fichier, un nom et une langue. + </notification> + <notification name="SpellingDictIsSecondary"> + Le dictionnaire [DIC_NAME] ne semble pas contenir de fichier "aff" ; il s'agit donc d'un dictionnaire « secondaire ». +Vous pouvez l'utiliser comme dictionnaire supplémentaire mais pas comme dictionnaire principal. + +Voir https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Impossible de copier + [FROM_NAME] + vers + [TO_NAME] + </notification> <notification label="Enregistrer la tenue" name="SaveOutfitAs"> Enregistrer ce que je porte comme nouvelle tenue : <form name="form"> @@ -1152,7 +1202,7 @@ par une carte [THIS_GPU]. Vous avez été téléporté vers une région voisine. </notification> <notification name="AvatarMovedLast"> - Votre dernière destination n'est pas disponible actuellement. + La destination demandée n'est pas disponible actuellement. Vous avez été téléporté vers une région voisine. </notification> <notification name="AvatarMovedHome"> @@ -1171,8 +1221,7 @@ Vous pouvez utiliser [SECOND_LIFE] normalement, les autres résidents vous voien L'installation de [APP_NAME] est terminée. Si vous utilisez [SECOND_LIFE] pour la première fois, vous devez ouvrir un compte avant de pouvoir vous connecter. -Retourner sur [http://join.secondlife.com secondlife.com] pour ouvrir un nouveau compte ? - <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Nouveau compte..."/> + <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Créer un compte..."/> </notification> <notification name="LoginPacketNeverReceived"> Nous avons des difficultés à vous connecter. Il y a peut-être un problème avec votre connexion Internet ou la [SECOND_LIFE_GRID]. @@ -1314,7 +1363,7 @@ Dépasse la limite fixée à [MAX_AGENTS] [LIST_TYPE] de [NUM_EXCESS]. Veuillez choisir un objet à vendre et réessayer. </notification> <notification name="FinishedRawDownload"> - Chargement du fichier de terrain raw effectué vers : + Téléchargement du fichier de terrain raw effectué vers : [DOWNLOAD_PATH]. </notification> <notification name="DownloadWindowsMandatory"> @@ -1693,83 +1742,128 @@ Cette action modifiera des milliers de régions et sera difficile à digérer po <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Votre catégorie d'accès ne vous autorise pas à pénétrer dans cette région. Cela vient peut-être du fait qu'il manquait des informations pour valider votre âge. - -Vérifiez que vous avez la toute dernière version du client et consultez les pages d'aide pour savoir comment accéder aux zones ayant ce niveau d'accès. + La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Votre catégorie d'accès ne vous permet pas de pénétrer dans cette région. - -Souhaitez-vous en savoir plus sur les différentes catégories d'accès ? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 </url> - <usetemplate ignoretext="Je ne peux pas pénétrer dans cette région car je n'ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d'aide"/> + <usetemplate ignoretext="Passage à une autre région : la région que vous essayez de visiter comporte du contenu uniquement accessible aux adultes." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Votre catégorie d'accès ne vous permet pas de pénétrer dans cette région. + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. </notification> <notification name="RegionEntryAccessBlocked_Change"> - La catégorie de contenu définie dans vos préférences ne vous permet pas de pénétrer dans cette région. - -Pour cela, vous devez modifier votre paramètre de catégorie de contenu. Vous pourrez alors rechercher du contenu [REGIONMATURITY] et y accéder. Pour annuler vos modifications, accédez à Moi > Préférences > Général. + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences ou d'annuler l'action. Une fois vos préférences modifiées, vous pouvez réessayer d'accéder à la région. <form name="form"> <button name="OK" text="Modifier les préférences"/> - <button default="true" name="Cancel" text="Fermer"/> - <ignore name="ignore" text="La catégorie de contenu que j'ai choisie m'empêche de pénétrer dans une région"/> + <button default="true" name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Passage à une autre région : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences actuelles."/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Nous rencontrons des difficultés techniques au niveau de votre téléportation car vos préférences ne sont pas synchronisées avec le serveur. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. + <url name="url"> + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 + </url> + <usetemplate ignoretext="Téléportation : la région que vous essayez de visiter comporte du contenu uniquement accessible aux adultes." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences afin de poursuivre la téléportation ou d'annuler la téléportation. + <form name="form"> + <button name="OK" text="Modifier et continuer"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Téléportation (redémarrage possible) : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences ou d'annuler la téléportation. Une fois vos préférences modifiées, vous devrez réessayer de vous téléporter. + <form name="form"> + <button name="OK" text="Modifier les préférences"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Téléportation (redémarrage impossible) : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Nous rencontrons des difficultés techniques au niveau de votre téléportation car vos préférences ne sont pas synchronisées avec le serveur. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Votre préférence de catégorie de contenu est désormais [RATING]. + Aucune autre notification vous informant que vous allez visiter une région au contenu [RATING] ne vous sera envoyée. Vous pouvez modifier vos préférences de contenu à l'avenir en accédant à Moi > Préférences > Général, à partir de la barre de menus. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Impossible de modifier vos préférences afin d'afficher le contenu [PREFERRED_MATURITY] à l'heure actuelle. Le paramètre [ACTUAL_MATURITY] a été rétabli. Vous pouvez réessayer de modifier vos préférences en accédant à Moi > Préférences > Général, à partir de la barre de menus. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Votre catégorie d'accès ne vous permet pas de réclamer cette région. Cela vient peut-être du fait qu'il manquait des informations pour valider votre âge. - -Vérifiez que vous avez la toute dernière version du client et consultez les pages d'aide pour savoir comment accéder aux zones ayant ce niveau d'accès. + Le niveau de contenu du terrain que vous essayez de revendiquer dépasse celui défini dans vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Votre catégorie d'accès ne vous permet pas de réclamer cette région. - -Souhaitez-vous en savoir plus sur les différentes catégories d'accès ? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Seuls les adultes sont autorisés à revendiquer ce terrain. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 </url> - <usetemplate ignoretext="Je ne peux pas réclamer cette région car je n'ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d'aide"/> + <usetemplate ignoretext="Seuls les adultes sont autorisés à revendiquer ce terrain." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Votre catégorie d'accès ne vous autorise pas à réclamer cette région. + Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. </notification> <notification name="LandClaimAccessBlocked_Change"> - Votre catégorie d'accès ne vous permet pas de réclamer cette région. - -En cliquant sur Modifier les préférences, vous pourrez changer votre catégorie d'accès et pénétrer dans la région. À partir de maintenant, vous pouvez rechercher et accéder au contenu [REGIONMATURITY]. Vous pouvez modifier ce paramètre à partir du menu Moi > Préférences > Général. - <usetemplate ignoretext="La catégorie de contenu que j'ai choisie m'empêche de réclamer un terrain" name="okcancelignore" notext="Fermer" yestext="Modifier les Préférences"/> + Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences, puis d'essayer de revendiquer ce terrain à nouveau. + <form name="form"> + <button name="OK" text="Modifier les préférences"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Le terrain que vous essayez de revendiquer comporte du contenu dont le niveau est exclu de vos préférences."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Votre catégorie d'accès ne vous permet pas d'acheter cette région. Cela vient peut-être du fait qu'il manquait des informations pour valider votre âge. - -Vérifiez que vous avez la toute dernière version du client et consultez les pages d'aide pour savoir comment accéder aux zones ayant ce niveau d'accès. + Le niveau de contenu du terrain que vous essayez d'acheter dépasse celui défini dans vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Votre catégorie d'accès ne vous permet pas d'acheter cette région. - -Souhaitez-vous en savoir plus sur les différentes catégories d'accès ? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Seuls les adultes sont autorisés à acheter ce terrain. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr + http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311 </url> - <usetemplate ignoretext="Je ne peux pas acheter ce terrain car je n'ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d'aide"/> + <usetemplate ignoretext="Seuls les adultes sont autorisés à acheter ce terrain." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Votre catégorie d'accès ne vous permet pas d'acheter cette région. + Le terrain que vous essayez d'acheter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Le terrain que vous essayez d'acheter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes. </notification> <notification name="LandBuyAccessBlocked_Change"> - Votre catégorie d'accès ne vous autorise pas à acheter cette région. - -En cliquant sur Modifier les préférences, vous pourrez changer votre catégorie d'accès et pénétrer dans la région. À partir de maintenant, vous pouvez rechercher et accéder au contenu [REGIONMATURITY]. Vous pouvez modifier ce paramètre à partir du menu Moi > Préférences > Général. - <usetemplate ignoretext="La catégorie de contenu que j'ai choisie m'empêche d'acheter un terrain" name="okcancelignore" notext="Fermer" yestext="Modifier les Préférences"/> + Le terrain que vous essayez d'acheter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences, puis d'essayer d'acheter ce terrain à nouveau. + <form name="form"> + <button name="OK" text="Modifier les préférences"/> + <button name="Cancel" text="Annuler"/> + <ignore name="ignore" text="Le terrain que vous essayez d'acheter comporte du contenu dont le niveau est exclu de vos préférences."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Vous avez sélectionné trop de prims. Veuillez sélectionner au maximum [MAX_PRIM_COUNT] prims et réessayer. @@ -1824,10 +1918,9 @@ Publier cette petite annonce maintenant pour [AMOUNT] L$ ? </form> </notification> <notification label="Catégorie de la région modifiée" name="RegionMaturityChange"> - Le niveau de maturité de cette région a été mis à jour. -Ce changement n'apparaîtra pas immédiatement sur la carte. - -Pour entrer dans les régions Adultes, le résident doit avoir vérifié son compte, que ce soit par vérification de l'âge ou du mode de paiement. + Le niveau de contenu de cette région a changé. +Il se peut que l'affichage de cette modification sur la carte prenne quelque temps. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Versions de voix non compatibles" name="VoiceVersionMismatch"> Cette version de [APP_NAME] n'est pas compatible avec la fonctionnalité de chat vocal dans cette région. Vous devez mettre à jour [APP_NAME] pour que le chat vocal fonctionne correctement. @@ -2117,14 +2210,11 @@ Liez-la à partir d'une page web pour permettre aux autres résidents d&apo <usetemplate ignoretext="Porter automatiquement tout en modifiant mon apparence" name="okcancelignore" notext="Non" yestext="Oui"/> </notification> <notification name="NotAgeVerified"> - Vous devez avoir au moins 18 ans pour accéder au contenu et aux zones Adulte dans Second Life. Visitez la page de vérification de l'âge afin de confirmer que vous avez plus de 18 ans. -Cette opération lancera votre navigateur Web. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Je n'ai pas procédé à la vérification de mon âge" name="okcancelignore" notext="Annuler" yestext="Accéder à la page de vérification de l'âge"/> + L'accès à l'endroit que vous essayez de visiter est limité aux résidents de plus de 18 ans. + <usetemplate ignoretext="Je n'ai pas l'âge requis pour visiter les zones d'accès limité en fonction de l'âge." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + L'accès à cet endroit est limité aux plus de 18 ans. </notification> <notification name="Cannot enter parcel: no payment info on file"> Pour pouvoir pénétrer dans cette zone, vous devez avoir enregistré vos informations de paiement. Souhaitez-vous aller sur [SECOND_LIFE] et enregistrer vos informations de paiement ? @@ -2386,6 +2476,23 @@ Vous ne pouvez pas voler ici. <notification name="NoBuild"> La construction est interdite dans cette zone. Vous ne pouvez pas construite ou rezzer d'objets ici. </notification> + <notification name="PathfindingDirty"> + Des modifications de recherche de chemin sont en attente concernant cette région. Si vous disposez de droits de construction, vous pouvez la figer de nouveau en cliquant sur le bouton Refiger la région. + </notification> + <notification name="DynamicPathfindingDisabled"> + La recherche de chemin dynamique n'est pas activée dans cette région. Il se peut que les objets scriptés utilisant des appels LSL de recherche de chemin ne fonctionnent pas comme prévu pour cette région. + </notification> + <notification name="PathfindingRebakeNavmesh"> + La modification de certains objets de cette région risque d'entraîner un comportement incorrect des autres objets mobiles. Pour que les objets mobiles se comportent correctement, cliquez sur Refiger la région. Pour plus d'informations, choisissez Aide. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Aide" ignoretext="La modification de certains objets de cette région risque d'entraîner un comportement incorrect des autres objets mobiles." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Une erreur est survenue. Un problème réseau ou serveur s'est peut-être produit ou vous ne disposez pas de droits de construction. Se déconnecter puis se reconnecter permet parfois de résoudre le problème. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Cette parcelle masque les avatars et le chat écrit des autres parcelles. Vous ne pouvez pas voir les résidents qui se trouvent en dehors, et ceux qui se trouvent en dehors ne peuvent pas vous voir. Le chat écrit habituel sur le canal 0 est également bloqué. </notification> @@ -2404,9 +2511,7 @@ Aucun script ne marche ici à part ceux du propriétaire du terrain. Vous ne pouvez réclamer qu'un terrain public dans la région où vous vous trouvez actuellement. </notification> <notification name="RegionTPAccessBlocked"> - Votre catégorie d'accès ne vous autorise pas à pénétrer dans cette région. Vous devez sans doute procéder à la vérification de votre âge ou installer une version plus récente du client. - -Pour savoir comment accéder aux zones ayant un tel niveau d'accès, veuillez consulter les pages d'aide. + La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi > Préférences > Général. </notification> <notification name="URBannedFromRegion"> Vous avez été banni de cette région. @@ -2417,11 +2522,11 @@ Pour savoir comment accéder aux zones ayant un tel niveau d'accès, veuill <notification name="ImproperPaymentStatus"> Vous n'avez pas le statut de paiement approprié pour pénétrer dans cette région. </notification> - <notification name="MustGetAgeRgion"> - Pour pouvoir pénétrer dans cette région, vous devez avoir procédé à la vérification de votre âge. + <notification name="MustGetAgeRegion"> + Pour accéder à cette région, vous devez avoir au moins 18 ans. </notification> <notification name="MustGetAgeParcel"> - Pour pouvoir pénétrer sur cette parcelle, vous devez avoir procédé à la vérification de votre âge. + Pour accéder à cette parcelle, vous devez avoir au moins 18 ans. </notification> <notification name="NoDestRegion"> Région de destination introuvable. @@ -2523,12 +2628,33 @@ Veuillez réessayer dans quelques minutes. <notification name="TeleportOffered"> [NAME_SLURL] propose de vous téléporter à son emplacement : -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +« [MESSAGE] » +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Téléporter"/> <button name="Cancel" text="Annuler"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] propose de vous téléporter à son emplacement : + +« [MESSAGE] » +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Cette région comporte du contenu [REGION_CONTENT_MATURITY] alors que vos préférences actuelles excluent tout contenu [REGION_CONTENT_MATURITY]. Il est possible de modifier vos préférences afin de poursuivre la téléportation ou d'annuler la téléportation. + <form name="form"> + <button name="Teleport" text="Modifier et continuer"/> + <button name="Cancel" text="Annuler"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] propose de vous téléporter à son emplacement : + +« [MESSAGE] » +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Toutefois, cette région comporte du contenu uniquement accessible aux adultes. + </notification> <notification name="TeleportOfferSent"> Offre de téléportation envoyée à [TO_NAME] </notification> @@ -2932,6 +3058,10 @@ Texture figée de [RESOLUTION] chargée pour [BODYREGION] au bout de [TIME] seco ([EXISTENCE] secondes d'existence) Texture figée de [RESOLUTION] mise à jour localement pour [BODYREGION] au bout de [TIME] secondes. </notification> + <notification name="LivePreviewUnavailable"> + Impossible d'afficher un aperçu de cette texture car il s'agit d'une texture sans copie et/ou transfert. + <usetemplate ignoretext="M'avertir que le mode Aperçu en direct n'est pas disponible pour les textures sans copie et/ou transfert" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Voulez-vous vraiment quitter cet appel ? <usetemplate ignoretext="Confirmer avant de quitter l'appel" name="okcancelignore" notext="Non" yestext="Oui"/> @@ -3103,6 +3233,62 @@ Cliquez sur un point dans le monde et faites glisser votre souris pour faire tou Cette action masquera tous les boutons et articles de menu. Pour les récupérer, cliquez de nouveau sur [SHORTCUT]. <usetemplate ignoretext="Confirmer avant de masquer l'interface" name="okcancelignore" notext="Annuler" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens basculera." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Voulez-vous continuer ? + <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison des restrictions d'autorisation les concernant." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. + +Voulez-vous continuer ? + <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens sélectionnés basculera et d'autres ne peuvent pas être définis en raison de restrictions d'autorisation sur les groupes de liens." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens sélectionnés basculera et d'autres ne peuvent pas être définis en raison d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. Les types d'usage de ces groupes de liens ne seront pas modifiés. + +Voulez-vous continuer ? + <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison des restrictions d'autorisation les concernant et d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + L'indicateur Fantôme de certains groupes de liens sélectionnés basculera. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d'autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE]. + +Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d'une forme non convexe. Les types d'usage de ces groupes de liens ne seront pas modifiés. + +Voulez-vous continuer ? + <usetemplate ignoretext="L'indicateur Fantôme de certains groupes de liens sélectionnés basculera et d'autres ne peuvent pas être définis en raison de restrictions d'autorisation sur les groupes de liens et d'une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + L'objet sélectionné affecte le maillage de navigation. Si vous le modifiez en Flexibilité, il sera supprimé de ce maillage. + <usetemplate ignoretext="L'objet sélectionné affecte le maillage de navigation. Si vous le modifiez en Flexibilité, il sera supprimé de ce maillage." name="okcancelignore" notext="Annuler" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Vous semblez ne pas avoir le matériel requis pour utiliser [APP_NAME]. [APP_NAME] requiert une carte graphique OpenGL avec une prise en charge du multitexturing. Si vous avez une telle carte, assurez-vous que vous avez aussi les pilotes les plus récents pour la carte, ainsi que les service packs et les patchs pour votre système d'exploitation. @@ -3138,4 +3324,12 @@ Désactivation des mises à jour futures de ce fichier... <notification name="LocalBitmapsVerifyFail"> Tentative d'ajout d'un fichier image [FNAME] non valide ou illisible n'ayant pas pu être ouvert ou décodé. Tentative annulée. </notification> + <notification name="PathfindingReturnMultipleItems"> + Vous allez renvoyer [NUM_ITEMS] articles. Voulez-vous vraiment continuer ? + <usetemplate ignoretext="Voulez-vous vraiment renvoyer plusieurs articles ?" name="okcancelignore" notext="Non" yestext="Oui"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Vous allez supprimer [NUM_ITEMS] articles. Voulez-vous vraiment continuer ? + <usetemplate ignoretext="Voulez-vous vraiment supprimer plusieurs articles ?" name="okcancelignore" notext="Non" yestext="Oui"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml index f54bed4fae..96add2a74b 100644 --- a/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml +++ b/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml @@ -5,6 +5,6 @@ </text> <scroll_list name="blocked" tool_tip="Liste des résidents actuellement ignorés"/> <button label="Ignorer une personne" label_selected="Ignorer le résident..." name="Block resident..." tool_tip="Choisir un résident à ignorer"/> - <button label="Ignorer l'objet par nom" label_selected="Ignorer l'objet par nom..." name="Block object by name..." tool_tip="Choisir un objet à ignorer par nom"/> + <button label="Ignorer un objet par son nom" label_selected="Ignorer un objet par son nom..." name="Block object by name..." tool_tip="Choisir un objet à ignorer par nom"/> <button label="Ne plus ignorer" label_selected="Ne plus ignorer" name="Unblock" tool_tip="Enlever le résident ou l'objet de la liste des ignorés"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_bottomtray.xml b/indra/newview/skins/default/xui/fr/panel_bottomtray.xml deleted file mode 100644 index c4537861e3..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Active/Désactive le micro"/> - <string name="VoiceControlBtnToolTip" value="Affiche/Masque le panneau de contrôle de la voix"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Parler" label_selected="Parler" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Geste" name="Gesture" tool_tip="Affiche/Masque les gestes"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Bouger" name="movement_btn" tool_tip="Affiche/Masque le contrôle des déplacements"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Affichage" name="camera_btn" tool_tip="Affiche/Masque le contrôle de la caméra"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Prendre une photo"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Construire" name="build_btn" tool_tip="Affiche/Masque les outils pour la construction"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Rechercher" name="search_btn" tool_tip="Affiche/Masque la recherche"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Carte" name="world_map_btn" tool_tip="Affiche/Masque la carte du monde"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini-carte" name="mini_map_btn" tool_tip="Affiche/Masque la mini-carte"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversations"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notifications"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_group_invite.xml b/indra/newview/skins/default/xui/fr/panel_group_invite.xml index 53f7ac33c2..d792439220 100644 --- a/indra/newview/skins/default/xui/fr/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/fr/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Certains résidents que vous avez choisis font déjà partie du groupe et l'invitation ne leur a donc pas été envoyée. </panel.string> + <panel.string name="invite_selection_too_large"> + Invitations de groupe non envoyées : trop de résidents sélectionnés. Les invitations de groupe sont limitées à 100 par demande. + </panel.string> <text name="help_text"> Vous pouvez inviter plusieurs résidents à la fois. Cliquez d'abord sur Choisir un résident. </text> diff --git a/indra/newview/skins/default/xui/fr/panel_login.xml b/indra/newview/skins/default/xui/fr/panel_login.xml index e54b36644c..c8a1fe8751 100644 --- a/indra/newview/skins/default/xui/fr/panel_login.xml +++ b/indra/newview/skins/default/xui/fr/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://fr.secondlife.com/registration/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=fr </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + CONNEXION + </text> <text name="username_text"> Nom d'utilisateur : </text> @@ -15,34 +15,32 @@ <text name="password_text"> Mot de passe : </text> - <check_box label="Enregistrer" name="remember_check"/> - <button label="Connexion" name="connect_btn"/> - <text name="mode_selection_text"> - Mode : - </text> - <combo_box name="mode_combo" tool_tip="Sélectionnez un mode. Pour une exploration facile et rapide avec chat, choisissez Basique. Pour accéder à plus de fonctionnalités, choisissez Avancé."> - <combo_box.item label="Basique" name="Basic"/> - <combo_box.item label="Avancé" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Lieu de départ : </text> <combo_box name="start_location_combo"> <combo_box.item label="Dernier emplacement" name="MyLastLocation"/> <combo_box.item label="Domicile" name="MyHome"/> - <combo_box.item label="<Saisir le nom de la région>" name="Typeregionname"/> + <combo_box.item label="<Nom de la région>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - S'inscrire + <layout_panel name="links_login_panel"> + <text name="login_help"> + Besoin d'aide ? </text> <text name="forgot_password_text"> Nom d'utilisateur ou mot de passe oublié ? </text> - <text name="login_help"> - Besoin d'aide ? + <button label="Connexion" name="connect_btn"/> + <check_box label="Enregistrer" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CRÉER VOTRE COMPTE </text> + <button label="Commencer" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/fr/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..7acf092257 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="Refiger la région" name="navmesh_btn" tool_tip="Cliquer pour refiger le maillage de navigation de la région."/> + <button label="Demande consistant à refiger la région en cours..." name="navmesh_btn_sending" tool_tip="Envoi de la demande consistant à refiger la région au serveur..."/> + <button label="La région se refige..." name="navmesh_btn_baking" tool_tip="La région se refige. Ce bouton disparaîtra lorsque le processus sera terminé."/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml b/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml index 6f4e9c23f9..945a5e0272 100644 --- a/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml +++ b/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml @@ -9,12 +9,12 @@ </combo_box> <layout_stack name="postcard_image_params_ls"> <layout_panel name="postcard_image_size_lp"> - <spinner label="Largeur" name="postcard_snapshot_width"/> - <spinner label="Hauteur" name="postcard_snapshot_height"/> + <spinner label="Larg." name="postcard_snapshot_width"/> + <spinner label="Haut." name="postcard_snapshot_height"/> <check_box label="Conserver les proportions" name="postcard_keep_aspect_check"/> </layout_panel> <layout_panel name="postcard_image_format_quality_lp"> - <slider label="Qualité de l'image" name="image_quality_slider"/> + <slider label="Qualité image" name="image_quality_slider"/> <text name="image_quality_level"> ([QLVL]) </text> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml index 76ed237451..550beb653e 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="Chats IM" name="EnableIMChatPopups" tool_tip="Cocher cette case pour qu'un popup s'affiche à réception d'un message instantané."/> <spinner label="Durée de vie du popup Chat près de moi :" name="nearby_toasts_lifetime"/> <spinner label="Disparition progressive du popup Chat près de moi :" name="nearby_toasts_fadingtime"/> - <button label="Traduction automatique" name="ok_btn"/> + <button label="Traduction..." name="ok_btn"/> + <button label="Rechercher/Remplacer..." name="autoreplace_showgui"/> + <button label="Orthographe..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_move.xml b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml index 94d7322b22..80aed90a2d 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml @@ -28,7 +28,7 @@ <combo_box.item label="Déplacement vers le clic" name="1"/> </combo_box> <text name="double_click_action_lbl"> - Double-clic sur le terrain : + Double clic sur le terrain : </text> <combo_box name="double_click_action_combo"> <combo_box.item label="Aucune action" name="0"/> diff --git a/indra/newview/skins/default/xui/fr/panel_region_debug.xml b/indra/newview/skins/default/xui/fr/panel_region_debug.xml index 733c3f9a22..98ae250215 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_debug.xml @@ -30,11 +30,11 @@ <check_box label="Sur le terrain d'un autre résident" name="return_other_land" tool_tip="Ne renvoyer que les objets se trouvant sur le terrain de quelqu'un d'autre"/> <check_box label="Dans toutes les régions de ce domaine" name="return_estate_wide" tool_tip="Renvoyer les objets dans toutes les régions qui constituent ce domaine"/> <button label="Renvoyer" name="return_btn"/> - <button label="Afficher les collisions les plus consommatrices..." name="top_colliders_btn" tool_tip="Liste des objets avec le plus de collisions potentielles" width="320"/> + <button label="Collisions les plus consommatrices" name="top_colliders_btn" tool_tip="Liste des objets avec le plus de collisions potentielles" width="320"/> <button label="?" left="337" name="top_colliders_help"/> - <button label="Afficher les objets scriptés les plus consommateurs..." name="top_scripts_btn" tool_tip="Liste des objets qui passent le plus de temps à exécuter des scripts" width="320"/> + <button label="Scripts les plus consommateurs" name="top_scripts_btn" tool_tip="Liste des objets passant le plus de temps à exécuter des scripts" width="320"/> <button label="?" left="337" name="top_scripts_help"/> <button label="Redémarrer la région" name="restart_btn" tool_tip="Redémarrer la région au bout de 2 minutes" width="160"/> <button label="?" left="177" name="restart_help"/> - <button label="Retarder le redémarrage" name="cancel_restart_btn" tool_tip="Retarder le redémarrage de la région d'une heure" width="160"/> + <button label="Annuler le redémarrage" name="cancel_restart_btn" tool_tip="Annuler le redémarrage de la région." width="160"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_environment.xml b/indra/newview/skins/default/xui/fr/panel_region_environment.xml index d18503db86..085a308786 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_environment.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_environment.xml @@ -15,7 +15,7 @@ <combo_box.item label="-Effectuer une sélection-" name="item0"/> </combo_box> <text name="sky_dayc_settings_title"> - Ciel / Cycle du jour + Ciel/Cycle du jour </text> <radio_group name="sky_dayc_settings_radio_group"> <radio_item label="Ciel fixe" name="my_sky_settings"/> diff --git a/indra/newview/skins/default/xui/fr/panel_region_estate.xml b/indra/newview/skins/default/xui/fr/panel_region_estate.xml index 9d97d1bf29..be89020ac7 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_estate.xml @@ -21,7 +21,7 @@ domaine. Conditions d'accès des résidents : </text> <check_box label="Informations de paiement enregistrées" name="limit_payment" tool_tip="Pour pouvoir accéder à ce domaine, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d'informations."/> - <check_box label="Âge vérifié" name="limit_age_verified" tool_tip="Pour que les résidents puissent accéder à ce domaine, leur âge doit avoir fait l'objet d'une vérification. Consultez le [SUPPORT_SITE] pour plus d'informations."/> + <check_box label="Avoir plus de 18 ans" name="limit_age_verified" tool_tip="Pour accéder à ce domaine, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d'informations."/> <check_box label="Autoriser les chats vocaux" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <text name="abuse_email_text"> diff --git a/indra/newview/skins/default/xui/fr/panel_region_general.xml b/indra/newview/skins/default/xui/fr/panel_region_general.xml index b5795bebe2..234d316069 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_general.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_general.xml @@ -22,7 +22,7 @@ <check_box label="Interdire le vol" name="block_fly_check"/> <check_box label="Autoriser les dégâts" name="allow_damage_check"/> <check_box label="Interdire les bousculades" name="restrict_pushobject"/> - <check_box label="Autoriser la revente" name="allow_land_resell_check"/> + <check_box label="Autoriser la revente de terrain" name="allow_land_resell_check"/> <check_box label="Autoriser la fusion/division" name="allow_parcel_changes_check"/> <check_box label="Ne pas afficher dans la recherche" name="block_parcel_search_check" tool_tip="Afficher cette région et ses parcelles dans les résultats de recherche"/> <check_box label="Autoriser les objets de maillage" name="mesh_rez_enabled_check" tool_tip="Laisser les gens rezzer des objets de maillage dans cette région."/> diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml index d7e321d06d..97f486d3a3 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml @@ -55,8 +55,8 @@ du terrain" name="terrain_lower_spin"/> <spinner label="Bas" name="height_start_spin_2"/> <spinner label="Haut" name="height_range_spin_0"/> <spinner label="Haut" name="height_range_spin_2"/> - <button label="Télécharger le terrain au format RAW..." name="download_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> - <button label="Charger le terrain au format RAW..." name="upload_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> + <button label="Télécharger le terrain en RAW..." name="download_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> + <button label="Charger un terrain en RAW..." name="upload_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/> <button label="Figer le terrain" name="bake_terrain_btn" tool_tip="Définir le terrain actuel comme point central pour les limites d'élévation/abaissement"/> <button label="Appliquer" name="apply_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_texture.xml b/indra/newview/skins/default/xui/fr/panel_region_texture.xml deleted file mode 100644 index c0b667137a..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_region_texture.xml +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Textures du sol" name="Textures"> - <text name="region_text_lbl"> - Région : - </text> - <text name="region_text"> - (inconnue) - </text> - <text name="base_texture_text"> - Textures de base (fichiers 128x128, 24 bit .tga) - </text> - <text name="height_text_lbl"> - 1 (faible) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (élevé) - </text> - <text name="detail_texture_text"> - Textures du terrain (fichiers.tga 512 x 512, 24 bit requis) - </text> - <text name="height_text_lbl5"> - Limites d'élévation de texture - </text> - <text name="height_text_lbl6"> - Nord-ouest - </text> - <text name="height_text_lbl7"> - Nord-est - </text> - <text name="height_text_lbl8"> - Sud-ouest - </text> - <text name="height_text_lbl9"> - Sud-est - </text> - <text name="height_text_lbl10" width="460"> - Ces valeurs représentent les limites de mélange pour les textures ci-dessus. - </text> - <text name="height_text_lbl11"> - En mètres, la valeur Bas correspond à la hauteur max. de la texture n°1 - </text> - <text name="height_text_lbl12"> - et la valeur Haut correspond à la hauteur min. de la texture n°4. - </text> - <text name="height_text_lbl13"> - Nord-est - </text> - <spinner label="Bas" name="height_start_spin_0"/> - <spinner label="Bas" name="height_start_spin_1"/> - <spinner label="Bas" name="height_start_spin_2"/> - <spinner label="Bas" name="height_start_spin_3"/> - <spinner label="Haut" name="height_range_spin_0"/> - <spinner label="Haut" name="height_range_spin_1"/> - <spinner label="Haut" name="height_range_spin_2"/> - <spinner label="Haut" name="height_range_spin_3"/> - <text name="height_text_lbl14"> - Ces valeurs représentent les limites de mélange pour les textures ci-dessus. - </text> - <text name="height_text_lbl15"> - La valeur Bas correspond à la hauteur max. de la Texture 1, - </text> - <text name="height_text_lbl16"> - et la valeur Haut correspond à la hauteur min. de la Texture 4. - </text> - <button label="Appliquer" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_side_tray.xml b/indra/newview/skins/default/xui/fr/panel_side_tray.xml deleted file mode 100644 index 178ae4324b..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Activer/désactiver le panneau latéral." name="sidebar_openclose" tab_title="Activer/désactiver le panneau latéral"/> - <sidetray_tab description="Domicile." name="sidebar_home" tab_title="Accueil"> - <panel label="domicile" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Modifiez votre profil public et vos Favoris." name="sidebar_me" tab_title="Mon profil"> - <panel_container name="panel_container"> - <panel label="Moi" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trouvez vos amis, vos contacts et les personnes se trouvant près de vous." name="sidebar_people" tab_title="Personnes"> - <panel_container name="panel_container"> - <panel label="Profil du groupe" name="panel_group_info_sidetray"/> - <panel label="Résidents et objets ignorés" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trouvez de nouveaux lieux à découvrir et les lieux que vous connaissez déjà." label="Lieux" name="sidebar_places" tab_title="Endroits"> - <panel label="Lieux" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Parcourez votre inventaire." name="sidebar_inventory" tab_title="Mon inventaire"> - <panel label="Modifier l'inventaire" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Modifiez votre apparence actuelle." name="sidebar_appearance" tab_title="Mon apparence"> - <panel label="Changer d'apparence" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml index 4454d2475e..472c4a5e8f 100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_inventory"> <text name="title"> - Enregistrer dans mon inventaire + Enregistrer dans l'inventaire </text> <text name="hint_lbl"> - L'enregistrement d'une image dans votre inventaire coûte [UPLOAD_COST] L$. Pour enregistrer votre image sous forme de texture, sélectionnez l'un des formats carrés. + L'enregistrement d'une image dans l'inventaire coûte [UPLOAD_COST] L$. Pour enregistrer votre image sous forme de texture, sélectionnez un format carré. </text> <combo_box label="Résolution" name="texture_size_combo"> <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/> diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml index 41264521fd..97dc3e7e2b 100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_local"> <text name="title"> - Enregistrer sur mon ordinateur + Enregistrer sur l'ordinateur </text> <combo_box label="Résolution" name="local_size_combo"> <combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/> @@ -25,7 +25,7 @@ <combo_box.item label="JPEG" name="JPEG"/> <combo_box.item label="BMP (sans perte)" name="BMP"/> </combo_box> - <slider label="Qualité de l'image" name="image_quality_slider"/> + <slider label="Qualité image" name="image_quality_slider"/> <text name="image_quality_level"> ([QLVL]) </text> diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml index db3fcbeac9..befe1b3bc6 100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml @@ -2,6 +2,6 @@ <panel name="panel_snapshot_options"> <button label="Publier sur le flux de mon profil" name="save_to_profile_btn"/> <button label="Envoyer par e-mail" name="save_to_email_btn"/> - <button label="Enregistrer dans mon inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/> - <button label="Enregistrer sur mon ordinateur" name="save_to_computer_btn"/> + <button label="Enreg. dans l'inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/> + <button label="Enreg. sur l'ordinateur" name="save_to_computer_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml index bb23b52850..82a4815144 100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml @@ -10,7 +10,7 @@ Envoi en cours... </string> <text name="title"> - Envoyer par e-mail + E-mail </text> <button label="Message" name="message_btn"/> <button label="Paramètres" name="settings_btn"/> diff --git a/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml new file mode 100644 index 0000000000..e05c93a4ac --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="Principal" name="System Volume"/> + <slider label="Boutons" name="UI Volume"/> + <slider label="Ambiant" name="Wind Volume"/> + <slider label="Sons" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Activer les sons des gestes."/> + <slider label="Musique" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Activer les flux de musique."/> + <slider label="Médias" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Activer les flux de média."/> + <slider label="Voix" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Activer le chat vocal."/> +</panel> diff --git a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml index 95649d3934..e7fc7859c9 100644 --- a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (inconnu) </panel.string> + <panel.string name="unknown_multiple"> + (valeur inconnue ou valeurs multiples) + </panel.string> <panel.string name="public"> (public) </panel.string> diff --git a/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml index bd8a39fe16..60027d41cb 100644 --- a/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Vous ne pouvez pas modifier ces objets </panel.string> + <panel.string name="text modify info 5"> + Impossible de modifier cet objet au-delà de la frontière d'une région + </panel.string> + <panel.string name="text modify info 6"> + Impossible de modifier ces objets au-delà de la frontière d'une région + </panel.string> <panel.string name="text modify warning"> Cet objet comprend des parties liées </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Prix : L$" name="Edit Cost"/> <check_box label="Afficher avec la recherche" name="search_check" tool_tip="Permettre aux autres résidents de voir cet objet dans les résultats de recherche"/> + <text name="pathfinding_attributes_label"> + Attributs de recherche de chemin : + </text> <text name="B:"> B : </text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 0987952c28..6a2a3f559a 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -137,7 +137,7 @@ Quitter </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=fr-FR + http://join.secondlife.com/index.php?lang=fr-FR&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Le client que vous utilisez ne permet plus d'accéder à Second Life. Téléchargez un nouveau client à la page suivante : @@ -1006,6 +1006,9 @@ Veuillez réessayer de vous connecter dans une minute. <string name="script_files"> Scripts </string> + <string name="dictionary_files"> + Dictionnaires + </string> <string name="AvatarSetNotAway"> Présent </string> @@ -1411,6 +1414,12 @@ Veuillez réessayer de vous connecter dans une minute. <string name="InvFolder favorite"> Mes Favoris </string> + <string name="InvFolder Favorites"> + Mes favoris + </string> + <string name="InvFolder favorites"> + Mes favoris + </string> <string name="InvFolder Current Outfit"> Tenue actuelle </string> @@ -1426,6 +1435,12 @@ Veuillez réessayer de vous connecter dans une minute. <string name="InvFolder Meshes"> Maillages </string> + <string name="InvFolder Received Items"> + Articles reçus + </string> + <string name="InvFolder Merchant Outbox"> + Boîte d'envoi vendeur + </string> <string name="InvFolder Friends"> Amis </string> @@ -3864,6 +3879,12 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Avatars visibles et chat autorisé en dehors de cette parcelle </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Les objets mobiles risquent de ne pas se comporter correctement dans cette région tant qu'elle n'est pas refigée. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + La recherche de chemin dynamique n'est pas activée dans cette région. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] - Mise à jour </string> @@ -4893,7 +4914,7 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles Parler </string> <string name="Command_View_Label"> - Paramètres de la caméra + Caméra </string> <string name="Command_Voice_Label"> Paramètres vocaux @@ -5006,6 +5027,21 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Aucun + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Maillage de navigation affecté + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personnage + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Multiple) + </string> <string name="snapshot_quality_very_low"> Très faible </string> @@ -5021,4 +5057,10 @@ Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles <string name="snapshot_quality_very_high"> Très élevée </string> + <string name="TeleportMaturityExceeded"> + Le résident ne peut pas visiter cette région. + </string> + <string name="UserDictionary"> + [User] + </string> </strings> diff --git a/indra/newview/skins/default/xui/fr/teleport_strings.xml b/indra/newview/skins/default/xui/fr/teleport_strings.xml index d0c74ff353..6065fa2966 100644 --- a/indra/newview/skins/default/xui/fr/teleport_strings.xml +++ b/indra/newview/skins/default/xui/fr/teleport_strings.xml @@ -45,6 +45,9 @@ Pour recommencer le didacticiel, accédez à Welcome Island Public. <message name="no_inventory_host"> L'inventaire est temporairement indisponible. </message> + <message name="MustGetAgeRegion"> + Pour accéder à cette région, vous devez avoir au moins 18 ans. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ Pour recommencer le didacticiel, accédez à Welcome Island Public. <message name="requesting"> Demande de téléportation en cours... </message> + <message name="pending"> + En attente de téléportation... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index 39114b7bf7..c672511fc5 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -66,27 +66,26 @@ Versione Server voice: [VOICE_VERSION] </panel> <panel label="Licenze" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion - APR Copyright (C) 2000-2004 The Apache Software Foundation - Collada DOM Copyright 2005 Sony Computer Entertainment Inc. - cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. - FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). + FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. - ogg/vorbis Copyright (C) 2001, Xiphophorus - OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. - PCRE Copyright (c) 1997-2008 University of Cambridge + ogg/vorbis Copyright (C) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. - zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. - google-perftools Copyright (c) 2005, Google Inc. + zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. Il Viewer Second Life utilizza Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e licenziatari). Tutti i diritti riservati. Per informazioni dettagliate, vedere www.havok.com. 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 cfc3ad8fdb..fe3e59b0bd 100644 --- a/indra/newview/skins/default/xui/it/floater_about_land.xml +++ b/indra/newview/skins/default/xui/it/floater_about_land.xml @@ -470,7 +470,7 @@ Media: Consenti l'accesso solo ai Residenti che: </text> <check_box label="Hanno informazioni di pagamento in archivio [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Per poter visitare questo lotto i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/> - <check_box label="Hanno verificato l'età [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Per poter visitare questo lotto i Residenti devono aver verificato la propria età. Vedi [SUPPORT_SITE] per maggiori informazioni."/> + <check_box label="Hanno almeno 18 anni [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Per poter visitare questo lotto i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/> <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'accesso temporaneo"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/it/floater_animation_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_preview.xml deleted file mode 100644 index dc99d287b9..0000000000 --- a/indra/newview/skins/default/xui/it/floater_animation_preview.xml +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> - <floater.string name="failed_to_initialize"> - Impossibile inizializzare la sequenza - </floater.string> - <floater.string name="anim_too_long"> - Il file dell'animazione è lungo [LENGTH] secondi. - -La lunghezza massima è [MAX_LENGTH] secondi. - </floater.string> - <floater.string name="failed_file_read"> - Impossibile leggere il file dell'animazione. - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - Ok - </floater.string> - <floater.string name="E_ST_EOF"> - Fine prematura del file. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Impossibile leggere la definizione del vincolo. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - Impossibile aprire il file BVH. - </floater.string> - <floater.string name="E_ST_NO_HIER"> - Intestazione HIERARCHY non valida. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - Impossibile trovare la ROOT o JOINT. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - Impossibile trovare il nome JOINT. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - Impossibile trovare OFFSET. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - Impossibile trovare CHANNELS. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Impossibile ottenere un ordine di rotazione. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Rotazione dell'asse non disponibile. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - Impossibile trovare MOTION. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - Impossibile ottenere il numero dei frame. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Impossibile ottenere il tempo del frame. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Impossibile ottenere i valori della posizione. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Impossibile ottenere i valori di rotazione. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Impossibile aprire il file di traduzione. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Impossibile leggere l'intestazione della traduzione. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Impossibile leggere i nomi della traduzione. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Impossibile leggere la traduzione, ignora il valore. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Impossibile leggere la traduzione del valore relativo. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Valore non trovato. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Impossibile leggere la matrice di traduzione. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Impossibile trovare il nome mergechild. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Impossibile ottenere il nome mergeparent. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Impossibile ottenere il valore di priorità. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Impossibile ottenere il valore di ripetizione. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Impossibile ottenere i valori easeIn. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - Cannot get ease Out values. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Impossibile ottenere il valore morph della mano. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Impossibile leggere il nome emote. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Nome non corretto del root joint, usa "hip". - </floater.string> - <text name="name_label"> - Nome: - </text> - <text name="description_label"> - Descrizione: - </text> - <spinner label="Priorità" name="priority" tool_tip="Definisce quali altre animazioni possono essere sostituite da questa animazione"/> - <check_box label="Ciclica" name="loop_check" tool_tip="Riproduce questa animazione in ripetizione"/> - <spinner label="In(%)" name="loop_in_point" tool_tip="Imposta il punto sul quale ritorna l'animazione"/> - <spinner label="Out(%)" name="loop_out_point" tool_tip="Imposta il punto sul quale termina l'animazione"/> - <text name="hand_label"> - Postura della mano - </text> - <combo_box name="hand_pose_combo" tool_tip="Definisce ciò che fanno le mani durante l'animazione"> - <combo_box.item label="Stendi" name="Spread"/> - <combo_box.item label="Rilassato" name="Relaxed"/> - <combo_box.item label="Indica entrambi" name="PointBoth"/> - <combo_box.item label="Pugno" name="Fist"/> - <combo_box.item label="Sinistra rilassata" name="RelaxedLeft"/> - <combo_box.item label="Indica sinistra" name="PointLeft"/> - <combo_box.item label="Pugno con la sinistra" name="FistLeft"/> - <combo_box.item label="Destra rilassata" name="RelaxedRight"/> - <combo_box.item label="Indica destra" name="PointRight"/> - <combo_box.item label="Pugno destro" name="FistRight"/> - <combo_box.item label="Saluta a destra" name="SaluteRight"/> - <combo_box.item label="Battitura" name="Typing"/> - <combo_box.item label="Pace a destra" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Espressione - </text> - <combo_box name="emote_combo" tool_tip="Definisce ciò che fa il viso durante l'animazione"> - <item label="(Nessuno)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Spavento" name="Afraid" value="Spavento"/> - <item label="Arrabbiato" name="Angry" value="Arrabbiato"/> - <item label="Grande sorriso" name="BigSmile" value="Grande sorriso"/> - <item label="Annoiato" name="Bored" value="Annoiato"/> - <item label="Pianto" name="Cry" value="Pianto"/> - <item label="Disdegno" name="Disdain" value="Disdegno"/> - <item label="Imbarazzato" name="Embarrassed" value="Imbarazzato"/> - <item label="Accigliato" name="Frown" value="Accigliato"/> - <item label="Bacio" name="Kiss" value="Bacio"/> - <item label="Risata" name="Laugh" value="Risata"/> - <item label="Plllppt" name="Plllppt" value="Linguaccia"/> - <item label="Repulsione" name="Repulsed" value="Repulsione"/> - <item label="Triste" name="Sad" value="Triste"/> - <item label="Scrollata di spalle" name="Shrug" value="Scrollata di spalle"/> - <item label="Sorriso" name="Smile" value="Sorriso"/> - <item label="Stupore" name="Surprise" value="Stupore"/> - <item label="Occhiolino" name="Wink" value="Occhiolino"/> - <item label="Preoccupato" name="Worry" value="Preoccupato"/> - </combo_box> - <text name="preview_label"> - Vedi anteprima mentre - </text> - <combo_box name="preview_base_anim" tool_tip="Da usarsi per controllare il comportamento dell'animazione mentre l'avatar svolge azioni abituali."> - <item label="In piedi" name="Standing" value="In piedi"/> - <item label="Camminando" name="Walking" value="Cammina"/> - <item label="Seduto" name="Sitting" value="Seduto"/> - <item label="Volo" name="Flying" value="Volo"/> - </combo_box> - <spinner label="Avvio lento (sec)" name="ease_in_time" tool_tip="Durata (in secondi) della fusione in entrata delle animazioni"/> - <spinner label="Arresto lento (sec)" name="ease_out_time" tool_tip="Durata (in secondi) della fusione in uscita delle animazioni"/> - <button name="play_btn" tool_tip="Riproduci la tua animazione"/> - <button name="pause_btn" tool_tip="Metti in pausa la tua animazione"/> - <button label="" name="stop_btn" tool_tip="Ferma la riproduzione dell'animazione"/> - <text name="bad_animation_text"> - Impossibile leggere il file dell'animazione. - -Raccomandiamo file di tipo BVH esportati da -Poser 4. - </text> - <button label="Importa ([AMOUNT]L$)" name="ok_btn"/> - <button label="Annulla" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_autoreplace.xml b/indra/newview/skins/default/xui/it/floater_autoreplace.xml new file mode 100644 index 0000000000..559a42cfae --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Impostazioni sostituzione automatica"> + <check_box label="Attiva sostituzione automatica" name="autoreplace_enable" tool_tip="Quando inserisci testo nella chat, sostituisci le parole chiave inserite con l'elemento sostitutivo corrispondente."/> + <button label="Importa lista..." name="autoreplace_import_list" tool_tip="Carica da file una lista esportata in precedenza."/> + <button label="Esporta lista..." name="autoreplace_export_list" tool_tip="Salva la lista selezionata in un file per condividerla."/> + <button label="Nuova lista..." name="autoreplace_new_list" tool_tip="Crea una nuova lista"/> + <button label="Cancella lista" name="autoreplace_delete_list" tool_tip="Cancella la lista selezionata"/> + <button name="autoreplace_list_up" tool_tip="Aumenta la priorità di questa lista."/> + <button name="autoreplace_list_down" tool_tip="Diminuisci la priorità di questa lista."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Parola chiave" name="keyword"/> + <scroll_list.columns label="Sostituzione" name="replacement"/> + </scroll_list> + <button label="Aggiungi..." name="autoreplace_add_entry"/> + <button label="Rimuovi" name="autoreplace_delete_entry"/> + <button label="Salva elemento" name="autoreplace_save_entry" tool_tip="Salva questo elemento."/> + <button label="Salva modifiche" name="autoreplace_save_changes" tool_tip="Salva tutte le modifiche."/> + <button label="Annulla" name="autoreplace_cancel" tool_tip="Annulla tutte le modifiche."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/it/floater_inventory.xml b/indra/newview/skins/default/xui/it/floater_inventory.xml deleted file mode 100644 index 2aa6795988..0000000000 --- a/indra/newview/skins/default/xui/it/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="IL MIO INVENTARIO"> - <floater.string name="Title"> - IL MIO INVENTARIO - </floater.string> - <floater.string name="TitleFetching"> - IL MIO INVENTARIO (recupero di [ITEM_COUNT] articoli...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - IL MIO INVENTARIO ([ITEM_COUNT] articoli) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Completato - </floater.string> - <panel label="Pannello dell'Inventario" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_model_preview.xml b/indra/newview/skins/default/xui/it/floater_model_preview.xml index ca36fd2def..e8df4d2d4b 100644 --- a/indra/newview/skins/default/xui/it/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/it/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="Triangoli" name="triangles" value="Triangoli"/> <text initial_value="Vertici" name="vertices" value="Vertici"/> <text initial_value="Alto" name="high_label" value="Alto"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Medio" name="medium_label" value="Medio"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Basso" name="low_label" value="Basso"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Bassissimo" name="lowest_label" value="Bassissimo"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Carica da file"/> + <item name="Generate" value="Genera"/> + <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/> + </combo_box> <button label="Sfoglia..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Limite triangoli"/> + <item name="Error Threshold" value="Limite errori"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Genera normali" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/it/floater_nearby_chat.xml b/indra/newview/skins/default/xui/it/floater_nearby_chat.xml deleted file mode 100644 index 9e81899880..0000000000 --- a/indra/newview/skins/default/xui/it/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT NEI DINTORNI"> - <check_box label="Traduci chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..5122954edb --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personaggi con pathfinding"> + <floater.string name="messaging_get_inprogress"> + Ricerca personaggi con pathfinding in corso... + </floater.string> + <floater.string name="messaging_get_error"> + Errore rilevato durante la ricerca di personaggi con pathfinding. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nessun personaggio con pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personaggi selezionati su [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Caricamento in corso] + </floater.string> + <floater.string name="character_owner_unknown"> + [Sconosciuto] + </floater.string> + <floater.string name="character_owner_group"> + [gruppo] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome" name="name"/> + <scroll_list.columns label="Descrizione" name="description"/> + <scroll_list.columns label="Proprietario" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitudine" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personaggi: + </text> + <button label="Aggiorna lista" name="refresh_objects_list"/> + <button label="Seleziona tutto" name="select_all_objects"/> + <button label="Non selezionare nessuno" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Azioni per i personaggi selezionati: + </text> + <check_box label="Mostra marcatore" name="show_beacon"/> + <check_box label="Mostra capsula fisica" name="show_physics_capsule"/> + <button label="Prendi" name="take_objects"/> + <button label="Prendi copia" name="take_copy_objects"/> + <button label="Teletrasportami alla posizione" name="teleport_me_to_object" tool_tip="Attivato solo se viene selezionato un personaggio."/> + <button label="Restituisci" name="return_objects"/> + <button label="Elimina" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml new file mode 100644 index 0000000000..77be220a2a --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Visualizzazione / test pathfinding"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Implementazione libreria percorsi non trovata. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Attendere il caricamento della regione. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Controllo stato navmesh + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Scaricamento navmesh in corso + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Il navmesh è stato cambiato sul server. Scaricamento del navmesh più recente in corso + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Il navmesh più recente è stato scaricato. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Navmesh non scaricato correttamente. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Il navmesh ha modifiche in sospeso. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Costruzione navmesh in corso. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Alcune regioni navmesh hanno modifiche in sospeso. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + La costruzione di alcune regioni navmesh è in corso. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Alcune regioni navmesh hanno modifiche in sospeso e in altre la costruzione è in corso. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Navmesh è aggiornato. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Implementazione libreria percorsi non trovata. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Seleziona punti iniziale e finale. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Seleziona punto iniziale. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Seleziona punto finale. + </floater.string> + <floater.string name="pathing_path_valid"> + Il percorso viene visualizzato con il colore arancione. + </floater.string> + <floater.string name="pathing_path_invalid"> + Nessun percorso trovato tra i punti selezionati. + </floater.string> + <floater.string name="pathing_error"> + Si è verificato un errore durante la generazione del percorso. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Visuale" name="view_panel"> + <text name="show_label"> + Mostra: + </text> + <check_box label="Mondo" name="show_world"/> + <check_box label="Solo elementi spostabili" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Mostra mappa camminabilità: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Non mostrare" name="show_heatmap_mode_none"/> + <combo_box.item label="Personaggio tipo A" name="show_heatmap_mode_a"/> + <combo_box.item label="Personaggio tipo B" name="show_heatmap_mode_b"/> + <combo_box.item label="Personaggio tipo C" name="show_heatmap_mode_c"/> + <combo_box.item label="Personaggio tipo D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Camminabili" name="show_walkables"/> + <check_box label="Volumi materiali" name="show_material_volumes"/> + <check_box label="Ostacoli statici" name="show_static_obstacles"/> + <check_box label="Volumi esclusioni" name="show_exclusion_volumes"/> + <check_box label="Piano acqua" name="show_water_plane"/> + <check_box label="Con vista a raggi X" name="show_xray"/> + </panel> + <panel label="Percorso test" name="test_panel"> + <text name="ctrl_click_label"> + Seleziona il punto iniziale premendo Ctrl e facendo clic. + </text> + <text name="shift_click_label"> + Seleziona il punto finale premendo Maiusc e facendo clic. + </text> + <text name="character_width_label"> + Larghezza personaggio + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Tipo personaggio + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Nessuno" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Cancella percorso" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..7edac3ff46 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Set collegati pathfinding"> + <floater.string name="messaging_get_inprogress"> + Ricerca set collegati pathfinding in corso... + </floater.string> + <floater.string name="messaging_get_error"> + Errore rilevato durante la ricerca di set collegati pathfinding. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modifica set collegati pathfinding selezionati in corso... + </floater.string> + <floater.string name="messaging_set_error"> + Errore rilevato durante la modifica dei set collegati pathfinding selezionati. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nessun set collegato con pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] set collegati selezionati su [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + In questa regione non è attivata la funzione pathfinding + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terreno] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Caricamento in corso] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Sconosciuto] + </floater.string> + <floater.string name="linkset_owner_group"> + [gruppo] + </floater.string> + <floater.string name="linkset_is_scripted"> + Sì + </floater.string> + <floater.string name="linkset_is_not_scripted"> + No + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Sconosciuto + </floater.string> + <floater.string name="linkset_use_walkable"> + Camminabile + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Ostacolo statico + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Ostacolo mobile + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volume materiale + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volume esclusione + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Oggetto fantasma mobile + </floater.string> + <floater.string name="linkset_is_terrain"> + [non modificabile] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [limitato] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [concavo] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [limitato,concavo] + </floater.string> + <floater.string name="linkset_choose_use"> + Seleziona uso set collegati... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtra in base all'uso set collegati..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Camminabile" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Ostacolo statico" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Ostacolo mobile" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volume materiale" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volume esclusione" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Oggetto fantasma mobile" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Applica" name="apply_filters"/> + <button label="Cancella" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome (prim principale)" name="name"/> + <scroll_list.columns label="Descrizione (prim principale)" name="description"/> + <scroll_list.columns label="Proprietario" name="owner"/> + <scroll_list.columns label="Scriptato" name="scripted"/> + <scroll_list.columns label="Impatto" name="land_impact"/> + <scroll_list.columns label="Distanza" name="dist_from_you"/> + <scroll_list.columns label="Uso set collegati" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Set collegati: + </text> + <button label="Aggiorna lista" name="refresh_objects_list"/> + <button label="Seleziona tutto" name="select_all_objects"/> + <button label="Non selezionare nessuno" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Mostra marcatore" name="show_beacon"/> + <button label="Prendi" name="take_objects"/> + <button label="Prendi copia" name="take_copy_objects"/> + <button label="Teletrasportami alla posizione" name="teleport_me_to_object"/> + <button label="Restituisci" name="return_objects"/> + <button label="Elimina" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Camminabilità: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Camminabilità per personaggi di tipo A. Umanoide è un esempio del tipo di personaggio."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Camminabilità per personaggi di tipo B. Creatura è un esempio del tipo di personaggio."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Camminabilità per personaggi di tipo C. Elemento meccanico è un esempio del tipo di personaggio."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Camminabilità per personaggi di tipo D. Altro è un esempio del tipo di personaggio."/> + <button label="Applica modifiche" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Umanoide) + </text> + <text name="suggested_use_b_label"> + (Creatura) + </text> + <text name="suggested_use_c_label"> + (Elemento meccanico) + </text> + <text name="suggested_use_d_label"> + (Altro) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_postcard.xml b/indra/newview/skins/default/xui/it/floater_postcard.xml deleted file mode 100644 index cb2916268a..0000000000 --- a/indra/newview/skins/default/xui/it/floater_postcard.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="INVIA FOTO VIA E-MAIL"> - <text name="to_label" width="135"> - Email del destinatario: - </text> - <line_editor left="143" name="to_form" width="127"/> - <text name="from_label"> - La tua email: - </text> - <line_editor left="143" name="from_form" width="127"/> - <text name="name_label"> - Il tuo nome: - </text> - <line_editor left="143" name="name_form" width="127"/> - <text name="subject_label"> - Soggetto: - </text> - <line_editor left="143" name="subject_form" width="127"/> - <line_editor label="Scrivi il soggetto qui." name="subject_form"/> - <text name="msg_label"> - Messaggio: - </text> - <text_editor name="msg_form"> - Scrivi il messaggio qui. - </text_editor> - <text name="fine_print"> - Se il tuo destinatario si registrerà in [SECOND_LIFE], riceverai il relativo bonus. - </text> - <button label="Annulla" name="cancel_btn"/> - <button label="Invia" name="send_btn"/> - <string name="default_subject"> - Cartolina da [SECOND_LIFE]. - </string> - <string name="default_message"> - Vieni a vedere! - </string> - <string name="upload_message"> - Invio... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_spellcheck.xml b/indra/newview/skins/default/xui/it/floater_spellcheck.xml new file mode 100644 index 0000000000..2a8557b0fc --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Impostazioni controllo ortografico"> + <check_box label="Attiva controllo ortografico" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Dizionario principale: + </text> + <text label="Registri:" name="spellcheck_additional"> + Dizionari aggiuntivi: + </text> + <text name="spellcheck_available"> + Disponibile + </text> + <text name="spellcheck_active"> + Attivato + </text> + <button label="Rimuovi" name="spellcheck_remove_btn"/> + <button label="Importa..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml new file mode 100644 index 0000000000..c04fc249a7 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Imposta dizionario"> + <button label="Sfoglia" label_selected="Sfoglia" name="dictionary_path_browse"/> + <button label="Importa" name="ok_btn"/> + <button label="Annulla" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_stats.xml b/indra/newview/skins/default/xui/it/floater_stats.xml index 2241cad711..825b2ce57a 100644 --- a/indra/newview/skins/default/xui/it/floater_stats.xml +++ b/indra/newview/skins/default/xui/it/floater_stats.xml @@ -47,6 +47,12 @@ <stat_bar label="Oggetti a basso LOD" name="physicslodtasks"/> <stat_bar label="Memoria allocata" name="physicsmemoryallocated"/> </stat_view> + <stat_bar label="Script eseguiti" name="simpctscriptsrun"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="Tempo passaggio AI" name="simsimaistepmsec"/> + <stat_bar label="Passaggi silhouette saltati" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personaggi aggiornati" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_view label="Tempo (ms)" name="simperf"> <stat_bar label="Tempo totale Frame" name="simframemsec"/> <stat_bar label="Tempo netto" name="simnetmsec"/> diff --git a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml index e85030087c..c97a91bb3f 100644 --- a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml @@ -19,6 +19,8 @@ <button label="Default" label_selected="Default" name="Default"/> <button label="Vuoto" label_selected="Vuoto" name="Blank"/> <button label="Niente" label_selected="Niente" name="None"/> + <check_box initial_value="true" label="Anteprima dal vivo" name="apply_immediate_check"/> + <text name="preview_disabled" value="Anteprima disattivata"/> <filter_editor label="Filtro texture" name="inventory search editor"/> <check_box initial_value="false" label="Mostra cartelle" name="show_folders_check"/> <button label="Aggiungi" label_selected="Aggiungi" name="l_add_btn"/> @@ -30,5 +32,4 @@ </scroll_list> <button label="OK" label_selected="OK" name="Select"/> <button label="Annulla" label_selected="Annulla" name="Cancel"/> - <check_box initial_value="true" label="Applica adesso" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml index 57e65c3456..49b6453319 100644 --- a/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, Nuovo fetching elementi visibili dalla cache, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels </text> + <text name="total_time_refetch_all_cache_label"> + 16, Nuovo fetching di tutte le texture dalla cache, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + </text> <text name="total_time_refetch_vis_http_label"> - 16, Nuovo fetching elementi visibili da HTTP, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + 17, Nuovo fetching elementi visibili da HTTP, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + </text> + <text name="total_time_refetch_all_http_label"> + 18, Nuovo fetching di tutte le texture da HTTP, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels + </text> + <spinner label="19, Rapporto Texel/Pixel:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Fonte texture: </text> - <spinner label="17, Rapporto Texel/Pixel:" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="Solo HTTP" name="1"/> + </radio_group> <button label="Attiva" name="start_btn"/> <button label="Reimposta" name="clear_btn"/> <button label="Chiudi" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="Decodifica" name="decode_btn"/> <button label="Texture GL" name="gl_btn"/> <button label="Nuovo fetch visibili cache" name="refetchviscache_btn"/> + <button label="Nuovo fetching di tutta la cache" name="refetchallcache_btn"/> <button label="Nuovo fetch visibili HTTP" name="refetchvishttp_btn"/> + <button label="Nuovo fetching di tutto il contenuto HTTP" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index c963ac72e6..dd59035dd4 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -149,6 +149,12 @@ <panel.string name="text modify info 4"> Non puoi modificare questi oggetti </panel.string> + <panel.string name="text modify info 5"> + Questo oggetto non può essere modificato attraverso il confine di una regione + </panel.string> + <panel.string name="text modify info 6"> + Questi oggetti non possono essere modificati attraverso il confine di una regione + </panel.string> <panel.string name="text modify warning"> Devi selezionare tutto l'oggetto per impostare i permessi </panel.string> @@ -204,12 +210,12 @@ <combo_box.item label="Ingrandisci" name="Zoom"/> </combo_box> <check_box label="In vendita:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Copia" name="Copy"/> <combo_box.item label="Contenuto" name="Contents"/> <combo_box.item label="Originale" name="Original"/> </combo_box> - <spinner label="Prezzo: L$" name="Edit Cost"/> <check_box label="Mostra nella ricerca" name="search_check" tool_tip="Permetti che l'oggetto sia visibile nella ricerca"/> <panel name="perms_build"> <text name="perm_modify"> @@ -245,6 +251,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Attributi pathfinding: + </text> + </panel> </panel> <panel label="Oggetto" name="Object"> <check_box label="Bloccato" name="checkbox locked" tool_tip="Previene lo spostamento o la cancellazione dell'oggetto. Spesso utile mentre si costruisce per evitare involontarie modifiche."/> diff --git a/indra/newview/skins/default/xui/it/floater_top_objects.xml b/indra/newview/skins/default/xui/it/floater_top_objects.xml index 7d062db23b..d8ca7f4438 100644 --- a/indra/newview/skins/default/xui/it/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/it/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Ora </floater.string> - <floater.string name="scripts_mono_time_label"> - Ora 'Mono' - </floater.string> <floater.string name="top_colliders_title"> Oggetti con maggiori collisioni </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Nome" name="name" width="84"/> <scroll_list.columns label="Proprietario" name="owner" width="84"/> <scroll_list.columns label="Ubicazione" name="location" width="84"/> + <scroll_list.columns label="Lotto" name="parcel"/> <scroll_list.columns label="Ora" name="time" width="84"/> - <scroll_list.columns label="Ora (Mono)" name="mono_time" width="84"/> <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="Memoria (KB)" name="memory"/> </scroll_list> <text name="id_text"> ID oggetto: @@ -51,6 +49,10 @@ </text> <line_editor font="SansSerifSmall" left="90" name="owner_name_editor" width="280"/> <button label="Filtro" name="filter_owner_btn" width="150"/> + <text name="parcel_name_text"> + Lotto: + </text> + <button label="Filtra" name="filter_parcel_btn"/> <button label="Aggiorna" name="refresh_btn" width="150"/> <button label="Restituisci selezionato" name="return_selected_btn" width="150"/> <button label="Restituisci tutti" left="170" name="return_all_btn"/> diff --git a/indra/newview/skins/default/xui/it/menu_bottomtray.xml b/indra/newview/skins/default/xui/it/menu_bottomtray.xml deleted file mode 100644 index ddd6909136..0000000000 --- a/indra/newview/skins/default/xui/it/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Pulsante Parla" name="EnableVoiceChat"/> - <menu_item_check label="Tasto Gesture" name="ShowGestureButton"/> - <menu_item_check label="Tasto Movimento" name="ShowMoveButton"/> - <menu_item_check label="Tasto Visuale" name="ShowCameraButton"/> - <menu_item_check label="Tasto Foto" name="ShowSnapshotButton"/> - <menu_item_check label="Pulsante Costruisci" name="ShowBuildButton"/> - <menu_item_check label="Pulsante Cerca" name="ShowSearchButton"/> - <menu_item_check label="Pulsante Mappa" name="ShowWorldMapButton"/> - <menu_item_check label="Pulsante Mini mappa" name="ShowMiniMapButton"/> - <menu_item_call label="Taglia" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copia" name="NearbyChatBar_Copy"/> - <menu_item_call label="Incolla" name="NearbyChatBar_Paste"/> - <menu_item_call label="Elimina" name="NearbyChatBar_Delete"/> - <menu_item_call label="Seleziona tutto" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/it/menu_inventory.xml b/indra/newview/skins/default/xui/it/menu_inventory.xml index 4bf6be82fd..b31e35771d 100644 --- a/indra/newview/skins/default/xui/it/menu_inventory.xml +++ b/indra/newview/skins/default/xui/it/menu_inventory.xml @@ -68,6 +68,7 @@ <menu_item_call label="Elimina la cartella di sistema" name="Delete System Folder"/> <menu_item_call label="Inizia la conferenza chat" name="Conference Chat Folder"/> <menu_item_call label="Esegui" name="Sound Play"/> + <menu_item_call label="Copia SLurl" name="url_copy"/> <menu_item_call label="Informazioni sul punto di riferimento" name="About Landmark"/> <menu_item_call label="Riproduci in Second Life" name="Animation Play"/> <menu_item_call label="Esegui localmente" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/it/menu_mode_change.xml b/indra/newview/skins/default/xui/it/menu_mode_change.xml deleted file mode 100644 index 499dcf1873..0000000000 --- a/indra/newview/skins/default/xui/it/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Di base" name="BasicMode"/> - <menu_item_check label="Avanzata" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/it/menu_object.xml b/indra/newview/skins/default/xui/it/menu_object.xml index a172cf3b26..7f41e8937f 100644 --- a/indra/newview/skins/default/xui/it/menu_object.xml +++ b/indra/newview/skins/default/xui/it/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Modifica" name="Edit..."/> <menu_item_call label="Costruisci" name="Build"/> + <menu_item_call label="Mostra nei set collegati" name="show_in_linksets"/> + <menu_item_call label="Mostra nei personaggi" name="show_in_characters"/> <menu_item_call label="Apri" name="Open"/> <menu_item_call label="Siediti qui" name="Object Sit"/> <menu_item_call label="Alzati" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/it/menu_text_editor.xml b/indra/newview/skins/default/xui/it/menu_text_editor.xml index 4636ce9929..5b61da914e 100644 --- a/indra/newview/skins/default/xui/it/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/it/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(sconosciuto)" name="Suggestion 1"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 2"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 3"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 4"/> + <menu_item_call label="(sconosciuto)" name="Suggestion 5"/> + <menu_item_call label="Aggiungi al dizionario" name="Add to Dictionary"/> + <menu_item_call label="Aggiungi per ignorare" name="Add to Ignore"/> <menu_item_call label="Taglia" name="Cut"/> <menu_item_call label="Copia" name="Copy"/> <menu_item_call label="Incolla" name="Paste"/> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index f94b2f9a9e..547c5a9b73 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -28,6 +28,7 @@ <menu_item_call label="Preferenze..." name="Preferences"/> <menu_item_call label="Pulsanti barra strumenti..." name="Toolbars"/> <menu_item_call label="Nascondi tutti i controlli" name="Hide UI"/> + <menu_item_check label="Mostra elementi HUD" name="Show HUD Attachments"/> <menu_item_call label="Esci da [APP_NAME]" name="Quit"/> </menu> <menu label="Comunica" name="Communicate"> @@ -39,6 +40,7 @@ <menu_item_call label="Amici" name="My Friends"/> <menu_item_call label="Gruppi" name="My Groups"/> <menu_item_call label="Persone vicine" name="Active Speakers"/> + <menu_item_call label="Blocca lista" name="Block List"/> </menu> <menu label="Mondo" name="World"> <menu_item_call label="Crea punto di riferimento per questo luogo" name="Create Landmark Here"/> @@ -124,6 +126,11 @@ <menu_item_call label="Imposta gli script come in esecuzione" name="Set Scripts to Running"/> <menu_item_call label="Imposta script come non in esecuzione" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Set collegati..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personaggi..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Visualizza / test..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Opzioni" name="Options"> <menu_item_check label="Mostra autorizzazioni avanzate" name="DebugPermissions"/> <menu_item_check label="Seleziona solo i miei oggetti" name="Select Only My Objects"/> @@ -174,7 +181,6 @@ <menu_item_check label="Nascondi particelle" name="Hide Particles"/> <menu_item_check label="Nascondi selezionati" name="Hide Selected"/> <menu_item_check label="Evidenzia trasparenza" name="Highlight Transparent"/> - <menu_item_check label="Mostra elementi HUD" name="Show HUD Attachments"/> <menu_item_check label="Mostra mirino visuale soggettiva" name="ShowCrosshairs"/> </menu> <menu label="Modalità di rendering" name="Rendering Types"> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 9660c8f851..d5fdde4e7d 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -360,13 +366,19 @@ Inserisci il Nome utente del tuo avatar. Devi avere un account per entrare in [SECOND_LIFE]. Vuoi crearne uno adesso? <url name="url"> - https://join.secondlife.com/index.php?lang=it-IT + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Riprova" yestext="Crea un nuovo account"/> </notification> <notification name="InvalidCredentialFormat"> Immetti il nome utente oppure sia il nome che il cognome del tuo avatar nel campo del nome utente, quindi effettua nuovamente l'accesso. </notification> + <notification name="InvalidGrid"> + '[GRID]' non è un identificatore di griglia valido. + </notification> + <notification name="InvalidLocationSLURL"> + La tua posizione iniziale non ha specificato una griglia valida. + </notification> <notification name="DeleteClassified"> Cancella annuncio '[NAME]'? Non ci sono rimborsi per la tariffa pagata. @@ -598,6 +610,9 @@ Puoi unire al massimo [MAX] oggetti. Accertati che nessuno sia bloccato e che li possiedi tutti. </notification> + <notification name="CannotLinkPermanent"> + Gli oggetti non possono essere collegati attraverso i confini. + </notification> <notification name="CannotLinkDifferentOwners"> Impossibile unire perche non tutti gli oggetti hanno lo stesso proprietario. @@ -977,6 +992,41 @@ Offri l'amicizia a [NAME]? <button name="Cancel" text="Annulla"/> </form> </notification> + <notification label="Aggiungi lista di sostituzione automatica" name="AddAutoReplaceList"> + Nome per la nuova lista: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Rinomina lista di sostituzione automatica" name="RenameAutoReplaceList"> + Il nome '[DUPNAME]' è già in uso + Inserisci un nuovo nome univoco: + <form name="form"> + <button name="ReplaceList" text="Sostituisci lista corrente"/> + <button name="SetName" text="Usa nuovo nome"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + La parola chiave deve essere una sola parola e la sostituzione non può essere vuota. + </notification> + <notification name="InvalidAutoReplaceList"> + L'elenco di sostituzione non è valido. + </notification> + <notification name="SpellingDictImportRequired"> + Devi specificare un file, un nome e una lingua. + </notification> + <notification name="SpellingDictIsSecondary"> + Sembra che il dizionario [DIC_NAME] non includa un file "aff"; ciò indica che di tratta di un dizionario "secondario". +Può essere usato come dizionario aggiuntivo, ma non come dizionario principale. + +Vedi https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Copia non eseguita da + [FROM_NAME] + a + [TO_NAME] + </notification> <notification label="Salva vestiario" name="SaveOutfitAs"> Salva gli abiti che indosso come nuovo vestiario: <form name="form"> @@ -1157,7 +1207,7 @@ a '[THIS_GPU]' Sei stato trasferito in una regione vicina. </notification> <notification name="AvatarMovedLast"> - La tua ultima posizione non è al momento disponibile. + La posizione richiesta non è al momento disponibile. Sei stato trasferito in una regione vicina. </notification> <notification name="AvatarMovedHome"> @@ -1176,8 +1226,7 @@ Puoi comunque usare [SECOND_LIFE] normalmente e gli altri residenti ti vedranno L'installazione di [APP_NAME] è terminata. Se questa è la prima volta che usi [SECOND_LIFE], devi creare un account prima che tu possa effettuare l'accesso. -Vuoi tornare a [http://join.secondlife.com secondlife.com] per creare un nuovo account? - <usetemplate name="okcancelbuttons" notext="Continua" yestext="Nuovo Account..."/> + <usetemplate name="okcancelbuttons" notext="Continua" yestext="Crea account..."/> </notification> <notification name="LoginPacketNeverReceived"> Ci sono problemi di connessione. È possibile che ci siano problemi con la tua connessione Internet oppure sulla [SECOND_LIFE_GRID]. @@ -1698,83 +1747,128 @@ Cambierà migliaia di regioni e produrrà seri problemi ai vari server. <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Non sei ammesso in questa regione a causa della tua categoria di accesso. Questo può risultare da una mancanza di informazioni necessarie per convalidare la tua età. - -Verifica di avere installato l'ultima versione del programma e vai alla Knowledge Base per ulteriori informazioni su come accedere nelle zone con tale categoria di accesso. + La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Non sei ammesso in questa regione a causa della tua categoria d'accesso. - -Vuoi andare alla Knowledge Base per ulteriori informazioni sulle categorie di accesso? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Non posso entrare in questa regione a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/> + <usetemplate ignoretext="Attraversamento regione: la regione che cerchi di visitare include contenuti accessibili solo ad adulti." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Non sei ammesso in questa regione a causa della tua categoria d'accesso. + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Non ti è consentito entrare in quella regione a causa della categoria di accesso impostata nelle preferenze. - -Per entrare nella regione, dovrai modificare la tua categoria di accesso. Ciò ti consentirà inoltre di effettuare ricerche di contenuti di categoria [REGIONMATURITY]. Per annullare le modifiche in un secondo momento, vai a Io > Preferenze > Generali. + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le tue preferenze o annullare. Dopo aver modificato le preferenze, prova nuovamente ad entrare nella regione. + <form name="form"> + <button name="OK" text="Modifica preferenze"/> + <button default="true" name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Attraversamento regione: La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Si è verificato un problema con il teleport a causa di un errore di sincronizzazione delle preferenze con il server. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Teleport: la regione che cerchi di visitare include contenuti accessibili solo ad adulti." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e continuare con il teleport oppure annullarlo. <form name="form"> - <button name="OK" text="Cambia preferenza"/> - <button default="true" name="Cancel" text="Chiudi"/> - <ignore name="ignore" text="La categoria di accesso impostata mi impedisce di entrare in una regione"/> + <button name="OK" text="Modifica e continua"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Teleport (riavviabile): La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le tue preferenze o annullare il teleport. Dopo aver modificato le preferenze, prova nuovamente a teletrasportarti nella regione. + <form name="form"> + <button name="OK" text="Modifica preferenze"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Teleport (non riavviabile): La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Si è verificato un problema con il teleport a causa di un errore di sincronizzazione delle preferenze con il server. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - La tua categoria di accesso attuale è [RATING]. + Non riceverai più notifiche se stai per visitare una regione con contenuti [RATING]. In futuro potrai modificare le preferenze relative ai contenuti selezionando Io > Preferenze > Generale nella barra del menu. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Non è stato possibile modificare le preferenze per visualizzare contenuti [PREFERRED_MATURITY]. le preferenze sono state ripristinate per consentire la visualizzazione di contenuti [ACTUAL_MATURITY]. Puoi cercare di modificare nuovamente le preferenze selezionando Io > Preferenze > Generale nella barra del menu. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Non puoi prendere possesso di questo terreno a causa della tua categoria di accesso. Questo può essere dovuto ad una mancanza di informazioni valide che confermino la tua età. - -Verifica di avere installato l'ultima versione del programma e vai alla Knowledge Base per informazioni sull'accesso ad aree con queste categorie di accesso. + Il terreno che desideri richiedere ha una categoria di accesso maggiore di quella indicata nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Non puoi prendere possesso di questa terra a causa delle preferenze sulle categorie di accesso. - -Vuoi andare alla Knowledge Base per maggiori informazioni sulle categorie di accesso? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Solo gli adulti possono richiedere questo terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Non posso richiedere questo terreno a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/> + <usetemplate ignoretext="Solo gli adulti possono richiedere questo terreno." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Non puoi prendere possesso di questa terra a causa della tua categoria di accesso. + Il terreno che desideri richiedere include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Il terreno che cerchi di richiedere include contenuti [REGIONMATURITY], accessibili solo ad adulti. </notification> <notification name="LandClaimAccessBlocked_Change"> - Non puoi richiedere questo terreno a causa della tua categoria di accesso. - -Puoi cliccare su Cambia preferenze per modificare la categoria di accesso e quindi riuscire ad entrare. Da adesso potrai accedere ai contenuti [REGIONMATURITY] ed effettuare ricerche in questa categoria. Se in seguito tu volessi cambiare di nuovo le tue impostazioni, apri la finestra di dialogo da Io > Preferenze > Generale. - <usetemplate ignoretext="Le mie preferenze di categoria di accesso mi impediscono di richiedere terreno" name="okcancelignore" notext="Chiudi" yestext="Cambia le preferenze"/> + Il terreno che desideri richiedere include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e quindi cercare di richiedere nuovamente il terreno. + <form name="form"> + <button name="OK" text="Modifica preferenze"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Il terreno che cerchi di richiedere include contenuti esclusi nelle preferenze."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Non puoi acquistare questo terreno a causa della tua categoria di accesso. Questo può essere dovuto ad una mancanza di informazioni valide che confermino la tua età. - -Verifica di avere installato l'ultima versione del programma e vai alla Knowledge Base per informazioni sull'accesso ad aree con queste categorie di accesso. + Il terreno che desideri acquistare ha una categoria di accesso maggiore di quella indicata nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Non puoi acquistare questo terreno a causa della tua categoria di accesso. - -Vuoi andare alla Knowledge Base per maggiori informazioni sulle categorie di accesso? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Solo gli adulti possono acquistare questo terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Non posso acquistare questo terreno a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/> + <usetemplate ignoretext="Solo gli adulti possono acquistare questo terreno." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Non puoi acquistare questa land a causa della tua categoria di accesso. + Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], accessibili solo ad adulti. </notification> <notification name="LandBuyAccessBlocked_Change"> - Non puoi acquistare questo terreno a causa della tua categoria di accesso. - -Puoi cliccare su Cambia preferenze per modificare la categoria di accesso e quindi riuscire ad entrare. Da adesso potrai accedere ai contenuti [REGIONMATURITY] ed effettuare ricerche in questa categoria. Se in seguito tu volessi cambiare di nuovo le tue impostazioni, apri la finestra di dialogo da Io > Preferenze > Generale. - <usetemplate ignoretext="Le mie Preferenze di accesso mi impediscono di acquistare terreno" name="okcancelignore" notext="Chiudi" yestext="Cambia le preferenze"/> + Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e quindi cercare di acquistare nuovamente il terreno. + <form name="form"> + <button name="OK" text="Modifica preferenze"/> + <button name="Cancel" text="Annulla"/> + <ignore name="ignore" text="Il terreno che cerchi di acquistare include contenuti esclusi nelle preferenze."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Hai selezionato troppi prim. Seleziona non più di [MAX_PRIM_COUNT] prim e riprova @@ -1829,10 +1923,9 @@ Pubblica questo annuncio adesso per [AMOUNT]L$? </form> </notification> <notification label="Cambiato il contenuto Moderato" name="RegionMaturityChange"> - La classificazione di questa regione è stata aggiornata. -Un periodo di tempo è necessario prima che la modifica venga integrata nella mappa. - -Per accedere a regioni per adulti, i residenti devono avere un Account verificato, mediante verifica dell'età oppure mediante verifica della modalità di pagamento. + La classificazione di questa regione è stata modificata. +Prima che questa modifica venga integrata nella mappa potrebbe essere necessario un po' di tempo. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Versione voice non compatibile" name="VoiceVersionMismatch"> Questa versione di [APP_NAME] non è compatibile con la funzionalità di chat vocale in questa regione. Affinché la chat vocale funzioni correttamente, dovrai aggiornare [APP_NAME]. @@ -2123,14 +2216,11 @@ Inseriscilo in una pagina web per dare ad altri un accesso facile a questa ubica <usetemplate ignoretext="Indossare gli abiti che creo mentre modifico il mio aspetto" name="okcancelignore" notext="No" yestext="Si"/> </notification> <notification name="NotAgeVerified"> - Per accedere ai contenuti e alle aree per adulti in Second Life devi avere almeno 18 anni. Visita la pagina di verifica dell'età per confermare di avere almeno 18 anni. -Verrà avviato il browser Web. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Non ho verificato la mia età" name="okcancelignore" notext="Annulla" yestext="Passa alla verifica dell'età"/> + Il luogo che desideri visitare è limitato a persone di almeno 18 anni di età. + <usetemplate ignoretext="Non ho l'età necessaria per visitare aree limitate." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Posizione limitata a persone maggiori di 18 anni di età. </notification> <notification name="Cannot enter parcel: no payment info on file"> Per poter visitare questa zona devi avere devi aver fornito informazioni di pagamento a Linden Lab. Vuoi andare sul sito di [SECOND_LIFE] ed impostarle? @@ -2391,6 +2481,23 @@ Qui non puoi volare. <notification name="NoBuild"> In questa zona è proibita la costruzione. Qui non puoi costruire né rezzare oggetti. </notification> + <notification name="PathfindingDirty"> + La regione ha modifiche di pathfinding in sospeso. Se hai le autorizzazioni necessarie per la costruzione puoi eseguire il rebake facendo clic sul pulsante “Rebake regione”. + </notification> + <notification name="DynamicPathfindingDisabled"> + Il pathfinding dinamico non è attivato in questa regione. Gli oggetti scriptati che usano chiamate LSL di pathfinding potrebbero non funzionare come previsto in questa regione. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Se modifichi alcuni oggetti in questa regione, ciò potrebbe causare il comportamento errato di altri oggetti in movimento. Per fare in modo che gli oggetti in movimento si comportino correttamente, fai clic sul pulsante "Rebake regione". Per maggiori informazioni, seleziona la guida + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Guida" ignoretext="Se modifichi alcuni oggetti in questa regione, ciò potrebbe causare il comportamento errato di altri oggetti in movimento." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Si è verificato un errore. Potrebbe trattarsi di un problema di rete o del server, oppure potresti non avere le autorizzazioni necessarie per la costruzione. A volte il problema viene risolto uscendo ed eseguendo nuovamente l'accesso. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> In questo lotto non si possono vedere avatar e chat di testo presenti in altri lotti. Non puoi vedere altri residenti fuori dal lotto e loro non possono vederti. Viene bloccata anche la normale chat di testo sul canale 0. </notification> @@ -2409,9 +2516,7 @@ Qui funzionano soltanto gli script del proprietario del terreno. Puoi solo richiedere terreni pubblici nella regione in cui sei posizionato. </notification> <notification name="RegionTPAccessBlocked"> - Non puoi entrare in quella regione a causa della tua categoria di accesso. Può essere necessario validare l'età e/o installare l'ultima versione del programma. - -Visita la Knowledge Base per informazioni sull'accesso alle aree con queste categorie di accesso. + La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io > Preferenze > Generale. </notification> <notification name="URBannedFromRegion"> Tu hai l'accesso bloccato a questa regione. @@ -2422,8 +2527,11 @@ Visita la Knowledge Base per informazioni sull'accesso alle aree con queste <notification name="ImproperPaymentStatus"> Non hai una impostazioni di pagamento corrette per entrare in questa regione. </notification> + <notification name="MustGetAgeRegion"> + Per poter entrare in questa regione devi avere almeno 18 anni. + </notification> <notification name="MustGetAgeParcel"> - Devi essere di età verificata per entrare in questa terra. + Per poter entrare in questo lotto devi avere almeno 18 anni. </notification> <notification name="NoDestRegion"> Non è stata trovata nessuna regione di destinazione. @@ -2525,12 +2633,33 @@ Riprova tra qualche istante. <notification name="TeleportOffered"> [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teleport"/> <button name="Cancel" text="Cancella"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Questa regione include contenuti [REGION_CONTENT_MATURITY], ma le tue preferenze attuali escludono i contenuti [REGION_CONTENT_MATURITY]. Puoi modificare le preferenze e continuare con il teleport oppure annullarlo. + <form name="form"> + <button name="Teleport" text="Modifica e continua"/> + <button name="Cancel" text="Annulla"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Questa regione include però contenuti accessibili solo agli adulti. + </notification> <notification name="TeleportOfferSent"> Offerta di Teleport inviata a [TO_NAME] </notification> @@ -2934,6 +3063,10 @@ Hai caricato una texture [RESOLUTION] completata per '[BODYREGION]' do ( In esistenza da [EXISTENCE] secondi) Hai aggiornato localmente una texture [RESOLUTION] completata per '[BODYREGION]' dopo [TIME] secondi. </notification> + <notification name="LivePreviewUnavailable"> + Non possiamo mostrare un'anteprima di questa texture perché non ne è consentita la copia e/o il trasferimento. + <usetemplate ignoretext="Avvisami se la modalità Anteprima dal vivo non è disponibile per texture per cui non è consentita la copia e/o il trasferimento." name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Sei sicuro di volere uscire dalla chiamata? <usetemplate ignoretext="Conferma prima di uscire dalla chiamata" name="okcancelignore" notext="No" yestext="Sì"/> @@ -3105,6 +3238,62 @@ Clicca e trascina dovunque nel mondo per ruotare la visuale Questa azione cancellerà tutte le voci di menu e i pulsanti. Per visualizzarli nuovamente cliccare ancora [SHORTCUT]. <usetemplate ignoretext="Conferma prima di nascondere l'interfaccia" name="okcancelignore" notext="Annulla" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma di alcuni set collegati verrà commutato." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Vuoi continuare? + <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati a causa di limitazioni nelle autorizzazioni per i set collegati." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. + +Vuoi continuare? + <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato a causa di limitazioni nelle autorizzazioni per i set collegati." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. Il tipo di utilizzo di questi set collegati non cambierà. + +Vuoi continuare? + <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati a causa delle limitazioni nelle autorizzazioni per il set collegato e perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + L'indicatore oggetto fantasma di alcuni set collegati verrà commutato. + +Alcuni set collegati selezionati non possono essere impostati su '[REQUESTED_TYPE]' a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su '[RESTRICTED_TYPE]'. + +Alcuni set collegati selezionati non possono essere impostati a '[REQUESTED_TYPE]' perché la forma è non-convessa. Il tipo di utilizzo di questi set collegati non cambierà. + +Vuoi continuare? + <usetemplate ignoretext="L'indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato a causa delle limitazioni nelle autorizzazioni per il set collegato e perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + L'oggetto selezionato influenza il navmesh. Se lo si trasforma in un percorso flessibile verrà rimosso dal navmesh. + <usetemplate ignoretext="L'oggetto selezionato influenza il navmesh. Se lo si trasforma in un percorso flessibile verrà rimosso dal navmesh." name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Non sembra che tu abbia i requisiti hardware adeguati per [APP_NAME]. [APP_NAME] richiede una scheda grafica OpenGL con supporto multitexture. Se ne hai una in dotazione, accertati di avere i driver, i service pack e i patch più recenti per la scheda grafica e per il sistema operativo. @@ -3141,4 +3330,12 @@ Gli aggiornamenti futuri per questo file sono disattivati. Tentativo di aggiungere un file immagine [FNAME] non valido o non leggibile che non è stato possibile aprire o decodificare. Tentativo annullato. </notification> + <notification name="PathfindingReturnMultipleItems"> + Stai per restituire [NUM_ITEMS] elementi. Vuoi continuare? + <usetemplate ignoretext="Sei sicuro di volere restituire più oggetti?" name="okcancelignore" notext="No" yestext="Sì"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Stai per cancellare [NUM_ITEMS] elementi. Vuoi continuare? + <usetemplate ignoretext="Sei sicuro di volere eliminare più oggetti?" name="okcancelignore" notext="No" yestext="Sì"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/it/panel_bottomtray.xml b/indra/newview/skins/default/xui/it/panel_bottomtray.xml deleted file mode 100644 index 3d12473c87..0000000000 --- a/indra/newview/skins/default/xui/it/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Accende o spegne il microfono"/> - <string name="VoiceControlBtnToolTip" value="Mostra o nasconde il pannello di regolazione voce"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Parla" label_selected="Parla" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gesture" name="Gesture" tool_tip="Mostra o nasconde le gesture"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Sposta" name="movement_btn" tool_tip="Mostra o nasconde i comandi del movimento"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Visuale" name="camera_btn" tool_tip="Mostra o nasconde le regolazioni della visuale"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Scatta una foto"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Costruisci" name="build_btn" tool_tip="Mostra o nasconde gli strumenti di costruzione"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Cerca" name="search_btn" tool_tip="Mostra o nasconde la ricerca"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Mappa" name="world_map_btn" tool_tip="Mostra o nasconde la mappa del mondo"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini mappa" name="mini_map_btn" tool_tip="Mostra o nasconde la mini mappa"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversazioni"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notifiche"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_group_invite.xml b/indra/newview/skins/default/xui/it/panel_group_invite.xml index e3cb3c1092..1b57eba3f0 100644 --- a/indra/newview/skins/default/xui/it/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/it/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Alcuni dei residenti selezionati sono già nel gruppo, pertanto l'invito non verrà loro spedito. </panel.string> + <panel.string name="invite_selection_too_large"> + Invito di gruppo non inviato: troppi residenti selezionati Gli inviti di gruppo possono essere inviati a un massimo di 100 persone per ciascuna richiesta. + </panel.string> <text name="help_text"> Puoi selezionare più residenti da invitare nel tuo gruppo. Per iniziare, clicca su Apri il selettore di residenti. </text> diff --git a/indra/newview/skins/default/xui/it/panel_login.xml b/indra/newview/skins/default/xui/it/panel_login.xml index f88230ed11..2afde40940 100644 --- a/indra/newview/skins/default/xui/it/panel_login.xml +++ b/indra/newview/skins/default/xui/it/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=it </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ACCEDI + </text> <text name="username_text"> Nome utente: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Password: </text> - <check_box label="Ricorda password" name="remember_check"/> - <button label="Accedi" name="connect_btn"/> - <text name="mode_selection_text"> - Modalità: - </text> - <combo_box name="mode_combo" tool_tip="Seleziona la modalità. Seleziona Di base per esplorare facilmente e rapidamente e per la chat. Seleziona Avanzata per accedere ad altre funzionalità."> - <combo_box.item label="Di base" name="Basic"/> - <combo_box.item label="Avanzate" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Inizia da: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Scrivi nome regione>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Iscriviti + <layout_panel name="links_login_panel"> + <text name="login_help"> + Ti serve aiuto con la fase di accesso? </text> <text name="forgot_password_text"> Hai dimenticato il nome utente o la password? </text> - <text name="login_help"> - Ti serve aiuto con la fase di accesso? + <button label="Accedi" name="connect_btn"/> + <check_box label="Ricorda password" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREA IL TUO ACCOUNT </text> + <button label="Inizia adesso" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/it/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..432754076a --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="Rebake regione" name="navmesh_btn" tool_tip="Fai clic per eseguire rebake sul navmesh della regione"/> + <button label="Richiesta rebake" name="navmesh_btn_sending" tool_tip="Invio richiesta rebake al server."/> + <button label="Rebake regione in corso" name="navmesh_btn_baking" tool_tip="Rebake della regione in corso. Al termine, questo pulsante non sarà più visibile."/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml index 7f5992b584..0c9c4027e5 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="Chat IM" name="EnableIMChatPopups" tool_tip="Seleziona per vedere una finestra popup quando arriva un messaggio IM"/> <spinner label="Durata chat vicine:" name="nearby_toasts_lifetime"/> <spinner label="Durata dissolvenza chat vicine:" name="nearby_toasts_fadingtime"/> - <button label="Impostazioni traduzione chat" name="ok_btn"/> + <button label="Traduzione..." name="ok_btn"/> + <button label="Sostituzione automatica..." name="autoreplace_showgui"/> + <button label="Correzione ortografica..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_region_debug.xml b/indra/newview/skins/default/xui/it/panel_region_debug.xml index 45b3a016f4..aba60d03aa 100644 --- a/indra/newview/skins/default/xui/it/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/it/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" left="297" name="top_scripts_help"/> <button label="Riavvia la regione" name="restart_btn" tool_tip="Dai 2 minuti di tempo massimo e fai riavviare la regione"/> <button label="?" name="restart_help"/> - <button label="Ritarda il riavvio" name="cancel_restart_btn" tool_tip="Ritarda il riavvio della regione di un'ora"/> + <button label="Annulla riavvio" name="cancel_restart_btn" tool_tip="Annulla riavvio regione"/> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_region_estate.xml b/indra/newview/skins/default/xui/it/panel_region_estate.xml index da6b6b277f..98d9b86cfc 100644 --- a/indra/newview/skins/default/xui/it/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/it/panel_region_estate.xml @@ -26,7 +26,7 @@ Consenti l'accesso solo ai Residenti che: </text> <check_box label="Hanno memorizzato le informazioni per l'addebito" name="limit_payment" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/> - <check_box label="Hanno verificato l'età" name="limit_age_verified" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono aver verificato la propria età. Vedi [SUPPORT_SITE] per maggiori informazioni."/> + <check_box label="Hanno almeno 18 anni" name="limit_age_verified" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/> <check_box label="Permetti la chat voice" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <check_box label="Permetti teleport diretto" name="allow_direct_teleport"/> diff --git a/indra/newview/skins/default/xui/it/panel_region_texture.xml b/indra/newview/skins/default/xui/it/panel_region_texture.xml deleted file mode 100644 index 1337ed18ca..0000000000 --- a/indra/newview/skins/default/xui/it/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Texture del terreno" name="Textures"> - <text name="region_text_lbl"> - Regione: - </text> - <text name="region_text"> - sconosciuto - </text> - <text name="detail_texture_text" width="380"> - Texture del terreno (è necessario siano 512x512, 24 bit .tga files) - </text> - <text name="height_text_lbl"> - 1 (Bassa) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Alta) - </text> - <text name="height_text_lbl5"> - Range di elevazione della texture - </text> - <text name="height_text_lbl6"> - Nordovest - </text> - <text name="height_text_lbl7"> - Nordest - </text> - <text name="height_text_lbl8"> - Sudovest - </text> - <text name="height_text_lbl9"> - Sudest - </text> - <spinner label="Bassa" name="height_start_spin_0"/> - <spinner label="Bassa" name="height_start_spin_1"/> - <spinner label="Bassa" name="height_start_spin_2"/> - <spinner label="Bassa" name="height_start_spin_3"/> - <spinner label="Alta" name="height_range_spin_0"/> - <spinner label="Alta" name="height_range_spin_1"/> - <spinner label="Alta" name="height_range_spin_2"/> - <spinner label="Alta" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Questi valori indicano la gamma di miscele per le texture di cui sopra. - </text> - <text name="height_text_lbl11"> - Misurato in metri, il valore BASSO è la MASSIMA altezza della texture n. 1, e il valore ALTO è l'altezza MINIMA della texture n. 4. - </text> - <text name="height_text_lbl12"> - Texture #1, e il valore più ALTO all'altezza MINIMA della Texture #4. - </text> - <button label="Applica" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_side_tray.xml b/indra/newview/skins/default/xui/it/panel_side_tray.xml deleted file mode 100644 index e0143088a5..0000000000 --- a/indra/newview/skins/default/xui/it/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Apri/chiudi la barra laterale." name="sidebar_openclose" tab_title="Apri/chiudi la barra laterale"/> - <sidetray_tab description="Casa." name="sidebar_home" tab_title="Home"> - <panel label="casa" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Modifica il tuo profilo pubblico e i preferiti." name="sidebar_me" tab_title="Il mio profilo"> - <panel_container name="panel_container"> - <panel label="Io" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trova amici, contatti e persone nelle vicinanze." name="sidebar_people" tab_title="Persone"> - <panel_container name="panel_container"> - <panel label="Profilo del gruppo" name="panel_group_info_sidetray"/> - <panel label="Residenti e oggetti bloccati" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Trova luoghi dove andare e luoghi già visitati." label="Luoghi" name="sidebar_places" tab_title="Luoghi"> - <panel label="Luoghi" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Sfoglia il tuo inventario." name="sidebar_inventory" tab_title="Il mio inventario"> - <panel label="Modifica inventario" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Cambia il tuo aspetto ed il tuo look attuale." name="sidebar_appearance" tab_title="Il mio aspetto"> - <panel label="Modifica aspetto fisico" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml new file mode 100644 index 0000000000..bc17fc0c89 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater" width="220"> + <button left="197" name="prefs_btn"/> + <slider label="Principale" label_width="60" name="System Volume" width="160"/> + <slider label="Pulsanti" label_width="60" name="UI Volume" width="160"/> + <slider label="Ambiente" label_width="60" name="Wind Volume" width="160"/> + <slider label="Suoni" label_width="60" name="SFX Volume" width="160"/> + <check_box name="gesture_audio_play_btn" tool_tip="Attiva suoni dai gesti"/> + <slider label="Musica" label_width="60" name="Music Volume" width="160"/> + <check_box name="enable_music" tool_tip="Attiva streaming musica"/> + <slider label="Multimedia" label_width="60" name="Media Volume" width="160"/> + <check_box name="enable_media" tool_tip="Attiva streaming multimediale"/> + <slider label="Voce" label_width="60" name="Voice Volume" width="160"/> + <check_box name="enable_voice_check" tool_tip="Attiva chat vocale"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml index 900a65956b..2b3ea0fb83 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (sconosciuto) </panel.string> + <panel.string name="unknown_multiple"> + (sconosciuto / multiplo) + </panel.string> <panel.string name="public"> (pubblico) </panel.string> diff --git a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml index cfabdc81b0..8a0f93e650 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Non puoi modificare questi oggetti </panel.string> + <panel.string name="text modify info 5"> + Questo oggetto non può essere modificato attraverso il confine di una regione + </panel.string> + <panel.string name="text modify info 6"> + Questi oggetti non possono essere modificati attraverso il confine di una regione + </panel.string> <panel.string name="text modify warning"> Questo oggetto ha parti collegate </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Prezzo: L$" name="Edit Cost"/> <check_box label="Mostra nella ricerca" name="search_check" tool_tip="Permetti alle persone di vedere questo oggetto nei risultati della ricerca"/> + <text name="pathfinding_attributes_label"> + Attributi pathfinding: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 11accb5f08..fb1e387468 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -134,7 +134,7 @@ Esci </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=it-IT + http://join.secondlife.com/index.php?lang=it-IT&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Il viewer utilizzato non è più in grado di accedere a Second Life. Visita la parina seguente per scaricare un nuovo viewer: @@ -997,6 +997,9 @@ Prova ad accedere nuovamente tra un minuto. <string name="script_files"> Script </string> + <string name="dictionary_files"> + Dizionari + </string> <string name="AvatarSetNotAway"> Imposta come non assente </string> @@ -1396,6 +1399,12 @@ Prova ad accedere nuovamente tra un minuto. <string name="InvFolder favorite"> I miei preferiti </string> + <string name="InvFolder Favorites"> + I miei preferiti + </string> + <string name="InvFolder favorites"> + I miei preferiti + </string> <string name="InvFolder Current Outfit"> Abbigliamento attuale </string> @@ -1411,6 +1420,12 @@ Prova ad accedere nuovamente tra un minuto. <string name="InvFolder Meshes"> Reticoli </string> + <string name="InvFolder Received Items"> + Oggetti ricevuti + </string> + <string name="InvFolder Merchant Outbox"> + Casella venditore in uscita + </string> <string name="InvFolder Friends"> Amici </string> @@ -3786,6 +3801,12 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Avatar visibili e chat consentita fuori di questo lotto </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Gli oggetti che si muovono potrebbero non comportarsi correttamente in questa regione fino a quando non viene eseguito il rebake della regione. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Il pathfinding dinamico non è attivato in questa regione. + </string> <string name="UpdaterWindowTitle"> Aggiornamento [APP_NAME] </string> @@ -4916,6 +4937,21 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. <string name="Normal"> Normale </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Nessuno + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Influenza il navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personaggio + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Multiple) + </string> <string name="snapshot_quality_very_low"> Molto basso </string> @@ -4931,4 +4967,10 @@ Prova a racchiudere il percorso dell'editor in doppie virgolette. <string name="snapshot_quality_very_high"> Molto alto </string> + <string name="TeleportMaturityExceeded"> + Il Residente non può visitare questa regione. + </string> + <string name="UserDictionary"> + [User] + </string> </strings> diff --git a/indra/newview/skins/default/xui/it/teleport_strings.xml b/indra/newview/skins/default/xui/it/teleport_strings.xml index f485212290..bd967ebcc4 100644 --- a/indra/newview/skins/default/xui/it/teleport_strings.xml +++ b/indra/newview/skins/default/xui/it/teleport_strings.xml @@ -43,6 +43,9 @@ Per ripetere l'esercitazione, visita 'Welcome Island Public'. <message name="no_inventory_host"> L'inventario è temporaneamente inaccessibile. </message> + <message name="MustGetAgeRegion"> + Per poter entrare in questa regione devi avere almeno 18 anni. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -78,5 +81,8 @@ Per ripetere l'esercitazione, visita 'Welcome Island Public'. <message name="requesting"> Avvio teletrasporto.... </message> + <message name="pending"> + Teleport in sospeso... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index 3c7a210a22..6d5df75645 100644 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -66,27 +66,26 @@ Qt Webkit バージョン: [QT_WEBKIT_VERSION] </panel> <panel label="ライセンス" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion -APR Copyright (C) 2000-2004 The Apache Software Foundation -Collada DOM Copyright 2005 Sony Computer Entertainment Inc. -cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion +APR Copyright (C) 2011 The Apache Software Foundation +Collada DOM Copyright 2006 Sony Computer Entertainment Inc. +cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. -FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). +FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. -ogg/vorbis Copyright (C) 2001, Xiphophorus -OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. -PCRE Copyright (c) 1997-2008 University of Cambridge +ogg/vorbis Copyright (C) 2002, Xiphophorus +OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. +PCRE Copyright (c) 1997-2012 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. -zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. -google-perftools Copyright (c) 2005, Google Inc. +zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. Second Life ビューワでは Havok (TM) Physics が使用されています。(c)Copyright 1999-2010 Havok.com Inc. (and its Licensors).無断複写・複製・転載を禁じます。詳細については www.havok.com をご参照ください。 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 7c87bad5a3..3b4b5ed070 100644 --- a/indra/newview/skins/default/xui/ja/floater_about_land.xml +++ b/indra/newview/skins/default/xui/ja/floater_about_land.xml @@ -464,7 +464,7 @@ 次の住人にのみアクセスを許可: </text> <check_box label="支払情情報が登録されている [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="支払情報が登録されていないと、この区画にアクセスすることはできません。詳細については、[SUPPORT_SITE] をご覧ください。"/> - <check_box label="年齢確認が済んでいる [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="この区画にアクセスするには、年齢確認を済ませる必要があります。詳細については、[SUPPORT_SITE] をご覧ください。"/> + <check_box label="18 才以上です [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="この区画にアクセスするには、18 才以上でなければなりません。詳細については、[SUPPORT_SITE] をご覧ください。"/> <check_box label="グループのアクセスを許可:[GROUP]" name="GroupCheck" tool_tip="「一般」タブで、グループを選択してください。"/> <check_box label="入場許可を販売:" name="PassCheck" tool_tip="この区画への一時的なアクセスを許可します。"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_preview.xml deleted file mode 100644 index 548d24097f..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> - <floater.string name="failed_to_initialize"> - モーションを初期化できませんでした - </floater.string> - <floater.string name="anim_too_long"> - アニメーションファイルの長さは[LENGTH]秒です。 - -アニメーションの最大の長さは[MAX_LENGTH]秒です。 - </floater.string> - <floater.string name="failed_file_read"> - アニメーションファイルを読み取れません。 - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - Ok - </floater.string> - <floater.string name="E_ST_EOF"> - 不完全なファイル。 - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - 制約定義を読みとれません。 - </floater.string> - <floater.string name="E_ST_NO_FILE"> - BVH ファイルを開けません。 - </floater.string> - <floater.string name="E_ST_NO_HIER"> - 無効な HIERARCHY ヘッダーです。. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - ROOT または JOINT が見つかりません。 - </floater.string> - <floater.string name="E_ST_NO_NAME"> - JOINT ネームを取得できません。 - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - OFFSET が見つかりません。 - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - CHANNELS が見つかりません。 - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - 回転順序を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - 回転軸を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - MOTION が見つかりません。 - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - フレーム数を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - フレームタイムを取得できません。 - </floater.string> - <floater.string name="E_ST_NO_POS"> - ポジション値を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_ROT"> - 回転値を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - ファイルを開けません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - 読みとることができません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - 読みとることができません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - 読みとることができません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - 読みとることができません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - 読みとることができません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - 読みとることができません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Mergechild 名を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Mergeparent 名を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - プロパティ値を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - ループ値を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - easeln 値を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - easeOut 値を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Hand morph 値を取得できません。 - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - エモート名を読みとれません。 - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - ルートジョイント名が無効です。「hip」を使用してください。 - </floater.string> - <text name="name_label"> - 名前: - </text> - <text name="description_label"> - 説明: - </text> - <spinner label="優先順位" name="priority" tool_tip="このアニメーションがどのアニメーションを上書きするかを決めます"/> - <check_box label="ループ" name="loop_check" tool_tip="このアニメーションをループ再生します"/> - <spinner label="イン(%)" label_width="45" left="60" name="loop_in_point" tool_tip="アニメーションのループ復帰点を設定します" width="100"/> - <spinner label="アウト(%)" label_width="50" left="170" name="loop_out_point" tool_tip="アニメーションのループ終了点を設定します" width="100"/> - <text name="hand_label"> - 手の動き - </text> - <combo_box label="" name="hand_pose_combo" tool_tip="アニメーション再生中の手の動きを決めます"> - <combo_box.item label="広げる" name="Spread"/> - <combo_box.item label="リラックス" name="Relaxed"/> - <combo_box.item label="指を指す・両手" name="PointBoth"/> - <combo_box.item label="拳" name="Fist"/> - <combo_box.item label="リラックス・左" name="RelaxedLeft"/> - <combo_box.item label="指を指す・左" name="PointLeft"/> - <combo_box.item label="拳を上げる・左" name="FistLeft"/> - <combo_box.item label="リラックス・右" name="RelaxedRight"/> - <combo_box.item label="指を指す・右" name="PointRight"/> - <combo_box.item label="拳を上げる・右" name="FistRight"/> - <combo_box.item label="敬礼・右" name="SaluteRight"/> - <combo_box.item label="タイピング" name="Typing"/> - <combo_box.item label="ピース・右" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - 表現 - </text> - <combo_box label="" name="emote_combo" tool_tip="アニメーション再生中の顔の表情を決めます"> - <item label="(なし)" name="[None]" value=""/> - <item label="アーーーーー" name="Aaaaah" value="アーーーーー"/> - <item label="恐れる" name="Afraid" value="恐れる"/> - <item label="怒る" name="Angry" value="怒る"/> - <item label="満面の笑み" name="BigSmile" value="満面の笑み"/> - <item label="退屈" name="Bored" value="退屈"/> - <item label="泣く" name="Cry" value="泣く"/> - <item label="侮辱" name="Disdain" value="侮辱"/> - <item label="恥ずかしがる" name="Embarrassed" value="恥ずかしがる"/> - <item label="しかめっ面" name="Frown" value="しかめっ面"/> - <item label="キス" name="Kiss" value="キス"/> - <item label="笑う" name="Laugh" value="笑う"/> - <item label="Plllppt" name="Plllppt" value="Plllppt"/> - <item label="嫌悪感" name="Repulsed" value="嫌悪感"/> - <item label="悲しい" name="Sad" value="悲しい"/> - <item label="肩をすくめる" name="Shrug" value="肩をすくめる"/> - <item label="微笑む" name="Smile" value="微笑む"/> - <item label="驚く" name="Surprise" value="驚く"/> - <item label="ウィンク" name="Wink" value="ウィンク"/> - <item label="心配する" name="Worry" value="心配する"/> - </combo_box> - <text name="preview_label"> - 同時進行行動 - </text> - <combo_box label="" name="preview_base_anim" tool_tip="アバターが普通の行動をするときのアニメーションの動きをテストするためにこれを使います。"> - <item label="立つ" name="Standing" value="立つ"/> - <item label="歩く" name="Walking" value="歩く"/> - <item label="座る" name="Sitting" value="座る"/> - <item label="飛ぶ" name="Flying" value="飛ぶ"/> - </combo_box> - <spinner label="イーズイン(秒)" name="ease_in_time" tool_tip="アニメーションのブレンドイン時間(秒)"/> - <spinner label="イーズアウト(秒)" name="ease_out_time" tool_tip="アニメーションのブレンドアウト時間(秒)"/> - <button label="" name="play_btn" tool_tip="アニメーションを再生する"/> - <button name="pause_btn" tool_tip="アニメーションを一時停止する"/> - <button label="" name="stop_btn" tool_tip="アニメーションの再生を停止"/> - <slider label="" name="playback_slider"/> - <text name="bad_animation_text"> - アニメーションファイルを読み込めません。 - - Poser 4からエクスポートされたBVHファイルを推奨します。 - </text> - <button label="アップロードL$[AMOUNT]" name="ok_btn"/> - <button label="取り消し" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_autoreplace.xml b/indra/newview/skins/default/xui/ja/floater_autoreplace.xml new file mode 100644 index 0000000000..21abf59160 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="自動置換設定"> + <check_box label="自動置換を有効にする" name="autoreplace_enable" tool_tip="チャットテキストを入力するにつれて、入力したキーワードを対応する置換キーワードに置き換えます"/> + <button label="リストをインポート..." name="autoreplace_import_list" tool_tip="以前にエクスポートしたリストをファイルからロードします。"/> + <button label="リストをエクスポート..." name="autoreplace_export_list" tool_tip="選択したリストをファイルに保存して、共有できるようにします。"/> + <button label="新規リスト..." name="autoreplace_new_list" tool_tip="新規リストを作成します。"/> + <button label="リストを削除" name="autoreplace_delete_list" tool_tip="選択したリストを削除します。"/> + <button name="autoreplace_list_up" tool_tip="このリストの優先度を上げます。"/> + <button name="autoreplace_list_down" tool_tip="このリストの優先度を下げます。"/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="キーワード" name="keyword"/> + <scroll_list.columns label="置換" name="replacement"/> + </scroll_list> + <button label="追加..." name="autoreplace_add_entry"/> + <button label="削除" name="autoreplace_delete_entry"/> + <button label="エントリを保存" name="autoreplace_save_entry" tool_tip="このエントリを保存します。"/> + <button label="変更を保存" name="autoreplace_save_changes" tool_tip="変更をすべて保存します。"/> + <button label="取り消し" name="autoreplace_cancel" tool_tip="変更をすべて破棄します。"/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/ja/floater_inventory.xml b/indra/newview/skins/default/xui/ja/floater_inventory.xml deleted file mode 100644 index b113fde94a..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="持ち物"> - <floater.string name="Title"> - 持ち物 - </floater.string> - <floater.string name="TitleFetching"> - 持ち物 ( [ITEM_COUNT] アイテムを取得中...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - 持ち物 ( [ITEM_COUNT] アイテム) [FILTER] - </floater.string> - <floater.string name="Fetched"> - 取得済 - </floater.string> - <panel label="持ち物パネル" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_model_preview.xml b/indra/newview/skins/default/xui/ja/floater_model_preview.xml index c9ff0e29cb..942cc91317 100644 --- a/indra/newview/skins/default/xui/ja/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/ja/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="三角形" name="triangles" value="三角形"/> <text initial_value="頂点" name="vertices" value="頂点"/> <text initial_value="高" name="high_label" value="高"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="ファイルからロード"/> + <item name="Generate" value="生成"/> + </combo_box> <button label="参照" name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="三角形の限度数"/> + <item name="Error Threshold" value="エラーしきい値"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="中" name="medium_label" value="中"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="ファイルからロード"/> + <item name="Generate" value="生成"/> + <item name="Use LoD above" value="上記の LoD を使用"/> + </combo_box> <button label="参照" name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="三角形の限度数"/> + <item name="Error Threshold" value="エラーしきい値"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="低" name="low_label" value="低"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="ファイルからロード"/> + <item name="Generate" value="生成"/> + <item name="Use LoD above" value="上記の LoD を使用"/> + </combo_box> <button label="参照" name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="三角形の限度数"/> + <item name="Error Threshold" value="エラーしきい値"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="最低" name="lowest_label" value="最低"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="ファイルからロード"/> + <item name="Generate" value="生成"/> + <item name="Use LoD above" value="上記の LoD を使用"/> + </combo_box> <button label="参照" name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="三角形の限度数"/> + <item name="Error Threshold" value="エラーしきい値"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="ノーマルの作成" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml b/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml deleted file mode 100644 index bcddcc6907..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="近くのチャット"> - <check_box label="チャットを翻訳" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..ada96b5b62 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="パスファインディングキャラクター"> + <floater.string name="messaging_get_inprogress"> + パスファインディングキャラクターを照会中... + </floater.string> + <floater.string name="messaging_get_error"> + パスファインディングキャラクターの照会中にエラーが発生しました。 + </floater.string> + <floater.string name="messaging_complete_none_found"> + パスファインディングキャラクターがありません。 + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_TOTAL] キャラクター中 [NUM_SELECTED] キャラクターが選択されました。 + </floater.string> + <floater.string name="messaging_not_enabled"> + この地域(リージョン)はパスファインディングに対応していません。 + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Loading] + </floater.string> + <floater.string name="character_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="character_owner_group"> + [group] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="名前" name="name"/> + <scroll_list.columns label="説明" name="description"/> + <scroll_list.columns label="所有者" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="高度" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + キャラクター: + </text> + <button label="リストを更新" name="refresh_objects_list"/> + <button label="すべて選択" name="select_all_objects"/> + <button label="何も選択しない" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + 選択したキャラクターに対するアクション: + </text> + <check_box label="ビーコンを表示" name="show_beacon"/> + <check_box label="物理効果カプセルを表示" name="show_physics_capsule"/> + <button label="取る" name="take_objects"/> + <button label="コピーを取る" name="take_copy_objects"/> + <button label="私をそこにテレポートする" name="teleport_me_to_object" tool_tip="1 つのキャラクターが選択された場合にのみ有効です。"/> + <button label="返却" name="return_objects"/> + <button label="削除" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml new file mode 100644 index 0000000000..ec107f3e6b --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="パスファインディングの表示/テスト"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + パスファインディングライブラリの実装が見つかりません。 + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + この地域(リージョン)はパスファインディングに対応していません。 + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + 地域(リージョン)の読み込みを待機しています。 + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + ナビメッシュのステータスを確認しています。 + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + ナビメッシュをダウンロードしています。 + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + サーバー上でナビメッシュが変わりました。最新のナビメッシュをダウンロードしています。 + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + 最新のナビメッシュがダウンロードされました。 + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + ナビメッシュを正しくダウンロードできません。 + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + ナビメッシュに保留中の変更があります。 + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + ナビメッシュを作成しています。 + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + ナビメッシュの一部の地域(リージョン)に保留中の変更があります。 + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + 一部のナビメッシュ地域(リージョン)を構築しています。 + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + ナビメッシュの一部の地域(リージョン)に保留中の変更があり、その他の地域(リージョン)は構築中です。 + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + ナビメッシュは最新です。 + </floater.string> + <floater.string name="pathing_library_not_implemented"> + パスファインディングライブラリの実装が見つかりません。 + </floater.string> + <floater.string name="pathing_region_not_enabled"> + この地域(リージョン)はパスファインディングに対応していません。 + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + 開始点と終了点を選択してください。 + </floater.string> + <floater.string name="pathing_choose_start_point"> + 開始点を選択してください。 + </floater.string> + <floater.string name="pathing_choose_end_point"> + 終了点を選択してください。 + </floater.string> + <floater.string name="pathing_path_valid"> + パスはオレンジ色で表示されています。 + </floater.string> + <floater.string name="pathing_path_invalid"> + 選択した 2 点間のパスが見つかりません。 + </floater.string> + <floater.string name="pathing_error"> + パスの生成中にエラーが発生しました。 + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="表示" name="view_panel"> + <text name="show_label"> + 表示: + </text> + <check_box label="世界" name="show_world"/> + <check_box label="可動物のみ" name="show_world_movables_only"/> + <check_box label="ナビメッシュ" name="show_navmesh"/> + <text name="show_walkability_label"> + 歩行可能マップを表示: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="表示しない" name="show_heatmap_mode_none"/> + <combo_box.item label="キャラクター タイプ A" name="show_heatmap_mode_a"/> + <combo_box.item label="キャラクター タイプ B" name="show_heatmap_mode_b"/> + <combo_box.item label="キャラクター タイプ C" name="show_heatmap_mode_c"/> + <combo_box.item label="キャラクター タイプ D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="歩行可能" name="show_walkables"/> + <check_box label="素材ボリューム" name="show_material_volumes"/> + <check_box label="静的障害物" name="show_static_obstacles"/> + <check_box label="除外ボリューム" name="show_exclusion_volumes"/> + <check_box label="水上飛行機" name="show_water_plane"/> + <check_box label="X 線表示による" name="show_xray"/> + </panel> + <panel label="パスをテスト" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl キーを押しながらクリックして、開始点を選択します。 + </text> + <text name="shift_click_label"> + Shift キーを押しながらクリックして、終了点を選択します。 + </text> + <text name="character_width_label"> + キャラクターの幅 + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + キャラクタータイプ + </text> + <combo_box name="path_character_type"> + <combo_box.item label="なし" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="パスをクリア" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..4441d5e738 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="パスファインディングリンクセット"> + <floater.string name="messaging_get_inprogress"> + パスファインディングリンクセットを照会中... + </floater.string> + <floater.string name="messaging_get_error"> + パスファインディングリンクセットの照会中にエラーが発生しました。 + </floater.string> + <floater.string name="messaging_set_inprogress"> + 選択したパスファインディングリンクセットを修正中... + </floater.string> + <floater.string name="messaging_set_error"> + 選択したパスファインディングリンクセットの修正中にエラーが発生しました。 + </floater.string> + <floater.string name="messaging_complete_none_found"> + パスファインディングリンクセットがありません。 + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_TOTAL] リンクセット中 [NUM_SELECTED] リンクセットが選択されました。 + </floater.string> + <floater.string name="messaging_not_enabled"> + この地域(リージョン)はパスファインディングに対応していません。 + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Loading] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="linkset_owner_group"> + [group] + </floater.string> + <floater.string name="linkset_is_scripted"> + はい + </floater.string> + <floater.string name="linkset_is_not_scripted"> + いいえ + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + 不明 + </floater.string> + <floater.string name="linkset_use_walkable"> + 歩行可能 + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + 静的障害物 + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + 可動障害物 + </floater.string> + <floater.string name="linkset_use_material_volume"> + 素材ボリューム + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + 除外ボリューム + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + 可動ボリューム + </floater.string> + <floater.string name="linkset_is_terrain"> + [unmodifiable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restricted] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [concave] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restricted,concave] + </floater.string> + <floater.string name="linkset_choose_use"> + リンクセットの用途を選択... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="リンクセットの用途でフィルター..." name="filter_by_linkset_use_none"/> + <combo_box.item label="歩行可能" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="静的障害物" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="可動障害物" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="素材ボリューム" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="除外ボリューム" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="可動ボリューム" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="適用" name="apply_filters"/> + <button label="クリア" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="名前(ルートプリム)" name="name"/> + <scroll_list.columns label="説明(ルートプリム)" name="description"/> + <scroll_list.columns label="所有者" name="owner"/> + <scroll_list.columns label="スクリプト" name="scripted"/> + <scroll_list.columns label="負荷" name="land_impact"/> + <scroll_list.columns label="距離" name="dist_from_you"/> + <scroll_list.columns label="リンクセットの用途" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + リンクセット: + </text> + <button label="リスト更新" name="refresh_objects_list"/> + <button label="すべて選択" name="select_all_objects"/> + <button label="何も選択しない" name="select_none_objects"/> + </panel> + <panel> + <check_box label="ビーコンを表示" name="show_beacon"/> + <button label="取る" name="take_objects"/> + <button label="コピーを取る" name="take_copy_objects"/> + <button label="私をそこにテレポートする" name="teleport_me_to_object"/> + <button label="返却" name="return_objects"/> + <button label="削除" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + 歩行可能性: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="タイプ A のキャラクターの歩行可能性。キャラクタータイプの例はヒューマノイドです。"/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="タイプ B のキャラクターの歩行可能性。キャラクタータイプの例はクリーチャーです。"/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="タイプ C のキャラクターの歩行可能性。キャラクタータイプの例はメカニカルです。"/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="タイプ D のキャラクターの歩行可能性。キャラクタータイプの例はその他です。"/> + <button label="変更を適用" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (ヒューマノイド) + </text> + <text name="suggested_use_b_label"> + (クリーチャー) + </text> + <text name="suggested_use_c_label"> + (メカニカル) + </text> + <text name="suggested_use_d_label"> + (その他) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_postcard.xml b/indra/newview/skins/default/xui/ja/floater_postcard.xml deleted file mode 100644 index 9d9b59fa51..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_postcard.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="スナップショットをEメールで送信"> - <text name="to_label"> - 受信先のEメール: - </text> - <line_editor left="145" name="to_form" width="125"/> - <text name="from_label"> - あなたのEメール: - </text> - <line_editor left="145" name="from_form" width="125"/> - <text name="name_label"> - あなたの名前: - </text> - <line_editor left="145" name="name_form" width="125"/> - <text name="subject_label"> - 件名: - </text> - <line_editor label="件名を入力してください" left="145" name="subject_form" width="125"/> - <text name="msg_label"> - メッセージ: - </text> - <text_editor bottom_delta="-120" height="110" name="msg_form"> - メッセージをここに入力してください。 - </text_editor> - <check_box label="Web上で公開" name="allow_publish_check" tool_tip="このポストカードをWeb上で公開します。"/> - <check_box label="成人向けコンテンツ" name="mature_check" tool_tip="このポストカードには成人向け内容が含まれます。"/> - <button label="?" left="300" name="publish_help_btn"/> - <text name="fine_print"> - この受信者がSLに参加すると、あなたに紹介ボーナスが入ります - </text> - <button bottom_delta="-52" label="取り消し" name="cancel_btn"/> - <button label="送信" name="send_btn"/> - <text name="default_subject"> - [SECOND_LIFE] からのポストカードです。 - </text> - <text name="default_message"> - これは絶対チェック! - </text> - <string name="upload_message"> - 送信中... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_spellcheck.xml b/indra/newview/skins/default/xui/ja/floater_spellcheck.xml new file mode 100644 index 0000000000..31fbef9bcf --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="スペルチェッカーの設定"> + <check_box label="スペルチェッカーを有効にする" name="spellcheck_enable"/> + <text name="spellcheck_main"> + メイン辞書: + </text> + <text label="ログ:" name="spellcheck_additional"> + その他の辞書: + </text> + <text name="spellcheck_available"> + 入手可 + </text> + <text name="spellcheck_active"> + 有効 + </text> + <button label="削除" name="spellcheck_remove_btn"/> + <button label="インポート..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml new file mode 100644 index 0000000000..febe153d25 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="辞書をインポート"> + <button label="参照" label_selected="参照" name="dictionary_path_browse"/> + <button label="インポート" name="ok_btn"/> + <button label="取り消し" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_stats.xml b/indra/newview/skins/default/xui/ja/floater_stats.xml index da5358f06a..1922e4841a 100644 --- a/indra/newview/skins/default/xui/ja/floater_stats.xml +++ b/indra/newview/skins/default/xui/ja/floater_stats.xml @@ -53,7 +53,13 @@ <stat_bar label="オブジェクト" name="simobjects"/> <stat_bar label="アクティブなオブジェクト" name="simactiveobjects"/> <stat_bar label="アクティブなスクリプト" name="simactivescripts"/> + <stat_bar label="スクリプト実行" name="simpctscriptsrun"/> <stat_bar label="スクリプトイベント" name="simscripteps"/> + <stat_view label="パスファインディング" name="simpathfinding"> + <stat_bar label="AIステップ時間" name="simsimaistepmsec"/> + <stat_bar label="スキップされたシルエットステップ" name="simsimskippedsilhouettesteps"/> + <stat_bar label="更新されたキャラクター" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="パケットイン" name="siminpps"/> <stat_bar label="パケットアウト" name="simoutpps"/> <stat_bar label="保留中のダウンロード" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml index 55fe840658..3773812bb6 100644 --- a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml @@ -20,6 +20,8 @@ <button label="ブランク" label_selected="ブランク" name="Blank"/> <button label="なし" label_selected="なし" name="None"/> <button label="" label_selected="" name="Pipette"/> + <check_box initial_value="true" label="ライブプレビュー" name="apply_immediate_check"/> + <text name="preview_disabled" value="プレビュー無効"/> <filter_editor label="テクスチャをフィルター" name="inventory search editor"/> <check_box initial_value="false" label="フォルダを表示" name="show_folders_check"/> <button label="追加" label_selected="追加" name="l_add_btn"/> @@ -31,5 +33,4 @@ </scroll_list> <button label="OK" label_selected="OK" name="Select"/> <button label="取り消し" label_selected="取り消し" name="Cancel"/> - <check_box initial_value="true" label="すぐ適用" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml index 4efdf7d40d..adc35137b5 100644 --- a/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, キャッシュから表示テクスチャを再取得、時間:[TIME] 秒、取得:[SIZE]KB、[PIXEL]メガピクセル </text> + <text name="total_time_refetch_all_cache_label"> + 16、キャッシュからすべてのテクスチャを再フェッチ中、時間: [TIME] 秒、フェッチ済み: [SIZE]KB、[PIXEL]メガピクセル + </text> <text name="total_time_refetch_vis_http_label"> - 16, HTTP から表示テクスチャを再取得、時間:[TIME] 秒、取得:[SIZE]KB、[PIXEL]メガピクセル + 17、HTTP から可視ファイルを再フェッチ中、時間: [TIME] 秒、フェッチ済み: [SIZE]KB、[PIXEL]メガピクセル + </text> + <text name="total_time_refetch_all_http_label"> + 18、HTTP からすべてのテクスチャを再フェッチ中、時間: [TIME] 秒、フェッチ済み: [SIZE]KB、[PIXEL]メガピクセル + </text> + <spinner label="19、テセル/ピクセル比:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20、テクスチャ ソース: </text> - <spinner label="17, テクセル/ピクセルの比率:" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="キャッシュ + HTTP" name="0"/> + <radio_item label="HTTP のみ" name="1"/> + </radio_group> <button label="開始" name="start_btn"/> <button label="リセット" name="clear_btn"/> <button label="閉じる" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="デコード" name="decode_btn"/> <button label="GL テクスチャ" name="gl_btn"/> <button label="キャッシュ表示テクスチャ再取得" name="refetchviscache_btn"/> + <button label="すべてのキャッシュを再フェッチ" name="refetchallcache_btn"/> <button label="HTTP表示テクスチャ再取得" name="refetchvishttp_btn"/> + <button label="すべての HTTP を再フェッチ" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml index 2d12a5e56a..4bd6439ad2 100644 --- a/indra/newview/skins/default/xui/ja/floater_tools.xml +++ b/indra/newview/skins/default/xui/ja/floater_tools.xml @@ -148,6 +148,12 @@ <panel.string name="text modify info 4"> これらのオブジェクトを修正できません </panel.string> + <panel.string name="text modify info 5"> + 地域(リージョン)の境界を越えてこのオブジェクトを修正できません + </panel.string> + <panel.string name="text modify info 6"> + 地域(リージョン)の境界を越えてこれらのオブジェクトを修正できません + </panel.string> <panel.string name="text modify warning"> オブジェクト全体を選択して権限の設定を行ってください。 </panel.string> @@ -203,12 +209,12 @@ <combo_box.item label="ズームする" name="Zoom"/> </combo_box> <check_box label="販売対象:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="コピー" name="Copy"/> <combo_box.item label="中身" name="Contents"/> <combo_box.item label="オリジナル" name="Original"/> </combo_box> - <spinner label="価格: L$" name="Edit Cost"/> <check_box label="検索に表示" name="search_check" tool_tip="検索結果にこのオブジェクトを表示します"/> <panel name="perms_build"> <text name="perm_modify"> @@ -244,6 +250,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + パスファインディング属性: + </text> + </panel> </panel> <panel label="形状" name="Object"> <check_box label="ロック" name="checkbox locked" tool_tip="オブジェクトの移動と削除を禁止します。 この機能を使うと、制作中の意図せぬ編集を防ぐことができます"/> diff --git a/indra/newview/skins/default/xui/ja/floater_top_objects.xml b/indra/newview/skins/default/xui/ja/floater_top_objects.xml index bfc93e5624..c44f409d4e 100644 --- a/indra/newview/skins/default/xui/ja/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/ja/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> 時間 </floater.string> - <floater.string name="scripts_mono_time_label"> - Monoタイム - </floater.string> <floater.string name="top_colliders_title"> 上部コライダー </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="名前" name="name"/> <scroll_list.columns label="所有者" name="owner"/> <scroll_list.columns label="ロケーション" name="location"/> + <scroll_list.columns label="区画" name="parcel"/> <scroll_list.columns label="時間" name="time"/> - <scroll_list.columns label="Monoタイム" name="mono_time"/> <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="メモリ(KB)" name="memory"/> </scroll_list> <text name="id_text"> 物体ID: @@ -48,6 +46,10 @@ 所有者: </text> <button label="フィルタ" name="filter_owner_btn"/> + <text name="parcel_name_text"> + 区画: + </text> + <button label="フィルター" name="filter_parcel_btn"/> <button label="更新" name="refresh_btn"/> <button label="選択内容を返却" name="return_selected_btn"/> <button label="すべて返却" name="return_all_btn"/> diff --git a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml b/indra/newview/skins/default/xui/ja/menu_bottomtray.xml deleted file mode 100644 index 7f106c1ab5..0000000000 --- a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="スピーカーボタン" name="EnableVoiceChat"/> - <menu_item_check label="ジェスチャーボタン" name="ShowGestureButton"/> - <menu_item_check label="移動ボタン" name="ShowMoveButton"/> - <menu_item_check label="視界ボタン" name="ShowCameraButton"/> - <menu_item_check label="スナップショットボタン" name="ShowSnapshotButton"/> - <menu_item_check label="制作ボタン" name="ShowBuildButton"/> - <menu_item_check label="検索ボタン" name="ShowSearchButton"/> - <menu_item_check label="地図ボタン" name="ShowWorldMapButton"/> - <menu_item_check label="ミニマップボタン" name="ShowMiniMapButton"/> - <menu_item_call label="切り取り" name="NearbyChatBar_Cut"/> - <menu_item_call label="コピー" name="NearbyChatBar_Copy"/> - <menu_item_call label="貼り付け" name="NearbyChatBar_Paste"/> - <menu_item_call label="削除" name="NearbyChatBar_Delete"/> - <menu_item_call label="すべて選択" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/ja/menu_inventory.xml b/indra/newview/skins/default/xui/ja/menu_inventory.xml index d1893a0fc8..106b09453a 100644 --- a/indra/newview/skins/default/xui/ja/menu_inventory.xml +++ b/indra/newview/skins/default/xui/ja/menu_inventory.xml @@ -68,6 +68,7 @@ <menu_item_call label="システムフォルダを削除する" name="Delete System Folder"/> <menu_item_call label="コンファレンスチャットを開始する" name="Conference Chat Folder"/> <menu_item_call label="再生する" name="Sound Play"/> + <menu_item_call label="SLurl をコピー" name="url_copy"/> <menu_item_call label="ランドマークの情報" name="About Landmark"/> <menu_item_call label="インワールドで再生する" name="Animation Play"/> <menu_item_call label="ローカルで再生する" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/ja/menu_mode_change.xml b/indra/newview/skins/default/xui/ja/menu_mode_change.xml deleted file mode 100644 index dff3392bd5..0000000000 --- a/indra/newview/skins/default/xui/ja/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="ベーシック" name="BasicMode"/> - <menu_item_check label="アドバンス" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_object.xml b/indra/newview/skins/default/xui/ja/menu_object.xml index 4cee8089ee..01436ad12b 100644 --- a/indra/newview/skins/default/xui/ja/menu_object.xml +++ b/indra/newview/skins/default/xui/ja/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="編集" name="Edit..."/> <menu_item_call label="制作" name="Build"/> + <menu_item_call label="リンクセットで表示" name="show_in_linksets"/> + <menu_item_call label="キャラクターで表示" name="show_in_characters"/> <menu_item_call label="開く" name="Open"/> <menu_item_call label="ここに座る" name="Object Sit"/> <menu_item_call label="立ち上がる" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/ja/menu_text_editor.xml b/indra/newview/skins/default/xui/ja/menu_text_editor.xml index fcb1038a6a..eda973c888 100644 --- a/indra/newview/skins/default/xui/ja/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/ja/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(不明)" name="Suggestion 1"/> + <menu_item_call label="(不明)" name="Suggestion 2"/> + <menu_item_call label="(不明)" name="Suggestion 3"/> + <menu_item_call label="(不明)" name="Suggestion 4"/> + <menu_item_call label="(不明)" name="Suggestion 5"/> + <menu_item_call label="辞書に追加" name="Add to Dictionary"/> + <menu_item_call label="無視に追加" name="Add to Ignore"/> <menu_item_call label="切り取り" name="Cut"/> <menu_item_call label="コピー" name="Copy"/> <menu_item_call label="貼り付け" name="Paste"/> diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 3a398bd985..e60e6781c6 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -28,6 +28,7 @@ <menu_item_call label="環境設定..." name="Preferences"/> <menu_item_call label="ツールバーのボタン..." name="Toolbars"/> <menu_item_call label="全てのコントロールを非表示にする" name="Hide UI"/> + <menu_item_check label="HUD を表示" name="Show HUD Attachments"/> <menu_item_call label="[APP_NAME] を終了" name="Quit"/> </menu> <menu label="コミュニケーション" name="Communicate"> @@ -39,6 +40,7 @@ <menu_item_call label="フレンド" name="My Friends"/> <menu_item_call label="グループ" name="My Groups"/> <menu_item_call label="近くにいる人" name="Active Speakers"/> + <menu_item_call label="リストをブロック" name="Block List"/> </menu> <menu label="世界" name="World"> <menu_item_call label="現在地をランドマーク" name="Create Landmark Here"/> @@ -124,6 +126,11 @@ <menu_item_call label="スクリプトを実行中にする" name="Set Scripts to Running"/> <menu_item_call label="スクリプトを実行停止にする" name="Set Scripts to Not Running"/> </menu> + <menu label="パスファインディング" name="Pathfinding"> + <menu_item_call label="リンクセット..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="キャラクター..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="表示/テスト..." name="pathfinding_console_menu_item"/> + </menu> <menu label="オプション" name="Options"> <menu_item_check label="権限の詳細を表示する" name="DebugPermissions"/> <menu_item_check label="私のオブジェクトだけを選択する" name="Select Only My Objects"/> @@ -174,7 +181,6 @@ <menu_item_check label="パーティクルを非表示にする" name="Hide Particles"/> <menu_item_check label="選択したものを非表示にする" name="Hide Selected"/> <menu_item_check label="透明部分をハイライトする" name="Highlight Transparent"/> - <menu_item_check label="HUD を表示する" name="Show HUD Attachments"/> <menu_item_check label="一人称視点のときに十字線を表示する" name="ShowCrosshairs"/> </menu> <menu label="レンダリング(種類)" name="Rendering Types"> @@ -377,7 +383,6 @@ <menu_item_call label="キャラクタジオメトリの切り替え" name="Toggle Character Geometry"/> <menu_item_call label="男性アバターのテスト" name="Test Male"/> <menu_item_call label="女性アバターのテスト" name="Test Female"/> - <menu_item_call label="PG のトグル" name="Toggle PG"/> <menu_item_check label="選択アバター許可" name="Allow Select Avatar"/> </menu> <menu_item_call label="パラメータを強制的にデフォルトにする" name="Force Params to Default"/> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index f35c0f0d14..d5cff18a24 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -382,13 +388,19 @@ L$ が不足しているのでこのグループに参加することができ [SECOND_LIFE] に入るにはアカウントが必要です。今すぐアカウントを作成しますか? <url name="url"> - https://join.secondlife.com/index.php?lang=ja-JP + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="もう一度試す" yestext="新しいアカウントを作成"/> </notification> <notification name="InvalidCredentialFormat"> ユーザー名のフィールドにアバターのユーザー名もしくは氏名を入力してから、再度ログインする必要があります。 </notification> + <notification name="InvalidGrid"> + '[GRID]' は有効なグリッド ID ではありません。 + </notification> + <notification name="InvalidLocationSLURL"> + ログイン位置で有効なグリッドが指定されませんでした。 + </notification> <notification name="DeleteClassified"> クラシファイド広告 [NAME] を削除しますか? 支払い済みの料金は返金されません。 @@ -495,7 +507,7 @@ L$ が不足しているのでこのグループに参加することができ </notification> <notification name="StartRegionEmpty"> ログイン位置が指定されていません。 -ログイン位置の欄にリージョン名を入力するか、「最後にログアウトした場所」か「ホーム」を選択してください。 +ログイン位置の欄にリージョン名を入力するか、「最後にログアウトした場所」か「自宅(ホーム)」を選択してください。 <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -623,6 +635,9 @@ L$ が不足しているのでこのグループに参加することができ どのオブジェクトもロックされておらず、あなたのものであることを確認してください。 </notification> + <notification name="CannotLinkPermanent"> + 地域(リージョン)の境界を越えてオブジェクトをリンクできません。 + </notification> <notification name="CannotLinkDifferentOwners"> 所有者が異なるため、オブジェクトをリンクできません。 @@ -1009,6 +1024,40 @@ L$ は返金されません。 <button name="Cancel" text="キャンセル"/> </form> </notification> + <notification label="自動置換リストを追加" name="AddAutoReplaceList"> + 新しいリストの名前: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="自動置換リストの名前を変更" name="RenameAutoReplaceList"> + 名前 '[DUPNAME]' は既に使われています +一意の名前を入力してください: + <form name="form"> + <button name="ReplaceList" text="着用中のリストを入れ替える"/> + <button name="SetName" text="新しい名前を使用"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + キーワードは一語でなければならず、置換は空にできません。 + </notification> + <notification name="InvalidAutoReplaceList"> + その置換リストは無効です。 + </notification> + <notification name="SpellingDictImportRequired"> + ファイル、名前および言語を指定する必要があります。 + </notification> + <notification name="SpellingDictIsSecondary"> + 辞書 [DIC_NAME] に「aff」ファイルがないようです。これはこの辞書が「セカンダリ」辞書であることを意味します。 +この辞書は追加辞書として使用できますが、メイン辞書としては使用できません。 + +https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries を参照してください。 + </notification> + <notification name="SpellingDictImportFailed"> + [FROM_NAME] から + +[TO_NAME] へコピーできません + </notification> <notification label="アウトフィットを保存する" name="SaveOutfitAs"> 着用中のアウトフィットを新しいアウトフットとして保存: <form name="form"> @@ -1191,7 +1240,7 @@ L$ は返金されません。 近くのリージョンに移動しました。 </notification> <notification name="AvatarMovedLast"> - 前回いた場所は現在ご利用いただけません。 + リクエストされた場所は現在ご利用いただけません。 近くのリージョンに移動しました。 </notification> <notification name="AvatarMovedHome"> @@ -1210,8 +1259,7 @@ L$ は返金されません。 [APP_NAME] のインストールが完了しました。 [SECOND_LIFE] を使ったことがない場合は、ログインする前にアカウントの作成を行ってください。 -[http://join.secondlife.com/?lang=ja-JP] で新しいアカウントを作成しますか? - <usetemplate name="okcancelbuttons" notext="続行" yestext="新規アカウント..."/> + <usetemplate name="okcancelbuttons" notext="続行" yestext="アカウントを作成..."/> </notification> <notification name="LoginPacketNeverReceived"> 接続がなかなかできません。 お使いのインターネット接続か、[SECOND_LIFE_GRID] の問題と考えられます。 @@ -1733,83 +1781,128 @@ http://wiki.secondlife.com/wiki/Setting_your_display_name を参照してくだ <usetemplate name="okcancelbuttons" notext="取り消し" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - あなたのレーティング区分により、そのリージョン(地域)へは入ることができません。 年齢を確認する際の情報に不足があったためと考えられます。 - -最新ビューワがインストールされているかをご確認ください。このレーティング区分でのアクセスに関する詳細はナレッジベースをご覧ください。 + 訪問しようとしている地域(リージョン)には現在の環境設定を超えるコンテンツが含まれています。「ミー」 > 「環境設定」 > 「一般」を選択して、環境設定を変更できます。 <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - あなたのレーティング区分により、そのリージョン(地域)へは入ることができません。 - -ナレッジベースを開きレーティング区分について学びますか? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + 訪問しようとしている地域(リージョン)には、成人のみアクセスできる [REGIONMATURITY] コンテンツが含まれています。 <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="レーティング区分の制限のため、リージョンに入ることができないとき" name="okcancelignore" notext="閉じる" yestext="ナレッジベースを開く"/> + <usetemplate ignoretext="リージョン(地域)の横断:訪問しようとしている地域(リージョン)には、成人のみアクセスできるコンテンツが含まれています。" name="okcancelignore" notext="閉じる" yestext="ナレッジベースを開く"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - あなたのレーティング区分により、そのリージョン(地域)へは入ることができません。 + 訪問しようとしている地域(リージョン)には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツ除外するように設定されています。 + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + 訪問しようとしている地域(リージョン)には、成人のみアクセスできる [REGIONMATURITY] コンテンツが含まれています。 </notification> <notification name="RegionEntryAccessBlocked_Change"> - レーティング区分に関する設定により、その地域(リージョン)には立ち入れません。 - -その地域に入るには、あなたのレーティング区分の設定を変更してください。変更すると、[REGIONMATURITY]のコンテンツの検索やアクセスが可能になります。変更内容を元に戻すには、ミー > 環境設定 > 一般を選択してください。 + 訪問しようとしている地域(リージョン)には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。環境設定を変更するか、取り消すことができます。環境設定を変更した後、もう一度、地域(リージョン)に入ることができます。 <form name="form"> <button name="OK" text="環境設定の変更"/> - <button default="true" name="Cancel" text="閉じる"/> - <ignore name="ignore" text="選択したレーティング区分が原因で、リージョンに入れないとき"/> + <button default="true" name="Cancel" text="取り消し"/> + <ignore name="ignore" text="リージョン(地域)の横断:訪問しようとしている地域(リージョン)には現在の環境設定により除外されたコンテンツが含まれています。"/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + あなたの環境設定がサーバーと同期していないため、テレポートに技術的な問題が発生しています。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + 訪問しようとしている地域(リージョン)には現在の環境設定を超えるコンテンツが含まれています。「ミー」 > 「環境設定」 > 「一般」を選択して、環境設定を変更できます。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + 訪問しようとしている地域(リージョン)には、成人のみアクセスできる [REGIONMATURITY] コンテンツが含まれています。 + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="テレポート:訪問しようとしている地域(リージョン)には、成人のみアクセスできるコンテンツが含まれています。" name="okcancelignore" notext="閉じる" yestext="ナレッジベースを開く"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + 訪問しようとしている地域(リージョン)には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。 + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + 訪問しようとしている地域(リージョン)には、成人のみアクセスできる [REGIONMATURITY] コンテンツが含まれています。 + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + 訪問しようとしている地域(リージョン)には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。環境設定を変更してテレポートを続けるか、このテレポートを取り消すことができます。 + <form name="form"> + <button name="OK" text="変更して続ける"/> + <button name="Cancel" text="取り消し"/> + <ignore name="ignore" text="テレポート(再起動可能):訪問しようとしている地域(リージョン)には現在の環境設定により除外されたコンテンツが含まれています。"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + 訪問しようとしている地域(リージョン)には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。環境設定を変更するか、テレポートを取り消すことができます。環境設定を変更した後、もう一度テレポートを実行する必要があります。 + <form name="form"> + <button name="OK" text="環境設定の変更"/> + <button name="Cancel" text="取り消し"/> + <ignore name="ignore" text="テレポート(再起動不可):訪問しようとしている地域(リージョン)には現在の環境設定により除外されたコンテンツが含まれています。"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + あなたの環境設定がサーバーと同期していないため、テレポートに技術的な問題が発生しています。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - あなたのレーティング区分設定は現在 [RATING] です。 + 今後、[RATING] コンテンツ付きの地域(リージョン)を訪問しようとしているという通知を受け取りません。後でメニューバーの「ミー」 > 「環境設定」 > 「一般」を使用して、コンテンツの環境設定を変更できます。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + 現在、[PREFERRED_MATURITY] コンテンツを表示するように環境設定を変更できませんでした。あなたの環境設定は、[ACTUAL_MATURITY] コンテンツを表示するようにリセットされました。メニューバーの「ミー」 > 「環境設定」 > 「一般」を使用して、もう一度環境設定を変更できます。 + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - あなたのレーティング区分により、この土地を取得することはできません。 年齢を確認する際の情報に不足があったためと考えられます。 - -最新ビューワがインストールされているかをご確認ください。このレーティング区分でのアクセスに関する詳細はナレッジベースをご覧ください。 + 取得しようとしている土地には現在の環境設定を超えるレーティング区分が含まれています。「ミー」 > 「環境設定」 > 「一般」を選択して、環境設定を変更できます。 <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - あなたのレーティング区分により、この土地を取得することはできません。 - -ナレッジベースを開きレーティング区分について学びますか? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + この土地を購入できるのは、成人だけです。 <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="レーティング区分の制限のため、この土地を取得できません" name="okcancelignore" notext="閉じる" yestext="ナレッジベースを開く"/> + <usetemplate ignoretext="この土地を購入できるのは、成人だけです。" name="okcancelignore" notext="閉じる" yestext="ナレッジベースを開く"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - あなたのレーティング区分により、この土地を取得することはできません。 + 取得しようとしている土地には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。 + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + 取得しようとしている土地には、成人のみアクセスできる [REGIONMATURITY] コンテンツが含まれています。 </notification> <notification name="LandClaimAccessBlocked_Change"> - あなたのレーティング区分設定により、この土地を取得することはできません。 - -「設定を変更」をクリックしてあなたのレーティング区分を上げると、入れるようになります。 あなたは今後 [REGIONMATURITY] コンテンツの検索及びアクセスが可能となります。 あとで設定を元に戻したい場合は、「編集」>「環境設定」をご覧ください。 - <usetemplate ignoretext="選択したレーティング区分が原因で、土地を取得できないとき" name="okcancelignore" notext="閉じる" yestext="設定の変更"/> + 取得しようとしている土地には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。環境設定を変更して、もう一度土地の取得を試みることができます。 + <form name="form"> + <button name="OK" text="環境設定の変更"/> + <button name="Cancel" text="取り消し"/> + <ignore name="ignore" text="取得しようとしている土地には現在の環境設定により除外されたコンテンツが含まれています。"/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - あなたのレーティング区分により、この土地を購入することはできません。 年齢を確認する際の情報に不足があったためと考えられます。 - -最新ビューワがインストールされているかをご確認ください。このレーティング区分でのアクセスに関する詳細はナレッジベースをご覧ください。 + 購入しようとしている土地には現在の環境設定を超えるレーティング区分が含まれています。「ミー」 > 「環境設定」 > 「一般」を選択して、環境設定を変更できます。 <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - あなたのレーティング区分により、この土地を購入することはできません。 - -ナレッジベースを開きレーティング区分について学びますか? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + この土地を取得できるのは、成人だけです。 <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="レーティング区分の制限のため、この土地を購入できません" name="okcancelignore" notext="閉じる" yestext="ナレッジベースを開く"/> + <usetemplate ignoretext="この土地を取得できるのは、成人だけです。" name="okcancelignore" notext="閉じる" yestext="ナレッジベースを開く"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - あなたのレーティング区分により、この土地を購入することはできません。 + 購入しようとしている土地には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。 + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + 購入しようとしている土地には、成人のみアクセスできる [REGIONMATURITY] コンテンツが含まれています。 </notification> <notification name="LandBuyAccessBlocked_Change"> - あなたのレーティング区分設定により、この土地を購入することができません。 - -「設定を変更」をクリックしてあなたのレーティング区分を上げると、入れるようになります。 あなたは今後 [REGIONMATURITY] コンテンツの検索及びアクセスが可能となります。 あとで設定を元に戻したい場合は、「編集」>「環境設定」をご覧ください。 - <usetemplate ignoretext="選択したレーティング区分が原因で、土地を購入できないとき" name="okcancelignore" notext="閉じる" yestext="設定の変更"/> + 購入しようとしている土地には [REGIONMATURITY] コンテンツが含まれていますが、現在の環境設定は [REGIONMATURITY] コンテンツを除外するように設定されています。環境設定を変更して、もう一度土地の購入を試みることができます。 + <form name="form"> + <button name="OK" text="環境設定の変更"/> + <button name="Cancel" text="取り消し"/> + <ignore name="ignore" text="購入しようとしている土地には現在の環境設定により除外されたコンテンツが含まれています。"/> + </form> </notification> <notification name="TooManyPrimsSelected"> 選択したプリムが多すぎます。 [MAX_PRIM_COUNT] 個選択するか、プリム数を減らしてもう一度お試しください。 @@ -1867,10 +1960,9 @@ L$ [AMOUNT] で、このクラシファイド広告を今すぐ公開します </form> </notification> <notification label="地域のレーティング区分指定変更済み" name="RegionMaturityChange"> - このリージョン(地域)のレーティング区分がアップデートされました。 -地図に変更が反映されるまで数分かかることがあります。 - -Adult 専用リージョンに入るには、住人のアカウントが年齢確認か支払方法のいずれかで「確認済み」でなければなりません。 + このリージョンのレーティング区分が変更されました。 +地図にこの変更が反映するには数分かかることがあります。 + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="ボイスバージョンの不一致" name="VoiceVersionMismatch"> [APP_NAME] のこのバージョンは、このリージョンにおけるボイスチャットの互換性がありません。 ボイスチャットを正常に行うためには、[APP_NAME] のアップデートが必要です。 @@ -2165,14 +2257,11 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ <usetemplate ignoretext="「容姿」を編集中に、作成する衣類を装着するとき" name="okcancelignore" notext="いいえ" yestext="はい"/> </notification> <notification name="NotAgeVerified"> - Second Life で Adult 指定のコンテンツや領域にアクセスできるのは 18 歳以上のユーザーのみです。年齢確認ページで 18 歳以上であることを証明してください。 -これをクリックするとウェブブラウザが開きます。 - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="年齢の確認を済ませていないとき" name="okcancelignore" notext="取り消し" yestext="年齢確認ページを開く"/> + 訪問しようとしているロケーションは、18 才以上の住人に制限されています。 + <usetemplate ignoretext="年齢制限付きのエリアを訪問する年齢に達していません。" name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + ロケーションは 18 才以上に制限されています。 </notification> <notification name="Cannot enter parcel: no payment info on file"> 支払情報が登録されていないとこのエリアを訪れることができません。 [SECOND_LIFE] サイトで登録を行いますか? @@ -2435,6 +2524,23 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ <notification name="NoBuild"> このエリアでは制作が禁止されています。 オブジェクトを制作したり Rez することはできません。 </notification> + <notification name="PathfindingDirty"> + この値域(リージョン)には、保留中のパスファインディングの変更があります。制作権がある場合は、「地域の再構築」ボタンをクリックして、地域(リージョン)を再構築できます。 + </notification> + <notification name="DynamicPathfindingDisabled"> + この地域(リージョン)でダイナミックパスファインディングが有効になっていません。パスファインディング LSL 呼び出しを使用するスクリプト化されたオブジェクトがこの地域(リージョン)では動作できません。 + </notification> + <notification name="PathfindingRebakeNavmesh"> + この地域(リージョン)のオブジェクトを変更すると、他の移動オブジェクトが正しく動作しなくなる恐れがあります。移動オブジェクトを正しく動作させるには、「地域の再構築」ボタンをクリックします。詳しい情報は見るには「ヘルプ」を選択してください。 + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="ヘルプ" ignoretext="この地域(リージョン)のオブジェクトを変更すると、他の移動オブジェクトが正しく動作しなくなる恐れがあります。" name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + エラーが発生しました。ネットワークまたはサーバーに問題があるか、制作権がない可能性があります。この問題は、一度ログアウトしてから、ログインし直すと解決される場合があります。 + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> この区画にいるアバターやこの区画内で行われる文字チャットは、他の区画から見えません。あなたには、この区画外にいる住人が見えず、外の住人にはあなたの姿が見えません。チャンネル 0 での通常の文字チャットもブロックされます。 </notification> @@ -2453,9 +2559,7 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ そのリージョンにいないと公共の土地を取得することはできません。 </notification> <notification name="RegionTPAccessBlocked"> - あなたのレーティング区分によりそのリージョンへは入ることができません。 年齢確認を行うか、最新ビューワをインストールしてください。 - -現在のレーティング区分でアクセス可能なエリアに関する詳細はナレッジベースを参照してください。 + 訪問しようとしている地域(リージョン)には現在の環境設定を超えるコンテンツが含まれています。「ミー」 > 「環境設定」 > 「一般」を選択して、環境設定を変更できます。 </notification> <notification name="URBannedFromRegion"> あなたはリージョンへの立入が禁止されています。 @@ -2466,11 +2570,11 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ <notification name="ImproperPaymentStatus"> このリージョンに入るために適した支払いステータスがありません。 </notification> - <notification name="MustGetAgeRgion"> - このリージョンに入るためには、年齢確認を済ませる必要があります。 + <notification name="MustGetAgeRegion"> + この地域(リージョン)に入るには 18 才以上である必要があります。 </notification> <notification name="MustGetAgeParcel"> - この区画に入るためには、年齢確認を済ませる必要があります。 + この区画に入るには 18 才以上である必要があります。 </notification> <notification name="NoDestRegion"> 目的地のリージョンが見つかりませんでした。 @@ -2572,12 +2676,33 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ <notification name="TeleportOffered"> [NAME_SLURL] はテレポートであなたを呼んでいます。 -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="テレポート"/> <button name="Cancel" text="取り消し"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] はテレポートであなたを呼んでいます。 + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +この地域(リージョン)には [REGION_CONTENT_MATURITY] コンテンツが含まれていますが、現在の環境設定は [REGION_CONTENT_MATURITY] コンテンツを除外するように設定されています。環境設定を変更してテレポートを続けるか、このテレポートを取り消すことができます。 + <form name="form"> + <button name="Teleport" text="変更して続ける"/> + <button name="Cancel" text="取り消し"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] はテレポートであなたを呼んでいます。 + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +ただし、この地域(リージョン)には成人のみアクセスできるコンテンツが含まれています。 + </notification> <notification name="TeleportOfferSent"> [TO_NAME] にテレポートを送りました。 </notification> @@ -2900,18 +3025,6 @@ M キーを押して変更します。 [RESIDENTS] <usetemplate name="okcancelbuttons" notext="取り消し" yestext="Ok"/> </notification> - <notification name="ShareFolderConfirmation"> - フォルダは一度に 1 つしか共有できません。 - -次のアイテムを共有しますか? - -<nolink>[ITEMS]</nolink> - -次の住人と共有: - -[RESIDENTS] - <usetemplate name="okcancelbuttons" notext="取り消し" yestext="Ok"/> - </notification> <notification name="ItemsShared"> アイテムが共有されました。 </notification> @@ -2990,6 +3103,10 @@ M キーを押して変更します。 ( 作成後[EXISTENCE]秒経過) '[BODYREGION]'の[RESOLUTION]のベークドテクスチャは[TIME]秒後にローカルに更新されました。 </notification> + <notification name="LivePreviewUnavailable"> + コピー不可および/または転送不可のため、このテクスチャを表示できません。 + <usetemplate ignoretext="コピー不可および/または転送不可テクスチャでライブプレビューモードを使用できないことを警告する" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> このコールから抜けますか? <usetemplate ignoretext="コールから抜ける前の確認" name="okcancelignore" notext="いいえ" yestext="はい"/> @@ -3161,6 +3278,62 @@ M キーを押して変更します。 この操作により、全てのメニュー項目とボタンが非表示になります。再び表示するには [SHORTCUT] をもう一度クリックしてください。 <usetemplate ignoretext="UI を非表示にする前に確認" name="okcancelignore" notext="取り消し" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + 選択された一部のリンクセットはファントムフラグが切り替えられます。 + +続けますか? + <usetemplate ignoretext="選択された一部のリンクセットのファントムフラグが切り替えられます。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + 一部の選択されたリンクセットは、リンクセットへの権限が制限されているため、'[REQUESTED_TYPE]' に設定できません。これらのリンクセットは代わりに '[RESTRICTED_TYPE]' に設定されます。 + +続けますか? + <usetemplate ignoretext="一部の選択されたリンクセットは、リンクセットへの権限が制限されているため設定できません。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + 選択された一部のリンクセットは、形状が凸状でないため、'[REQUESTED_TYPE]' に設定できません。 + +続けますか? + <usetemplate ignoretext="選択された一部のリンクセットは、形状が凸状でないため設定できません。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + 選択された一部のリンクセットはファントムフラグが切り替えられます。 + +一部の選択されたリンクセットは、リンクセットへの権限が制限されているため、'[REQUESTED_TYPE]' に設定できません。これらのリンクセットは代わりに '[RESTRICTED_TYPE]' に設定されます。 + +続けますか? + <usetemplate ignoretext="選択された一部のリンクセットのファントムフラグが切り替えられ、他のリンクセットはリンクセットへの権限が制限されているため設定できません。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + 選択された一部のリンクセットはファントムフラグが切り替えられます。 + +選択された一部のリンクセットは、形状が凸状でないため、'[REQUESTED_TYPE]' に設定できません。 + +続けますか? + <usetemplate ignoretext="選択された一部のリンクセットのファントムフラグが切り替えられ、他のリンクセットは形状が凸状でないため設定できません。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + 一部の選択されたリンクセットは、リンクセットへの権限が制限されているため、'[REQUESTED_TYPE]' に設定できません。これらのリンクセットは代わりに '[RESTRICTED_TYPE]' に設定されます。 + +選択された一部のリンクセットは、形状が凸状でないため、'[REQUESTED_TYPE]' に設定できません。これらのリンクセットの用途タイプは変わりません。 + +続けますか? + <usetemplate ignoretext="一部の選択されたリンクセットは、リンクセットへの権限が制限されており、また形状が凸状でないため設定できません。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + 選択された一部のリンクセットはファントムフラグが切り替えられます。 + +一部の選択されたリンクセットは、リンクセットへの権限が制限されているため、'[REQUESTED_TYPE]' に設定できません。これらのリンクセットは代わりに '[RESTRICTED_TYPE]' に設定されます。 + +選択された一部のリンクセットは、形状が凸状でないため、'[REQUESTED_TYPE]' に設定できません。これらのリンクセットの用途タイプは変わりません。 + +続けますか? + <usetemplate ignoretext="選択された一部のリンクセットのファントムフラグが切り替えられ、他のリンクセットはリンクセットへの権限が制限され、また形状が凸状でないため設定できません。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + 選択されたオブジェクトはナビメッシュに影響を与えます。オブジェクトをフレキシブルパスに変更すると、ナビメッシュから削除されます。 + <usetemplate ignoretext="選択されたオブジェクトはナビメッシュに影響を与えます。オブジェクトをフレキシブルパスに変更すると、ナビメッシュから削除されます。" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> [APP_NAME] に必要なハードウェアがないようです。 [APP_NAME] にはマルチテクスチャをサポートする OpenGL グラフィックカードが必要です。 お使いのグラフィックカードの最新ドライバがインストールされているかどうか、オペレーティングシステムのサービスパックとパッチが入っているかをご確認ください。 @@ -3197,4 +3370,12 @@ M キーを押して変更します。 開くことができない、またはデコードできない無効または読み取り不能な画像ファイル [FNAME] を追加しようとしました。 この試行はキャンセルされました。 </notification> + <notification name="PathfindingReturnMultipleItems"> + [NUM_ITEMS] 個のアイテムを返却中です。続けますか? + <usetemplate ignoretext="複数のアイテムを返しますか?" name="okcancelignore" notext="いいえ" yestext="はい"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + [NUM_ITEMS] 個のアイテムを削除中です。続けますか? + <usetemplate ignoretext="複数のアイテムを削除しますか?" name="okcancelignore" notext="いいえ" yestext="はい"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml b/indra/newview/skins/default/xui/ja/panel_bottomtray.xml deleted file mode 100644 index 3529abbf36..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="マイクのオン・オフ"/> - <string name="VoiceControlBtnToolTip" value="ボイスコントロールパネルの表示・非表示"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="話す" label_selected="話す" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="ジェスチャー" name="Gesture" tool_tip="ジェスチャーの表示・非表示"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="移動" name="movement_btn" tool_tip="移動コントロールの表示・非表示"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="視界" name="camera_btn" tool_tip="カメラコントロールの表示・非表示"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="スナップショットを撮ります"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="制作" name="build_btn" tool_tip="制作ツールの表示・非表示"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="検索" name="search_btn" tool_tip="検索の表示・非表示"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="地図" name="world_map_btn" tool_tip="世界地図の表示・非表示"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="ミニマップ" name="mini_map_btn" tool_tip="ミニマップの表示・非表示"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="会話"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="通知"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_group_invite.xml b/indra/newview/skins/default/xui/ja/panel_group_invite.xml index a21b340fdd..cc9ebc405b 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> 選択した住人のなかに、既にグループに所属している人がいるため、招待を送ることができませんでした。 </panel.string> + <panel.string name="invite_selection_too_large"> + グループへの招待が送信されていません: 選択された住人が多すぎます。グループへの招待は1回のリクエストあたり100人に制限されています。 + </panel.string> <text bottom_delta="-96" font="SansSerifSmall" height="72" name="help_text"> グループには一度に複数の住人を招待することができます。 「リストから住人を選択」をクリックしてください。 </text> diff --git a/indra/newview/skins/default/xui/ja/panel_login.xml b/indra/newview/skins/default/xui/ja/panel_login.xml index ac1fe455c7..396d9e65b1 100644 --- a/indra/newview/skins/default/xui/ja/panel_login.xml +++ b/indra/newview/skins/default/xui/ja/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://jp.secondlife.com/registration/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=ja </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ログイン + </text> <text name="username_text"> ユーザーネーム: </text> @@ -15,15 +15,8 @@ <text name="password_text"> パスワード: </text> - <check_box label="パスワードを記憶" name="remember_check"/> - <button label="ログイン" left_pad="30" name="connect_btn" width="60"/> - <text name="mode_selection_text"> - モード: - </text> - <combo_box name="mode_combo" tool_tip="モードを選択します。ベーシックモードでは探索やチャットをすばやく簡単に実行でき、アドバンスモードでは、より多くの機能が利用できます。"> - <combo_box.item label="ベーシック" name="Basic"/> - <combo_box.item label="アドバンス" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> 開始地点: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<地域名を入力>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - お申し込み + <layout_panel name="links_login_panel"> + <text name="login_help"> + ログインの方法 </text> <text name="forgot_password_text"> ユーザー名またはパスワードをお忘れですか? </text> - <text name="login_help"> - ログインの方法 + <button label="ログイン" left_pad="30" name="connect_btn" width="60"/> + <check_box label="パスワードを記憶" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + アカウントを作成してください </text> + <button label="今すぐ開始" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/ja/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..ea3ec32424 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="地域の再構築" name="navmesh_btn" tool_tip="クリックしてこの地域のナビメッシュを再構築します。"/> + <button label="再構築をリクエスト中" name="navmesh_btn_sending" tool_tip="再構築リクエストをサーバーに送信しています。"/> + <button label="地域(リージョン)を再構築中" name="navmesh_btn_baking" tool_tip="地域を再構築しています。完了すると、このボタンは消えます。"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml index 75bf28a3c8..b6e344ca48 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="IM チャット" name="EnableIMChatPopups" tool_tip="これを選択すると、インスタントメッセージを受信した際にポップアップが表示されます"/> <spinner label="近くのチャットメッセージが表示される長さ:" name="nearby_toasts_lifetime"/> <spinner label="近くのチャットメッセージが消えるまでの長さ:" name="nearby_toasts_fadingtime"/> - <button label="チャットの翻訳設定" name="ok_btn"/> + <button label="他の言語..." name="ok_btn"/> + <button label="自動置換..." name="autoreplace_showgui"/> + <button label="スペルチェック中..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_region_debug.xml b/indra/newview/skins/default/xui/ja/panel_region_debug.xml index f6865c12b1..169da27ce5 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" name="top_scripts_help"/> <button label="地域再起動" name="restart_btn" tool_tip="2分間のカウントダウン後、地域を再起動します"/> <button label="?" name="restart_help"/> - <button label="再起動を遅延" name="cancel_restart_btn" tool_tip="地域の再起動を1時間遅延します"/> + <button label="再起動をキャンセル" name="cancel_restart_btn" tool_tip="リージョンの再起動をキャンセル"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_region_estate.xml b/indra/newview/skins/default/xui/ja/panel_region_estate.xml index 2e58c5a8f1..b5cc6b9765 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_estate.xml @@ -19,7 +19,7 @@ 次の住人にのみアクセスを許可: </text> <check_box label="支払情情報が登録されている" name="limit_payment" tool_tip="支払情報が登録されていないと、この不動産にアクセスすることはできません。詳細については、[SUPPORT_SITE] をご覧ください。"/> - <check_box label="年齢確認が済んでいる" name="limit_age_verified" tool_tip="この不動産にアクセスするには、年齢確認を済ませる必要があります。詳細については、[SUPPORT_SITE] をご覧ください。"/> + <check_box label="18 才以上です" name="limit_age_verified" tool_tip="この不動産(エステート)にアクセスするには、18 才以上でなければなりません。詳細については、[SUPPORT_SITE] をご覧ください。"/> <check_box label="ボイスチャットを許可" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <text name="abuse_email_text"> diff --git a/indra/newview/skins/default/xui/ja/panel_region_texture.xml b/indra/newview/skins/default/xui/ja/panel_region_texture.xml deleted file mode 100644 index 9e442ce091..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_region_texture.xml +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="地面テクスチャ" name="Textures"> - <text name="region_text_lbl"> - 地域: - </text> - <text name="region_text"> - 未知 - </text> - <text name="detail_texture_text"> - 地形のテクスチャ (512x512、24ビット .tgaファイルが必要です) - </text> - <text name="height_text_lbl"> - 1(低) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4(高) - </text> - <text name="height_text_lbl5"> - 地形テクスチャの隆起範囲 - </text> - <text name="height_text_lbl6"> - 北西 - </text> - <text name="height_text_lbl7"> - 北東 - </text> - <text name="height_text_lbl8"> - 南西 - </text> - <text name="height_text_lbl9"> - 南東 - </text> - <spinner label="低" name="height_start_spin_0"/> - <spinner label="低" name="height_start_spin_1"/> - <spinner label="低" name="height_start_spin_2"/> - <spinner label="低" name="height_start_spin_3"/> - <spinner label="高" name="height_range_spin_0"/> - <spinner label="高" name="height_range_spin_1"/> - <spinner label="高" name="height_range_spin_2"/> - <spinner label="高" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - 数値は上のテクスチャが調和する範囲を示します。 - </text> - <text name="height_text_lbl11"> - 計測単位はメートルで、「低」の値は、1番のテクスチャの高さの -「最大値」です。「高」の値は、4番のテクスチャの高さの「最低値」です。 - </text> - <text name="height_text_lbl12"> - そして「高」の値はテクスチャ#4の高さの下限となります。 - </text> - <button label="適用" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_side_tray.xml b/indra/newview/skins/default/xui/ja/panel_side_tray.xml deleted file mode 100644 index 3fd14ece06..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="サイドバーを表示・非表示" name="sidebar_openclose" tab_title="サイドバーを開く・閉じる"/> - <sidetray_tab description="ホーム。" name="sidebar_home" tab_title="ホーム"> - <panel label="ホーム" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="あなたの公開プロフィールとピックを編集してください。" name="sidebar_me" tab_title="マイ プロフィール"> - <panel_container name="panel_container"> - <panel label="ミー" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="フレンド、連絡先、近くの人を探してください。" name="sidebar_people" tab_title="人"> - <panel_container name="panel_container"> - <panel label="グループ情報" name="panel_group_info_sidetray"/> - <panel label="ブロックされた住人とオブジェクト" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="行きたい場所、行ったことのある場所を探してください。" label="場所" name="sidebar_places" tab_title="場所"> - <panel label="場所" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="あなたの持ち物を眺めてください。" name="sidebar_inventory" tab_title="持ち物"> - <panel label="持ち物を編集" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="あなたの容姿や現在の見た目を変更してください。" name="sidebar_appearance" tab_title="容姿"> - <panel label="容姿の編集" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml new file mode 100644 index 0000000000..967dedf061 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="マスター" name="System Volume"/> + <slider label="ボタン" name="UI Volume"/> + <slider label="環境音" name="Wind Volume"/> + <slider label="サウンド" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="ジェスチャーの音を有効にする"/> + <slider label="音楽" name="Music Volume"/> + <check_box name="enable_music" tool_tip="ストリーミング音楽を有効にする"/> + <slider label="メディア" name="Media Volume"/> + <check_box name="enable_media" tool_tip="ストリーミングメディアを有効にする"/> + <slider label="ボイス" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="ボイスチャットを有効にする"/> +</panel> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml index 6931e448b3..e70d91d258 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml @@ -1,8 +1,11 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="item properties" title="アイテムのプロフィール"> <panel.string name="unknown"> (不明) </panel.string> + <panel.string name="unknown_multiple"> + (不明/複数) + </panel.string> <panel.string name="public"> (公開) </panel.string> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml index eb2bfa993b..c61c73657f 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> これらのオブジェクトを修正できません </panel.string> + <panel.string name="text modify info 5"> + 地域(リージョン)の境界を越えてこのオブジェクトを修正できません + </panel.string> + <panel.string name="text modify info 6"> + 地域(リージョン)の境界を越えてこれらのオブジェクトを修正できません + </panel.string> <panel.string name="text modify warning"> このオブジェクトには、パーツがリンクされています </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="価格: L$" name="Edit Cost"/> <check_box label="検索に表示" name="search_check" tool_tip="このオブジェクトを検索結果に表示します"/> + <text name="pathfinding_attributes_label"> + パスファインディング属性: + </text> <text name="B:"> B. </text> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index f6b3edc57f..50697e5500 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -137,7 +137,7 @@ 終了 </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=ja-JP + http://join.secondlife.com/index.php?lang=ja-JP&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> お使いの古いビューワでは Second Life にアクセスできません。以下のページから新しいビューワをダウンロードしてください: @@ -1006,6 +1006,9 @@ support@secondlife.com にお問い合わせください。 <string name="script_files"> スクリプト </string> + <string name="dictionary_files"> + 辞書 + </string> <string name="AvatarSetNotAway"> 一時退席中解除 </string> @@ -1411,6 +1414,12 @@ support@secondlife.com にお問い合わせください。 <string name="InvFolder favorite"> お気に入り </string> + <string name="InvFolder Favorites"> + お気に入り + </string> + <string name="InvFolder favorites"> + お気に入り + </string> <string name="InvFolder Current Outfit"> 着用中のアウトフィット </string> @@ -1426,6 +1435,12 @@ support@secondlife.com にお問い合わせください。 <string name="InvFolder Meshes"> メッシュ </string> + <string name="InvFolder Received Items"> + 受け取った商品 + </string> + <string name="InvFolder Merchant Outbox"> + マーチャントのアウトボックス + </string> <string name="InvFolder Friends"> フレンド </string> @@ -3864,6 +3879,12 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ <string name="LocationCtrlSeeAVsTooltip"> この区画外にアバターを見えるようにして、チャットも許可 </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + 地域(リージョン)が再構築されるまで、移動するオブジェクトは正しく動作しない可能性があります。 + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + この地域(リージョン)でダイナミックパスファインディングが有効になっていません。 + </string> <string name="UpdaterWindowTitle"> [APP_NAME] アップデート </string> @@ -5006,6 +5027,21 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ <string name="Normal"> 普通 </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + なし + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + ナビメッシュに影響を与える + </string> + <string name="Pathfinding_Object_Attr_Character"> + キャラクター + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (複数) + </string> <string name="snapshot_quality_very_low"> 非常に低い </string> @@ -5021,4 +5057,10 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ <string name="snapshot_quality_very_high"> 非常に高い </string> + <string name="TeleportMaturityExceeded"> + 住人はこの地域(リージョン)を訪問できません。 + </string> + <string name="UserDictionary"> + [User] + </string> </strings> diff --git a/indra/newview/skins/default/xui/ja/teleport_strings.xml b/indra/newview/skins/default/xui/ja/teleport_strings.xml index 64f01f4030..7868c25807 100644 --- a/indra/newview/skins/default/xui/ja/teleport_strings.xml +++ b/indra/newview/skins/default/xui/ja/teleport_strings.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes"?> <teleport_messages> <message_set name="errors"> <message name="invalid_tport"> @@ -47,6 +47,9 @@ <message name="no_inventory_host"> インベントリシステムは現在利用できません。 </message> + <message name="MustGetAgeRegion"> + この地域(リージョン)に入るには 18 才以上である必要があります。 + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -82,5 +85,8 @@ <message name="requesting"> テレポートをリクエスト... </message> + <message name="pending"> + テレポートを保留中... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index 0194293642..f255b1b8ea 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -1106,7 +1106,6 @@ Możesz normalnie używać [SECOND_LIFE], inni użytkownicy będą Cię widzieli Instalacja [APP_NAME] zakończona. Jeżeli używasz [SECOND_LIFE] po raz pierwszy to musisz stworzyć konto żeby móc się zalogować. -Czy chcesz przejść na stronę [http://join.secondlife.com secondlife.com] żeby stworzyć nowe konto? <usetemplate name="okcancelbuttons" notext="Kontynuuj" yestext="Nowe konto..."/> </notification> <notification name="LoginPacketNeverReceived"> diff --git a/indra/newview/skins/default/xui/pl/panel_login.xml b/indra/newview/skins/default/xui/pl/panel_login.xml index dc8e7399af..c87a3d3bd4 100644 --- a/indra/newview/skins/default/xui/pl/panel_login.xml +++ b/indra/newview/skins/default/xui/pl/panel_login.xml @@ -5,6 +5,9 @@ </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + POŁĄCZ + </text> <text name="username_text"> Użytkownik: </text> @@ -12,15 +15,8 @@ <text name="password_text"> Hasło: </text> - <check_box label="Zapamiętaj hasło" name="remember_check"/> - <button label="Połącz" name="connect_btn"/> - <text name="mode_selection_text"> - Tryb życia: - </text> - <combo_box name="mode_combo" tool_tip="Wybierz tryb życia. Wybierz tryb turystyczny dla łatwego zwiedzania i czatowania. Wybierz tryb zaawansowany aby mieć dostęp do większej ilości opcji."> - <combo_box.item label="Turystyczny" name="Basic"/> - <combo_box.item label="Zaawansowany" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Rozpocznij w: </text> @@ -30,16 +26,23 @@ <combo_box.item label="<Wpisz Region>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Utwórz nowe konto + <layout_panel name="links_login_panel"> + <text name="login_help"> + Potrzebujesz pomocy z logowaniem się? </text> <text name="forgot_password_text"> Zapomniałeś swojej nazwy użytkownika lub hasła? </text> - <text name="login_help"> - Potrzebujesz pomocy z logowaniem się? + <button label="Połącz" name="connect_btn"/> + <check_box label="Zapamiętaj hasło" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CREATE YǾUR ACCǾUNT </text> + <button name="create_new_account_btn" + label="Utwórz nowe konto" + width="120"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml new file mode 100644 index 0000000000..1611900700 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel name="volumepulldown_floater"> + <slider label="Główny" name="System Volume"/> + <slider label="Przyciski" name="UI Volume"/> + <slider label="Okolica" name="Wind Volume"/> + <slider label="Efekty" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Włącz dźwięki gestów"/> + <slider label="Muzyka" name="Music Volume"/> + <check_box tool_tip="Włącz muzykę strumieniową" name="enable_music"/> + <slider label="Media" name="Media Volume"/> + <check_box tool_tip="Włącz media strumieniowe" name="enable_media"/> + <slider label="Głos" name="Voice Volume"/> + <check_box tool_tip="Włącz rozmowy głosowe" name="enable_voice_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index e843e56090..299f88b22a 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -65,27 +65,26 @@ Versão do servidor de voz: [VOICE_VERSION] </panel> <panel label="Licenças" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion - APR Copyright (C) 2000-2004 The Apache Software Foundation - Collada DOM Copyright 2005 Sony Computer Entertainment Inc. - cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. - FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). + FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University e David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. - ogg/vorbis Copyright (C) 2001, Xiphophorus - OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. - PCRE Copyright (c) 1997-2008 University of Cambridge + ogg/vorbis Copyright (C) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. - zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. - google-perftools Copyright (c) 2005, Google Inc. + zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. O Visualizador do Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e seus Licenciantes). Todos os direitos reservados. Consulte www.havok.com para obter detalhes. 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 cd0fb4c41b..f48280840c 100644 --- a/indra/newview/skins/default/xui/pt/floater_about_land.xml +++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml @@ -465,7 +465,7 @@ Mídia: Permitir acesso apenas para residentes que: </text> <check_box label="Possuam Dados de pagamento fornecidos [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Os residentes devem ter seus dados de pagamento cadastrados para acessar este lote. Consulte o [SUPPORT_SITE] para saber mais."/> - <check_box label="Tiveram sua idade verificada [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Os residentes devem ter a idade verificada para acessar este lote. Consulte o [SUPPORT_SITE] para saber mais."/> + <check_box label="Tem 18 anos ou mais [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Os residentes devem ter 18 anos ou mais para acessar este lote. Consulte o [SUPPORT_SITE] para obter mais informações."/> <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"> diff --git a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_preview.xml deleted file mode 100644 index 3ec81612a1..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml +++ /dev/null @@ -1,187 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview" title=""> - <floater.string name="failed_to_initialize"> - Não foi possível iniciar o movimento - </floater.string> - <floater.string name="anim_too_long"> - O arquivo de animação tem [LENGTH] segundos de duração. - -A duração máxima de animação permitida é de [MAX_LENGTH] segundos. - </floater.string> - <floater.string name="failed_file_read"> - Não foi possível ler o arquivo de animação. - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - OK - </floater.string> - <floater.string name="E_ST_EOF"> - Fim de arquivo prematuro - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Impossível ler definição constraint. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - Impossível abrir arquivo BVH. - </floater.string> - <floater.string name="E_ST_NO_HIER"> - Invalid HIERARCHY header. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - RAIZ ou JUNTA não encontrados. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - Impossível obter nome JOINT. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - Impossível localizar OFFSET. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - Impossível localizar CHANNELS. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Impossível obter ordem de rotação. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Impossível obter eixo de rotação. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - Impossível localizar MOTION. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - Impossível determinar número de quadros. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Impossível determinar tempo dos quadros. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Impossível definir posicionamento. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Impossível definir valores da rotação. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Impossível abrir arquivo de tradução. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Impossível ler cabeçalho de tradução. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Impossível ler nomes traduzidos. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Impossível obter valor traduzido a ignorar. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Impossível obter valor traduzido relativo. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Impossível obter valor traduzido. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Impossível ler matriz de tradução. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Impossível obter nome mergechild. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Impossível obter nome mergeparent. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Impossível obter valor prioritário. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Impossível obter valor do loop. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Impossível obter valor easeIn. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - Impossível obter valor easeOut. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Impossível obter valor de morph da mão. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Impossível ler nome do emote. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Nome da junta incorreto, use "quadril". - </floater.string> - <text name="name_label"> - Nome: - </text> - <text name="description_label"> - Descrição: - </text> - <spinner label="Prioridade" label_width="72" name="priority" tool_tip="Controla quais animações podem ser interrompidas por esta animação" width="110"/> - <check_box label="Loop" name="loop_check" tool_tip="Executa esta animação sem parar"/> - <spinner label="Dentro(%)" label_width="56" left="65" name="loop_in_point" tool_tip="Define o ponto em que a animação em loop reinicia" width="116"/> - <spinner label="Fora(%)" label_width="40" left="185" name="loop_out_point" tool_tip="Define o ponto em que a animação em loop acaba"/> - <text name="hand_label"> - Pose de Mão - </text> - <combo_box left_delta="100" name="hand_pose_combo" tool_tip="Controla os gestos das mãos durante a animação" width="184"> - <combo_box.item label="Abrir" name="Spread"/> - <combo_box.item label="Relaxado" name="Relaxed"/> - <combo_box.item label="Apontar ambas" name="PointBoth"/> - <combo_box.item label="Punho" name="Fist"/> - <combo_box.item label="E relaxada" name="RelaxedLeft"/> - <combo_box.item label="Apontar E" name="PointLeft"/> - <combo_box.item label="Punho E" name="FistLeft"/> - <combo_box.item label="D relaxada" name="RelaxedRight"/> - <combo_box.item label="Apontar D" name="PointRight"/> - <combo_box.item label="Punho D" name="FistRight"/> - <combo_box.item label="Saudação D" name="SaluteRight"/> - <combo_box.item label="Escrevendo" name="Typing"/> - <combo_box.item label="Paz D" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Expressão - </text> - <combo_box left_delta="100" name="emote_combo" tool_tip="Controla as expressões faciais durante a animação" width="184"> - <item label="(nenhum)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Com medo" name="Afraid" value="Com medo"/> - <item label="Bravo" name="Angry" value="Bravo"/> - <item label="Sorriso contagiante" name="BigSmile" value="Sorriso contagiante"/> - <item label="À toa" name="Bored" value="À toa"/> - <item label="Chorar" name="Cry" value="Chorar"/> - <item label="Desdenho" name="Disdain" value="Desdenho"/> - <item label="Com vergonha" name="Embarrassed" value="Com vergonha"/> - <item label="Franzir testa" name="Frown" value="Franzir testa"/> - <item label="Beijo" name="Kiss" value="Beijo"/> - <item label="Rir" name="Laugh" value="Rir"/> - <item label="Mostrar a língua" name="Plllppt" value="Mostrar a língua"/> - <item label="Asco" name="Repulsed" value="Asco"/> - <item label="Triste" name="Sad" value="Triste"/> - <item label="Encolher os ombros" name="Shrug" value="Encolher os ombros"/> - <item label="Sorriso" name="Smile" value="Sorriso"/> - <item label="Surpresa" name="Surprise" value="Surpresa"/> - <item label="Piscar" name="Wink" value="Piscar"/> - <item label="Preocupado" name="Worry" value="Preocupado"/> - </combo_box> - <text name="preview_label" width="250"> - Prever enquanto - </text> - <combo_box left_delta="100" name="preview_base_anim" tool_tip="Use isto para testar o comportamento de sua animação enquanto seu avatar executa ações comuns." width="130"> - <item label="Em pé" name="Standing" value="Em pé"/> - <item label="Andando" name="Walking" value="Andando"/> - <item label="Sentado" name="Sitting" value="Sentado"/> - <item label="Voando" name="Flying" value="Voando"/> - </combo_box> - <spinner label="Facilitar a entrada (sec)" label_width="125" name="ease_in_time" tool_tip="Tempo (em segundos) da transição inicial da animação" width="192"/> - <spinner bottom_delta="-20" label="Facilitar a saída (sec)" label_width="125" left="10" name="ease_out_time" tool_tip="Tempo (em segundos) da transição de saída da animação" width="192"/> - <button bottom_delta="-32" name="play_btn" tool_tip="Executar animação"/> - <button name="pause_btn" tool_tip="Pausar a animação"/> - <button label="" name="stop_btn" tool_tip="Interrompe a execução da animação."/> - <text name="bad_animation_text"> - Incapaz de ler o arquivo de animação. - -Nós recomendamos exportar arquivos BVH do -Poser 4. - </text> - <button label="Carregar (L$[AMOUNT])" name="ok_btn"/> - <button label="Cancelar" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_autoreplace.xml b/indra/newview/skins/default/xui/pt/floater_autoreplace.xml new file mode 100644 index 0000000000..ca813a8540 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Configurações da substituição automática"> + <check_box label="Habilitar substituição automática" name="autoreplace_enable" tool_tip="Ao inserir texto de bate-papo, substitua quaisquer palavras-chave inseridas pela substituição correspondente"/> + <button label="Importar lista..." name="autoreplace_import_list" tool_tip="Carrega uma lista exportada anteriormente de um arquivo."/> + <button label="Exportar lista..." name="autoreplace_export_list" tool_tip="Salva um arquivo da lista selecionada para compartilhá-la."/> + <button label="Nova lista..." name="autoreplace_new_list" tool_tip="Cria uma nova lista."/> + <button label="Excluir lista" name="autoreplace_delete_list" tool_tip="Exclui a lista selecionada."/> + <button name="autoreplace_list_up" tool_tip="Aumenta a prioridade desta lista."/> + <button name="autoreplace_list_down" tool_tip="Diminui a prioridade desta lista."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Palavra-chave" name="keyword"/> + <scroll_list.columns label="Substituição" name="replacement"/> + </scroll_list> + <button label="Adicionar..." name="autoreplace_add_entry"/> + <button label="Remover" name="autoreplace_delete_entry"/> + <button label="Salvar entrada" name="autoreplace_save_entry" tool_tip="Salva esta entrada."/> + <button label="Salvar alterações" name="autoreplace_save_changes" tool_tip="Salvar todas as alterações."/> + <button label="Cancelar" name="autoreplace_cancel" tool_tip="Descarta todas as alterações."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/pt/floater_inventory.xml b/indra/newview/skins/default/xui/pt/floater_inventory.xml deleted file mode 100644 index ae3312eab0..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_inventory.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="MEU INVENTÁRIO"> - <floater.string name="Title"> - MEU INVENTÁRIO - </floater.string> - <floater.string name="TitleFetching"> - MEU INVENTÁRIO (Pegando [ITEM_COUNT] items...) [FILTER] - </floater.string> - <floater.string name="TitleCompleted"> - MEU INVENTÁRIO ([ITEM_COUNT] items) [FILTER] - </floater.string> - <floater.string name="Fetched"> - Obtido - </floater.string> - <panel label="Painel do inventário" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_model_preview.xml b/indra/newview/skins/default/xui/pt/floater_model_preview.xml index 8960500831..8194278b16 100644 --- a/indra/newview/skins/default/xui/pt/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/pt/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="Triângulos" name="triangles" value="Triângulos"/> <text initial_value="Vértices" name="vertices" value="Vértices"/> <text initial_value="Alto" name="high_label" value="Alto"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + </combo_box> <button label="Procurar..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Médio" name="medium_label" value="Médio"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + <item name="Use LoD above" value="Usar LoD acima"/> + </combo_box> <button label="Procurar..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Baixo" name="low_label" value="Baixo"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + <item name="Use LoD above" value="Usar LoD acima"/> + </combo_box> <button label="Procurar..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Mais baixo" name="lowest_label" value="Mais baixo"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Carregar do arquivo"/> + <item name="Generate" value="Gerar"/> + <item name="Use LoD above" value="Usar LoD acima"/> + </combo_box> <button label="Procurar..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Limite de triângulos"/> + <item name="Error Threshold" value="Limite de erro"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Gerar normais" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml b/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml deleted file mode 100644 index 653861f7d8..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="Bate-papo local"> - <check_box label="Traduzir bate-papo" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..05784115e7 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Personagens do pathfinding"> + <floater.string name="messaging_get_inprogress"> + Procurando por personagens do pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Erro detectado ao procurar por personagens do pathfinding. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nenhum personagem do pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] personagens selecionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Carregando] + </floater.string> + <floater.string name="character_owner_unknown"> + [Desconhecido] + </floater.string> + <floater.string name="character_owner_group"> + [grupo] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome" name="name"/> + <scroll_list.columns label="Descrição" name="description"/> + <scroll_list.columns label="Proprietário" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="Altitude" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Personagens: + </text> + <button label="Atualizar lista" name="refresh_objects_list"/> + <button label="Selecionar tudo" name="select_all_objects"/> + <button label="Selecionar nenhum" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Ações nos personagens selecionados: + </text> + <check_box label="Exibir baliza" name="show_beacon"/> + <check_box label="Exibir cápsula da física" name="show_physics_capsule"/> + <button label="Pegar" name="take_objects"/> + <button label="Pegar uma cópia" name="take_copy_objects"/> + <button label="Teletransportar-me até ele" name="teleport_me_to_object" tool_tip="Habilitado apenas quando um personagem é selecionado."/> + <button label="Devolver" name="return_objects"/> + <button label="Excluir" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml new file mode 100644 index 0000000000..182f2513e0 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Visualização/teste do pathfinding"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Impossível encontrar a implementação de biblioteca de pathing. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Aguardando a conclusão do carregamento da região. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Verificando o status do navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Baixando o navmesh. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + O navmesh foi alterado no servidor. Baixando o navmesh mais recente. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + O navmesh mais recente foi baixado. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Impossível baixar o navmesh com êxito. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + O navmesh tem alterações pendentes. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + O navmesh está compilando. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Algumas regiões navmesh têm alterações pendentes. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Algumas regiões navmesh estão compilando. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Algumas regiões navmesh têm alterações pendentes e outras estão compilando. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + O navmesh está atualizado. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Impossível encontrar a implementação de biblioteca de pathing. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Escolha os pontos inicial e final. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Escolha o ponto inicial. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Escolha o ponto final. + </floater.string> + <floater.string name="pathing_path_valid"> + O caminho é exibido em laranja. + </floater.string> + <floater.string name="pathing_path_invalid"> + Impossível encontrar um caminho entre os pontos escolhidos. + </floater.string> + <floater.string name="pathing_error"> + Ocorreu um erro durante a geração do caminho. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Visualizar" name="view_panel"> + <text name="show_label"> + Exibir: + </text> + <check_box label="Mundo" name="show_world"/> + <check_box label="Apenas móveis" name="show_world_movables_only"/> + <check_box label="Navmesh" name="show_navmesh"/> + <text name="show_walkability_label"> + Exibir mapa de possibilidade de caminhar: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Não exibir" name="show_heatmap_mode_none"/> + <combo_box.item label="Tipo de personagem A" name="show_heatmap_mode_a"/> + <combo_box.item label="Tipo de personagem B" name="show_heatmap_mode_b"/> + <combo_box.item label="Tipo de personagem C" name="show_heatmap_mode_c"/> + <combo_box.item label="Tipo de personagem D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Caminháveis" name="show_walkables"/> + <check_box label="Volumes materiais" name="show_material_volumes"/> + <check_box label="Obstáculos estáticos" name="show_static_obstacles"/> + <check_box label="Volumes de exclusão" name="show_exclusion_volumes"/> + <check_box label="Plano aquático" name="show_water_plane"/> + <check_box label="Com visão de raio X" name="show_xray"/> + </panel> + <panel label="Testar caminho" name="test_panel"> + <text name="ctrl_click_label"> + Aperte a tecla Ctrl e clique com o mouse para selecionar o ponto inicial. + </text> + <text name="shift_click_label"> + Aperte a tecla Shift e clique com o mouse para selecionar o ponto final. + </text> + <text name="character_width_label"> + Largura do personagem + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Tipo de personagem + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Nenhum" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Limpar caminho" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..e0c60679dd --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Linksets do pathfinding"> + <floater.string name="messaging_get_inprogress"> + Procurando por linksets do pathfinding... + </floater.string> + <floater.string name="messaging_get_error"> + Erro detectado ao procurar por linksets do pathfinding. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Modificando os linksets do pathfinding selecionados... + </floater.string> + <floater.string name="messaging_set_error"> + Erro detectado ao modificar os linksets do pathfinding selecionados. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Nenhum linkset do pathfinding. + </floater.string> + <floater.string name="messaging_complete_available"> + [NUM_SELECTED] linksets selecionados de [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + Esta região não está habilitada para pathfinding. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terreno] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Carregando] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Desconhecido] + </floater.string> + <floater.string name="linkset_owner_group"> + [grupo] + </floater.string> + <floater.string name="linkset_is_scripted"> + Sim + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Não + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Desconhecido + </floater.string> + <floater.string name="linkset_use_walkable"> + Caminhável + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Obstáculo estático + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Obstáculo móvel + </floater.string> + <floater.string name="linkset_use_material_volume"> + Volume material + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Volume de exclusão + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Fantasma móvel + </floater.string> + <floater.string name="linkset_is_terrain"> + [inalterável] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restrito] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [côncavo] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restrito,côncavo] + </floater.string> + <floater.string name="linkset_choose_use"> + Escolher uso do linkset... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Filtrar por uso do linkset..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Caminhável" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Obstáculo estático" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Obstáculo móvel" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Volume material" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Volume de exclusão" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Fantasma móvel" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Aplicar" name="apply_filters"/> + <button label="Limpar" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Nome (prim raiz)" name="name"/> + <scroll_list.columns label="Descrição (prim raiz)" name="description"/> + <scroll_list.columns label="Proprietário" name="owner"/> + <scroll_list.columns label="Com script" name="scripted"/> + <scroll_list.columns label="Impacto" name="land_impact"/> + <scroll_list.columns label="Distância" name="dist_from_you"/> + <scroll_list.columns label="Uso do linkset" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Linksets: + </text> + <button label="Atualizar lista" name="refresh_objects_list"/> + <button label="Selecionar tudo" name="select_all_objects"/> + <button label="Selecionar nenhum" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Exibir baliza" name="show_beacon"/> + <button label="Pegar" name="take_objects"/> + <button label="Pegar uma cópia" name="take_copy_objects"/> + <button label="Teletransportar-me até ele" name="teleport_me_to_object"/> + <button label="Devolver" name="return_objects"/> + <button label="Excluir" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Possibilidade de caminhar: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Possibilidade de caminhar para os personagens do tipo A. Por exemplo: o tipo do personagem é humano."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Possibilidade de caminhar para os personagens do tipo B. Por exemplo: o tipo do personagem é criatura."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Possibilidade de caminhar para os personagens do tipo C. Por exemplo: o tipo do personagem é robô."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Possibilidade de caminhar para os personagens do tipo D. Por exemplo: o tipo do personagem é outro."/> + <button label="Aplicar alterações" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humano) + </text> + <text name="suggested_use_b_label"> + (Criatura) + </text> + <text name="suggested_use_c_label"> + (Robô) + </text> + <text name="suggested_use_d_label"> + (Outro) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_postcard.xml b/indra/newview/skins/default/xui/pt/floater_postcard.xml deleted file mode 100644 index 9740fbcb4d..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_postcard.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ENVIAR FOTO VIA EMAIL"> - <text name="to_label" width="135"> - Para (email): - </text> - <line_editor left="143" name="to_form" width="127"/> - <text name="from_label"> - De (email): - </text> - <line_editor left="143" name="from_form" width="127"/> - <text name="name_label"> - Seu nome: - </text> - <line_editor left="143" name="name_form" width="127"/> - <text name="subject_label"> - Assunto: - </text> - <line_editor left="143" name="subject_form" width="127"/> - <line_editor label="Digite o assunto aqui" name="subject_form"/> - <text name="msg_label"> - Mensagem: - </text> - <text_editor name="msg_form"> - Digite sua mensagem aqui. - </text_editor> - <text name="fine_print"> - Se seu indicado entrar no [SECOND_LIFE], você receberá um bônus pela indicação. - </text> - <button label="Cancelar" name="cancel_btn"/> - <button label="Enviar" name="send_btn"/> - <string name="default_subject"> - Postal do [SECOND_LIFE]. - </string> - <string name="default_message"> - Dá uma olhada nisto! - </string> - <string name="upload_message"> - Enviando... - </string> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_spellcheck.xml b/indra/newview/skins/default/xui/pt/floater_spellcheck.xml new file mode 100644 index 0000000000..02bb154d26 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Configurações do verificador ortográfico"> + <check_box label="Habilitar verificador ortográfico" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Dicionário principal: + </text> + <text label="Logs:" name="spellcheck_additional"> + Dicionários adicionais: + </text> + <text name="spellcheck_available"> + Disponível + </text> + <text name="spellcheck_active"> + Ativo + </text> + <button label="Remover" name="spellcheck_remove_btn"/> + <button label="Importar..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml new file mode 100644 index 0000000000..f4e95bddec --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Importar dicionário"> + <button label="Procurar" label_selected="Procurar" name="dictionary_path_browse"/> + <button label="Importar" name="ok_btn"/> + <button label="Cancelar" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_stats.xml b/indra/newview/skins/default/xui/pt/floater_stats.xml index e770c6ac38..be53624145 100644 --- a/indra/newview/skins/default/xui/pt/floater_stats.xml +++ b/indra/newview/skins/default/xui/pt/floater_stats.xml @@ -47,6 +47,12 @@ <stat_bar label="Low LOD Objects" name="physicslodtasks"/> <stat_bar label="Memory Allocated" name="physicsmemoryallocated"/> </stat_view> + <stat_bar label="Scripts executados" name="simpctscriptsrun"/> + <stat_view label="Pathfinding" name="simpathfinding"> + <stat_bar label="Tempo de etapa de AI" name="simsimaistepmsec"/> + <stat_bar label="Etapas de silhueta ignoradas" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Personagens atualizados" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_view label="Time (ms)" name="simperf"> <stat_bar label="Total Frame Time" name="simframemsec"/> <stat_bar label="Net Time" name="simnetmsec"/> diff --git a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml index 57223beaeb..a75cf34a94 100644 --- a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml @@ -19,6 +19,8 @@ <button label="Padrão" label_selected="Padrão" name="Default"/> <button label="Branco" label_selected="Branco" name="Blank"/> <button label="Nenhum" label_selected="Nenhum" name="None"/> + <check_box initial_value="true" label="Visualização em tempo real" name="apply_immediate_check"/> + <text name="preview_disabled" value="Visualização desativada"/> <filter_editor label="Filtrar texturas" name="inventory search editor"/> <check_box initial_value="false" label="Exibir pastas" name="show_folders_check"/> <button label="Adicionar" label_selected="Adicionar" name="l_add_btn"/> @@ -30,5 +32,4 @@ </scroll_list> <button label="OK" label_selected="OK" name="Select"/> <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> - <check_box initial_value="true" label="Applicar agora" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml index f20d50362e..0e897aea09 100644 --- a/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, Obtendo novamente visíveis do cache, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels </text> + <text name="total_time_refetch_all_cache_label"> + 16, Obtendo novamente todas as texturas do cache, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + </text> <text name="total_time_refetch_vis_http_label"> - 16, Obtendo novamente visíveis do HTTP, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + 17, Obtendo novamente visíveis do HTTP, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + </text> + <text name="total_time_refetch_all_http_label"> + 18, Obtendo novamente todas as texturas do HTTP, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels + </text> + <spinner label="19, Proporção de texel/pixel:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Origem da textura: </text> - <spinner label="17, Proporção de texel/pixel:" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="Cache + HTTP" name="0"/> + <radio_item label="Apenas HTTP" name="1"/> + </radio_group> <button label="Iniciar" name="start_btn"/> <button label="Redefinir" name="clear_btn"/> <button label="Fechar" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="Decodificar" name="decode_btn"/> <button label="Textura GL" name="gl_btn"/> <button label="Obter novamente cache visível" name="refetchviscache_btn"/> + <button label="Obter todo o cache novamente" name="refetchallcache_btn"/> <button label="Obter novamente HTTP visível" name="refetchvishttp_btn"/> + <button label="Obter todo o HTTP novamente" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index 4b31833602..8c245c582e 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -148,6 +148,12 @@ <panel.string name="text modify info 4"> Você não pode modificar estes objetos </panel.string> + <panel.string name="text modify info 5"> + Não é possível modificar este objeto através de uma demarcação da região + </panel.string> + <panel.string name="text modify info 6"> + Não é possível modificar estes objetos através de uma demarcação da região + </panel.string> <panel.string name="text modify warning"> Selecione o objeto inteiro para configurar as autorizações </panel.string> @@ -197,12 +203,12 @@ <combo_box.item label="Zoom" name="Zoom"/> </combo_box> <check_box label="À venda" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Cópia" name="Copy"/> <combo_box.item label="Conteúdo" name="Contents"/> <combo_box.item label="Original" name="Original"/> </combo_box> - <spinner label="Preço: L$" name="Edit Cost"/> <check_box label="Mostrar na busca" name="search_check" tool_tip="Permitir que as pessoas vejam este objeto nos resultados de busca"/> <panel name="perms_build"> <text name="perm_modify"> @@ -238,6 +244,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Atributos do pathfinding: + </text> + </panel> </panel> <panel label="Objeto" name="Object"> <check_box label="Travado" name="checkbox locked" tool_tip="Previne que o objeto seja movido ou apagado. Muito útil para evitar edições não intencionais durante a construção."/> diff --git a/indra/newview/skins/default/xui/pt/floater_top_objects.xml b/indra/newview/skins/default/xui/pt/floater_top_objects.xml index c3d5820616..ef682714c6 100644 --- a/indra/newview/skins/default/xui/pt/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/pt/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Tempo </floater.string> - <floater.string name="scripts_mono_time_label"> - Hora Mono - </floater.string> <floater.string name="top_colliders_title"> Principais Colidentes </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Nome" name="name"/> <scroll_list.columns label="Proprietário" name="owner"/> <scroll_list.columns label="Local" name="location"/> + <scroll_list.columns label="Lote" name="parcel"/> <scroll_list.columns label="Tempo" name="time"/> - <scroll_list.columns label="Hora Mono" name="mono_time"/> <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="Memória (KB)" name="memory"/> </scroll_list> <text name="id_text"> ID do Objeto: @@ -51,6 +49,10 @@ </text> <line_editor font="SansSerifSmall" left="140" name="owner_name_editor" width="280"/> <button label="Filtro" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Lote: + </text> + <button label="Filtrar" name="filter_parcel_btn"/> <button label="Atualizar" name="refresh_btn"/> <button label="Retornar Selecionado" name="return_selected_btn" width="170"/> <button label="Retornar Tudo" left="190" name="return_all_btn"/> diff --git a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml b/indra/newview/skins/default/xui/pt/menu_bottomtray.xml deleted file mode 100644 index 4598b8ab25..0000000000 --- a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Botão Falar" name="EnableVoiceChat"/> - <menu_item_check label="Botão de gestos" name="ShowGestureButton"/> - <menu_item_check label="Botão de movimento" name="ShowMoveButton"/> - <menu_item_check label="Botão de ver" name="ShowCameraButton"/> - <menu_item_check label="Botão de fotos" name="ShowSnapshotButton"/> - <menu_item_check label="Botão Construir" name="ShowBuildButton"/> - <menu_item_check label="Botão Buscar" name="ShowSearchButton"/> - <menu_item_check label="Botão Mapa" name="ShowWorldMapButton"/> - <menu_item_check label="Botão do Mini mapa" name="ShowMiniMapButton"/> - <menu_item_call label="Cortar" name="NearbyChatBar_Cut"/> - <menu_item_call label="Copiar" name="NearbyChatBar_Copy"/> - <menu_item_call label="Colar" name="NearbyChatBar_Paste"/> - <menu_item_call label="Excluir" name="NearbyChatBar_Delete"/> - <menu_item_call label="Selecionar tudo" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/pt/menu_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml index 09e1fbf72e..a3a648eb34 100644 --- a/indra/newview/skins/default/xui/pt/menu_inventory.xml +++ b/indra/newview/skins/default/xui/pt/menu_inventory.xml @@ -68,6 +68,7 @@ <menu_item_call label="Excluir pasta do sistema" name="Delete System Folder"/> <menu_item_call label="Pasta conversa em conferência" name="Conference Chat Folder"/> <menu_item_call label="Executar som" name="Sound Play"/> + <menu_item_call label="Copiar SLurl" name="url_copy"/> <menu_item_call label="Sobre o marco" name="About Landmark"/> <menu_item_call label="Executar animação" name="Animation Play"/> <menu_item_call label="Executar áudio" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/pt/menu_mode_change.xml b/indra/newview/skins/default/xui/pt/menu_mode_change.xml deleted file mode 100644 index 314d3e409b..0000000000 --- a/indra/newview/skins/default/xui/pt/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Básico" name="BasicMode"/> - <menu_item_check label="Avançado" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_object.xml b/indra/newview/skins/default/xui/pt/menu_object.xml index f4919e0c1f..28dd9febe2 100644 --- a/indra/newview/skins/default/xui/pt/menu_object.xml +++ b/indra/newview/skins/default/xui/pt/menu_object.xml @@ -5,6 +5,8 @@ </menu_item_call> <menu_item_call label="Editar" name="Edit..."/> <menu_item_call label="Construir" name="Build"/> + <menu_item_call label="Exibir em linksets" name="show_in_linksets"/> + <menu_item_call label="Exibir em personagens" name="show_in_characters"/> <menu_item_call label="Abrir" name="Open"/> <menu_item_call label="Sentar aqui" name="Object Sit"/> <menu_item_call label="Ficar de pé" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/pt/menu_text_editor.xml b/indra/newview/skins/default/xui/pt/menu_text_editor.xml index 31c284c6ed..a26b50e1c2 100644 --- a/indra/newview/skins/default/xui/pt/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/pt/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(desconhecido)" name="Suggestion 1"/> + <menu_item_call label="(desconhecido)" name="Suggestion 2"/> + <menu_item_call label="(desconhecido)" name="Suggestion 3"/> + <menu_item_call label="(desconhecido)" name="Suggestion 4"/> + <menu_item_call label="(desconhecido)" name="Suggestion 5"/> + <menu_item_call label="Adicionar ao dicionário" name="Add to Dictionary"/> + <menu_item_call label="Adicionar para ignorar" name="Add to Ignore"/> <menu_item_call label="Cortar" name="Cut"/> <menu_item_call label="Copiar" name="Copy"/> <menu_item_call label="Colar" name="Paste"/> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index d93330e6df..ca378c1b58 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -28,6 +28,7 @@ <menu_item_call label="Preferências..." name="Preferences"/> <menu_item_call label="Botões da barra de ferramentas..." name="Toolbars"/> <menu_item_call label="Ocultar todos os controles" name="Hide UI"/> + <menu_item_check label="Exibir anexos de HUD" name="Show HUD Attachments"/> <menu_item_call label="Sair do [APP_NAME]" name="Quit"/> </menu> <menu label="Comunicar" name="Communicate"> @@ -39,6 +40,7 @@ <menu_item_call label="Amigos" name="My Friends"/> <menu_item_call label="Grupos" name="My Groups"/> <menu_item_call label="Pessoas próximas" name="Active Speakers"/> + <menu_item_call label="Lista de bloqueados" name="Block List"/> </menu> <menu label="Mundo" name="World"> <menu_item_call label="Criar marco deste lugar" name="Create Landmark Here"/> @@ -124,6 +126,11 @@ <menu_item_call label="Scripts em modo execução" name="Set Scripts to Running"/> <menu_item_call label="Scripts em modo não execução" name="Set Scripts to Not Running"/> </menu> + <menu label="Pathfinding" name="Pathfinding"> + <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Personagens..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Visualização/teste..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Opções" name="Options"> <menu_item_check label="Mostrar permissões avançadas" name="DebugPermissions"/> <menu_item_check label="Só selecionar meus objetos" name="Select Only My Objects"/> @@ -174,7 +181,6 @@ <menu_item_check label="Esconder partículas" name="Hide Particles"/> <menu_item_check label="Ocultar seleções" name="Hide Selected"/> <menu_item_check label="Realçar transparentes" name="Highlight Transparent"/> - <menu_item_check label="Mostrar anexos HUD" name="Show HUD Attachments"/> <menu_item_check label="Mostrar retículo na vista subjetiva" name="ShowCrosshairs"/> </menu> <menu label="Tipos de renderização" name="Rendering Types"> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index 500a7f0c01..ff7382bf80 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -357,13 +363,19 @@ Digite o nome de usuário de seu avatar. É preciso ter uma conta para entrar no [SECOND_LIFE]. Deseja criar uma conta agora? <url name="url"> - https://join.secondlife.com/index.php?lang=pt-BR + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Tentar novamente" yestext="Abrir conta"/> </notification> <notification name="InvalidCredentialFormat"> Digite o nome de usuário ou o nome e sobrenome do seu avatar no campo Nome de usuário, depois entre em sua conta novamente. </notification> + <notification name="InvalidGrid"> + '[GRID]' não é um identificador de grade válido. + </notification> + <notification name="InvalidLocationSLURL"> + Seu ponto de partida não especificou uma grade válida. + </notification> <notification name="DeleteClassified"> Apagar classificado'[NAME]'? Não há reembolso por taxas já pagas. @@ -466,8 +478,8 @@ O objeto pode estar fora de alcance ou ter sido deletado. Houve um problema em salvar uma compilação de script devido a seguinte razão: [REASON]. Por favor, tente salvar novamente o script mais tarde. </notification> <notification name="StartRegionEmpty"> - Oops, você ainda não definiu sua região de partida. -Digite o nome da região na caixa 'Ponto de partida' ou selecione 'Última localização' ou 'Meu início' como ponto de partida. + Sua região de partida não está definida. +Digite o nome da região na caixa 'Ponto de partida' ou selecione 'Meu último local' ou 'Minha casa' como ponto de partida. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -594,6 +606,9 @@ Você pode unir um máximo de [MAX] objetos. Por favor, certifique-se de que nenhum deles está travado e que você é dono de todos eles. </notification> + <notification name="CannotLinkPermanent"> + Os objetos não podem ser vinculados através de demarcações de região. + </notification> <notification name="CannotLinkDifferentOwners"> Impossibilitado de unir porque nem todos os objetos são do mesmo dono. @@ -972,6 +987,41 @@ Oferecer amizade para [NAME]? <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification label="Adicionar lista de substituição automática" name="AddAutoReplaceList"> + Nome para a nova lista: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Renomear lista de substituição automática" name="RenameAutoReplaceList"> + O nome '[DUPNAME]' já está em uso + Insira um novo nome exclusivo: + <form name="form"> + <button name="ReplaceList" text="Substituir lista atual"/> + <button name="SetName" text="Usar novo nome"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + A palavra-chave deve ser uma palavra única e a substituição não pode estar vazia. + </notification> + <notification name="InvalidAutoReplaceList"> + A lista de substituição é inválida. + </notification> + <notification name="SpellingDictImportRequired"> + Você deve especificar um arquivo, um nome e um idioma. + </notification> + <notification name="SpellingDictIsSecondary"> + O dicionário [DIC_NAME] não aparenta ter um arquivo "aff"; isso significa que ele é um dicionário "secundário". +Ele pode ser usado como dicionário adicional mas não como dicionário Principal. + +Consulte https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Impossível copiar + [FROM_NAME] + para + [TO_NAME] + </notification> <notification label="Salvar este look" name="SaveOutfitAs"> Veja o meu novo visual: <form name="form"> @@ -1146,7 +1196,7 @@ para '[THIS_GPU]' Você chegou a uma região próxima. </notification> <notification name="AvatarMovedLast"> - Esse destino não está disponível no momento. + O destino solicitado não está disponível no momento. Você chegou a uma região próxima. </notification> <notification name="AvatarMovedHome"> @@ -1162,11 +1212,10 @@ Enquando isso, use o [SECOND_LIFE] normalmente. Seu visual será exibido correta </form> </notification> <notification name="FirstRun"> - A instalação do [APP_NAME] está pronta. + A instalação do [APP_NAME] está pronta. -Se você ainda não conhece o [SECOND_LIFE], basta criar uma conta para começar. -Voltar para [http://join.secondlife.com secondlife.com] para criar sua conta? - <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Nova conta.."/> +Se você ainda não conhece o [SECOND_LIFE], basta criar uma conta para começar. + <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Criar conta"/> </notification> <notification name="LoginPacketNeverReceived"> Estamos detectando um problema de conexão. Pode haver um problema com a sua conexão à internet ou com o [SECOND_LIFE_GRID]. @@ -1682,83 +1731,128 @@ Isto mudará milhares de regiões e fará o spaceserver soluçar. <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Mudar"/> </notification> <notification name="RegionEntryAccessBlocked"> - Você não é permitido na Região devido à sua Classificação de maturidade. Isto pode ser o resultado da falta de informação de validação de sua idade. - -Por favor, verifique se você está com o último Visualizador instalado e vá ao Banco de Conhecimento para detalhes em como acessar áreas com esta classificação de maturidade. + A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Você não é permitido nesta região devido à sua Classificação de maturidade. - -Ir para o Banco de Conhecimento para maiores informações sobre Classificações de maturidade? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Não posso entrar nessa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/> + <usetemplate ignoretext="Passagem de região: A região que você está tentando visitar tem conteúdo acessível apenas para adultos." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Você não é permitido nesta região devido à sua Classificação de maturidade. + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Você não pode entrar nessa região devido à sua seleção de maturidade. - -Para entrar na região desejada, mude o nível de maturidade. Você então poderá fazer buscas e acessar conteúdo [REGIONMATURITY]. Para desfazer qualquer mudança, vá para Eu > Preferências > Geral. + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências ou você pode cancelar. Após a alteração de suas preferências, você pode tentar acessar a região novamente. + <form name="form"> + <button name="OK" text="Mudar preferências"/> + <button default="true" name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Passagem de região: A região que você está tentando visitar tem conteúdo excluído por suas preferências."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Estamos tendo dificuldades técnicas com seu teletransporte, pois suas preferências estão dessincronizadas com o servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Teletransportar: A região que você está tentando visitar tem conteúdo acessível apenas para adultos." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e continuar o teletransporte, ou você pode cancelar este teletransporte. <form name="form"> - <button name="OK" text="Mudar preferência"/> - <button default="true" name="Cancel" text="Fechar"/> - <ignore name="ignore" text="Minha preferência de maturidade impede que eu vá a uma região"/> + <button name="OK" text="Alterar e continuar"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teletransportar (reinicializável): A região que você está tentando visitar tem conteúdo excluído por suas preferências."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências ou você pode cancelar o teletransporte. Após a alteração de suas preferências, você pode tentar se teletransportar novamente. + <form name="form"> + <button name="OK" text="Mudar preferências"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="Teletransportar (não reinicializável): A região que você está tentando visitar tem conteúdo excluído por suas preferências."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Estamos tendo dificuldades técnicas com seu teletransporte, pois suas preferências estão dessincronizadas com o servidor. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Sua opção de nível de maturidade é [RATING]. + Você não receberá mais notificações de que está prestes a visitar uma região com conteúdo [RATING]. Posteriormente você poderá alterar suas preferências de conteúdo acessando Eu > Preferências > Geral da barra do menu. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Impossível alterar suas preferências para visualizar conteúdo [PREFERRED_MATURITY] no momento. Suas preferências foram redefinidas para visualizar conteúdo [ACTUAL_MATURITY]. Você pode tentar alterar suas preferências novamente acessando Eu > Preferências > Geral na barra do menu. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Você não pode reclamar esta terra devido à sua Classificação de maturidade. Isto pode ser o resultado de falta de informação na validação de sua idade. - -Por favor, verifique se você tem o último Visualizador instalado e vá para o Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade. + O terreno que você está tentando reivindicar possui uma classificação de maturidade que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Você não pode reclamar esta terra devido à sua Classificação de maturidade. - -Ir para a o Banco de Conhecimento para maiores informações sobre Classificações de maturidade? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Apenas adultos podem reivindicar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Não reivindicar essa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/> + <usetemplate ignoretext="Apenas adultos podem reivindicar este terreno." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Você não pode reclamar esta terra devido à sua Classificação de maturidade. + O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], que é acessível apenas para adultos. </notification> <notification name="LandClaimAccessBlocked_Change"> - Você não pode reivindicar essa região devido à sua preferência de maturidade - -Clique em 'Mudar preferência' para aumentar o nível de maturidade e entrar nessa região. De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] . Para modificar esta configuração, vá à Eu > Preferências > Geral. - <usetemplate ignoretext="Minha preferência de conteúdo impede que eu reivindique terrenos" name="okcancelignore" notext="Fechar" yestext="Mudar Preferência"/> + O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e, então, você poderá tentar reivindicar a região novamente. + <form name="form"> + <button name="OK" text="Mudar preferências"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="O terreno que você está tentando reivindicar tem conteúdo excluído por suas preferências."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Você não pode comprar esta terra devido à sua Classificação de maturidade. Isto pode ser o resultado de falta de informação na validação de sua idade. - -Por favor, verifique se você tem o último Visualizador instalado e vá para o Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade. + O terreno que você está tentando comprar possui uma classificação de maturidade que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Você não pode comprar esta terra devido à sua Classificação de maturidade. - -Ir para o Banco de Conhecimento para maiores informações sobre Classificações de Maturidade? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Apenas adultos podem comprar este terreno. <url name="url"> - http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Não posso comprar essa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/> + <usetemplate ignoretext="Apenas adultos podem comprar este terreno." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Você não pode comprar esta terra devido à sua Classificação de maturidade. + O terreno que você está tentando comprar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + A região que você está tentando visitar tem conteúdo [REGIONMATURITY], que é acessível apenas para adultos. </notification> <notification name="LandBuyAccessBlocked_Change"> - Você não pode comprar esse terreno devido à sua preferência de maturidade - -Clique em 'Mudar preferência' para aumentar o nível de maturidade e entrar nessa região. De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] . Para modificar esta configuração, vá à Eu > Preferências > Geral. - <usetemplate ignoretext="Minha preferência de conteúdo não me deixa comprar terrenos" name="okcancelignore" notext="Fechar" yestext="Mudar Preferência"/> + O terreno que você está tentando comprar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e, então, você poderá tentar comprar a região novamente. + <form name="form"> + <button name="OK" text="Mudar preferências"/> + <button name="Cancel" text="Cancelar"/> + <ignore name="ignore" text="O terreno que você está tentando comprar tem conteúdo excluído por suas preferências."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Muitos prims foram selecionados. Selecione [MAX_PRIM_COUNT] ou menos prims, e tente de novo @@ -1813,10 +1907,9 @@ Publicar este classificado agora por L$ [AMOUNT]? </form> </notification> <notification label="Modificar a maturidade da Região" name="RegionMaturityChange"> - O conteúdo desta região foi reclassificado. -Talvez leve algum tempo para a mudança ser refletida no mapa. - -Para ir a regiões de conteúdo Adulto, é preciso ter uma conta verificada, seja comprovando a idade ou com dados de pagamento. + A classificação de maturidade desta região foi alterada. +Talvez leve algum tempo para que esta mudança seja refletida no mapa. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Discordância de Versão de Voz" name="VoiceVersionMismatch"> Esta versão do [APP_NAME] não é compatível com o recurso 'Bate-papo de voz' desta região. Para o bate-papo de voz funcionar, atualize o [APP_NAME]. @@ -2106,14 +2199,11 @@ Inclua um link para facilitar o acesso para visitantes. Teste o link na barra de <usetemplate ignoretext="Vestir as roupas que eu criar enquanto edito minha aparência" name="okcancelignore" notext="Não" yestext="Sim"/> </notification> <notification name="NotAgeVerified"> - Você deve ter no mínimo 18 anos para acessar conteúdo e áreas adultas no Second Life. Visite nossa página de verificação de idade para confirmar que você tem mais de 18 anos. -Isso abrirá o seu navegador. - -[_URL] - <url name="url" option="0"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Ainda não comprovei minha idade" name="okcancelignore" notext="Cancelar" yestext="Ir para verificação de idade"/> + O local que você está tentando visitar é restrito a residentes com 18 anos ou mais. + <usetemplate ignoretext="Não tenho idade suficiente para visitar áreas com restrição de idade." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Localização restrita para 18 anos de idade ou mais. </notification> <notification name="Cannot enter parcel: no payment info on file"> Área restrita a residentes que já cadastraram seus dados de pagamento Deseja ir ao site do [SECOND_LIFE] para cuidar disso? @@ -2371,6 +2461,23 @@ Logo, não é possível voar aqui. <notification name="NoBuild"> Esta área desativou a opção de construir. Não é possível construir ou fazer rez de objetos nesta área. </notification> + <notification name="PathfindingDirty"> + A região possui alterações de pathfinding pendentes. Se você possui direitos de construção, poderá recarregar a região clicando no botão “Recarregar região”. + </notification> + <notification name="DynamicPathfindingDisabled"> + O pathfinding dinâmico não está habilitado nesta região. Os objetos com script usando chamadas LSL de pathfinding podem não operar como o esperado na região. + </notification> + <notification name="PathfindingRebakeNavmesh"> + A alteração de determinados objetos nesta região pode resultar no comportamento incorreto de outros objeto em movimento. Para fazer com que os objetos em movimento se comportem corretamente, clique no botão “Recarregar região”. Escolha “Ajuda” para obter mais informações. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Ajuda" ignoretext="A alteração de determinados objetos nesta região pode resultar no comportamento incorreto de outros objeto em movimento." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Erro. Pode haver um erro de rede ou do servidor, ou você pode não ter direitos de construção. Às vezes, fazer login e logout novamente resolve este problema. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> Este terreno oculta os avatares e bate-papo de outro terreno. Não é possível ver residentes fora do terreno e vice-versa. O bate-papo por texto no canal 0 também está bloqueado. </notification> @@ -2389,9 +2496,7 @@ Os únicos scripts que funcionam são os do proprietário do terreno. Você só pode reivindicar terrenos públicos na região onde você está. </notification> <notification name="RegionTPAccessBlocked"> - Você não é permitido na Região devido à sua Classificação de maturidade. Você precisa validar sua idade e/ou instalar o último Visualizador. - -Por favor, vá ao Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade. + A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu > Preferências > Geral. </notification> <notification name="URBannedFromRegion"> Você está banido da região. @@ -2402,8 +2507,11 @@ Por favor, vá ao Banco de Conhecimento para detalhes sobre o acesso de áreas c <notification name="ImproperPaymentStatus"> Você não tem o status de pagamento adequado para entrar nesta região. </notification> + <notification name="MustGetAgeRegion"> + Você deve ter 18 anos ou mais para acessar esta região. + </notification> <notification name="MustGetAgeParcel"> - Você precisa ter a idade verificada para entrar neste lote. + Você deve ter 18 anos ou mais para acessar este lote. </notification> <notification name="NoDestRegion"> Nenhuma região de destino encontrada. @@ -2505,12 +2613,33 @@ Por favor, tente novamente em alguns instantes. <notification name="TeleportOffered"> [NAME_SLURL] quer teletransportar você para a região deles: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Teletransporte"/> <button name="Cancel" text="Cancelar"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] quer teletransportar você para a região deles: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +A região tem conteúdo [REGION_CONTENT_MATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGION_CONTENT_MATURITY]. Podemos alterar suas preferências e continuar o teletransporte, ou você pode cancelar este teletransporte. + <form name="form"> + <button name="Teleport" text="Alterar e continuar"/> + <button name="Cancel" text="Cancelar"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] quer teletransportar você para a região deles: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +No entanto, esta região tem conteúdo acessível apenas para adultos. + </notification> <notification name="TeleportOfferSent"> Oferta de teletransporte enviada para [TO_NAME] </notification> @@ -2908,6 +3037,10 @@ Você carregou uma textura com [RESOLUTION] para o(a) '[BODYREGION]' e ( [EXISTENCE] segundos de vida ) Você carregou uma textura com [RESOLUTION] para o(a) '[BODYREGION]' em [TIME] segundos. </notification> + <notification name="LivePreviewUnavailable"> + Não podemos exibir uma visualização desta textura, pois ela é cópia proibida e/ou transferência proibida. + <usetemplate ignoretext="Avise-me quando o modo Visualização em Tempo Real estiver indisponível para texturas de cópia proibida e/ou transferência proibida" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Tem certeza de que quer sair desta ligação? <usetemplate ignoretext="Confirmar antes de deixar ligação" name="okcancelignore" notext="Não" yestext="Sim"/> @@ -3077,6 +3210,62 @@ Se o botão Falar for ocultado, o recurso de voz será desabilitado. Essa ação irá ocultar todos os itens de menu e botões. Para trazê-los de volta, clique em [SHORTCUT] novamente. <usetemplate ignoretext="Confirmar antes de ocultar interface" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Deseja continuar? + <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos devido às restrições de permissão no linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. + +Deseja continuar? + <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outras não poderão ser definidas devido às restrições de permissão no linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outros não podem ser definidas, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. Estes tipos de uso de linksets não mudarão. + +Deseja continuar? + <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos devido às restrições de permissão no linkset e porque a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Alguns linksets selecionados terão suas sinalizações fantasmas alternadas. + +Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como '[REQUESTED_TYPE]' devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como '[RESTRICTED_TYPE]'. + +Alguns linksets selecionados não podem ser definidos como '[REQUESTED_TYPE]', pois a forma não é convexa. Estes tipos de uso de linksets não mudarão. + +Deseja continuar? + <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outras não poderão ser definidas, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + O objeto selecionado afeta o navmesh. Alterá-lo para um Caminho Flexível irá removê-lo do navmesh. + <usetemplate ignoretext="O objeto selecionado afeta o navmesh. Alterá-lo para um Caminho Flexível irá removê-lo do navmesh." name="okcancelignore" notext="Cancelar" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> Aparentemente a sua máquina não atende os requisitos de hardware do [APP_NAME]. [APP_NAME] requer placas de vídeo OpenGL com suporte a multitexturas. Se sua place de vídeo tiver este perfil, atualize o driver da placa de vídeo, assim como patches e service packs do sistema operacional. @@ -3113,4 +3302,12 @@ Desabilitando atualizações futuras deste arquivo. Tentativa de adição de um formato de imagem inválido ou ilegível [FNAME] que não pode ser aberto ou decodificado. Tentativa cancelada. </notification> + <notification name="PathfindingReturnMultipleItems"> + Você está devolvendo [NUM_ITEMS] itens. Tem certeza de que deseja continuar? + <usetemplate ignoretext="Tem certeza de que deseja devolver múltiplos itens?" name="okcancelignore" notext="Não" yestext="Sim"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Você está excluindo [NUM_ITEMS] itens. Tem certeza de que deseja continuar? + <usetemplate ignoretext="Tem certeza de que deseja excluir múltiplos itens?" name="okcancelignore" notext="Não" yestext="Sim"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml b/indra/newview/skins/default/xui/pt/panel_bottomtray.xml deleted file mode 100644 index cb517f643c..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Liga e desliga o microfone"/> - <string name="VoiceControlBtnToolTip" value="Mostra/oculta os controles de voz"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Falar" label_selected="Falar" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Gesto" name="Gesture" tool_tip="Mostra/oculta os gestos"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Movimentar" name="movement_btn" tool_tip="Mostra/oculta os controles de movimento"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Exibir" name="camera_btn" tool_tip="Mostra/oculta os controles da câmera"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button label="" name="snapshots" tool_tip="Tirar foto"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Construir" name="build_btn" tool_tip="Mostra/oculta ferramentas de Construção"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Busca" name="search_btn" tool_tip="Mostra/oculta os gestos"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Mapa" name="world_map_btn" tool_tip="Mostra/oculta o Mapa Múndi"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini Mapa" name="mini_map_btn" tool_tip="Mostra/oculta o Mini Mapa"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversas"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Notificações"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_group_invite.xml b/indra/newview/skins/default/xui/pt/panel_group_invite.xml index c7def0ed96..de057481de 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Alguns dos residentes selecionados já estão no grupo, portanto não receberam convite. </panel.string> + <panel.string name="invite_selection_too_large"> + Os convites para o grupo não foram enviados: muitos residentes selecionados. Os convites para o grupo são limitados a 100 por solicitação. + </panel.string> <text name="help_text" width="214"> Selecione um ou mais residentes para convidar. Clique em 'Abrir seletor de residentes' para começar. </text> diff --git a/indra/newview/skins/default/xui/pt/panel_login.xml b/indra/newview/skins/default/xui/pt/panel_login.xml index f4af6a7108..d7e9fa76ea 100644 --- a/indra/newview/skins/default/xui/pt/panel_login.xml +++ b/indra/newview/skins/default/xui/pt/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php?lang=pt </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + LOGIN + </text> <text name="username_text"> Nome de usuário: </text> @@ -15,33 +15,32 @@ <text name="password_text"> Senha: </text> - <check_box label="Lembrar senha" name="remember_check"/> - <button label="conectar" name="connect_btn"/> - <text name="mode_selection_text"> - Modo: - </text> - <combo_box name="mode_combo" tool_tip="Selecione o modo. O modo Básico é mais rápido e ideal para explorar e conversar. Use o modo Avançado para acessar mais recursos."> - <combo_box.item label="Básico" name="Basic"/> - <combo_box.item label="Avançado" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Começar em: </text> <combo_box name="start_location_combo"> <combo_box.item label="Última posição" name="MyLastLocation"/> - <combo_box.item label="Meu início" name="MyHome"/> + <combo_box.item label="Minha casa" name="MyHome"/> + <combo_box.item label="<Digite o nome da região>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Cadastre-se + <layout_panel name="links_login_panel"> + <text name="login_help"> + Precisa de ajuda com o login? </text> <text name="forgot_password_text"> Esqueceu seu nome ou senha? </text> - <text name="login_help"> - Precisa de ajuda ao conectar? + <button label="Login" name="connect_btn"/> + <check_box label="Lembrar senha" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + CRIE SUA CONTA </text> + <button label="Comece agora" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/pt/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..aa885ae031 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="Recarregar região" name="navmesh_btn" tool_tip="Clique para recarregar o navmesh da região."/> + <button label="Solicitando recarregamento" name="navmesh_btn_sending" tool_tip="Enviando solicitação de recarregamento para o servidor."/> + <button label="A região está recarregando" name="navmesh_btn_baking" tool_tip="A região está sendo recarregada. Este botão desaparecerá após a conclusão."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml index c5a4febb0e..350d53b81c 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="Bate-papos de MI" name="EnableIMChatPopups" tool_tip="Exibir pop-up de mensagens instantâneas novas"/> <spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_lifetime"/> <spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_fadingtime"/> - <button label="Configurações de tradução de bate-papo" name="ok_btn"/> + <button label="Tradução..." name="ok_btn"/> + <button label="Substituição automática..." name="autoreplace_showgui"/> + <button label="Verificando a ortografia..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_region_debug.xml b/indra/newview/skins/default/xui/pt/panel_region_debug.xml index f2cc9f644d..be15d40d74 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_debug.xml @@ -36,5 +36,5 @@ <button label="?" left="297" name="top_scripts_help"/> <button label="Reiniciar a região" name="restart_btn" tool_tip="Após 2 minutos de contagem regressiva, reiniciar a região"/> <button label="?" name="restart_help"/> - <button label="Adiar reinício" name="cancel_restart_btn" tool_tip="Adiar o reinício da região por uma hora"/> + <button label="Cancelar reinício" name="cancel_restart_btn" tool_tip="Cancelar reinício da região"/> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_region_estate.xml b/indra/newview/skins/default/xui/pt/panel_region_estate.xml index 6c5945aa15..b1453c9c32 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_estate.xml @@ -26,7 +26,7 @@ Permitir acesso apenas para residentes que: </text> <check_box label="Dados de pagamento constam no registro." name="limit_payment" tool_tip="Propriedade de acesso restrito a residentes que já cadastraram seus dados de pagamento Consulte o [SUPPORT_SITE] para saber mais."/> - <check_box label="A idade foi verificada" name="limit_age_verified" tool_tip="Residentes devem ter a idade verificada para acessar esta propriedade. Consulte o [SUPPORT_SITE] para saber mais."/> + <check_box label="Tem 18 anos ou mais" name="limit_age_verified" tool_tip="Os residentes devem ter 18 anos ou mais para acessar esta propriedade. Consulte o [SUPPORT_SITE] para obter mais informações."/> <check_box label="Permitir conversa de voz" name="voice_chat_check"/> <button label="?" name="voice_chat_help"/> <check_box label="Permitir Tele-transporte direto" name="allow_direct_teleport"/> diff --git a/indra/newview/skins/default/xui/pt/panel_region_texture.xml b/indra/newview/skins/default/xui/pt/panel_region_texture.xml deleted file mode 100644 index 35928ccc67..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_region_texture.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Texturas de Chão" name="Textures"> - <text name="region_text_lbl"> - Região: - </text> - <text name="region_text"> - desconhecido - </text> - <text name="detail_texture_text" width="380"> - Texturas de Terreno (requer 512x512, arquivos 24 bit .tga ) - </text> - <text name="height_text_lbl"> - 1 (baixo) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (alto) - </text> - <text name="height_text_lbl5"> - Escalas de Elevação de Terreno - </text> - <text name="height_text_lbl6"> - Noroeste - </text> - <text name="height_text_lbl7"> - Nordeste - </text> - <text name="height_text_lbl8"> - Sudoeste - </text> - <text name="height_text_lbl9"> - Sudeste - </text> - <spinner label="Baixo" name="height_start_spin_0"/> - <spinner label="Baixo" name="height_start_spin_1"/> - <spinner label="Baixo" name="height_start_spin_2"/> - <spinner label="Baixo" name="height_start_spin_3"/> - <spinner label="Alto" name="height_range_spin_0"/> - <spinner label="Alto" name="height_range_spin_1"/> - <spinner label="Alto" name="height_range_spin_2"/> - <spinner label="Alto" name="height_range_spin_3"/> - <text name="height_text_lbl10"> - Os valores representam o intervalo de mistura das texturas acima. - </text> - <text name="height_text_lbl11"> - Em metros, o valor BAIXO é a altura MÁXIMA da Textura 1, e HIGH é a altura MÍNIMA da Textura 4. - </text> - <text name="height_text_lbl12"> - e o valor Alto é a altura Mínima da Textura #4. - </text> - <button label="Aplicar" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_side_tray.xml b/indra/newview/skins/default/xui/pt/panel_side_tray.xml deleted file mode 100644 index 1a424fb7f1..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Exibir ou não barra lateral" name="sidebar_openclose" tab_title="Exibir ou não barra lateral"/> - <sidetray_tab description="Início" name="sidebar_home" tab_title="Início"> - <panel label="Início" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Edite seu perfil público e destaques." name="sidebar_me" tab_title="Meu perfil"> - <panel_container name="panel_container"> - <panel label="Eu" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encontre seus amigos, contatos e pessoas nas proximidades." name="sidebar_people" tab_title="Pessoas"> - <panel_container name="panel_container"> - <panel label="Perfil do grupo" name="panel_group_info_sidetray"/> - <panel label="Residentes& Objetos bloqueados" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Encontre lugares para ir e lugares que você ja visitou." label="Lugares" name="sidebar_places" tab_title="Lugares"> - <panel label="Lugares" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Abra seu inventário." name="sidebar_inventory" tab_title="Meu inventário"> - <panel label="Editar inventário" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Muda sua aparência e seu visual atual." name="sidebar_appearance" tab_title="Minha aparência"> - <panel label="Editar aparência" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml new file mode 100644 index 0000000000..1dfd2a69ca --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="Master" name="System Volume"/> + <slider label="Botões" name="UI Volume"/> + <slider label="Ambiente" name="Wind Volume"/> + <slider label="Sons" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Ativar sons dos gestos"/> + <slider label="Música" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Ativar streaming de música"/> + <slider label="Mídia" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Ativar mídia em stream"/> + <slider label="Voz" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Ativar bate-papo de voz"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml index e6370ea830..d3cb087108 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (desconhecido) </panel.string> + <panel.string name="unknown_multiple"> + (desconhecido / múltiplo) + </panel.string> <panel.string name="public"> (público) </panel.string> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml index 8092e6c145..3cfe0fe4f4 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Você não pode modificar estes objetos </panel.string> + <panel.string name="text modify info 5"> + Não é possível modificar este objeto através de uma demarcação da região + </panel.string> + <panel.string name="text modify info 6"> + Não é possível modificar estes objetos através de uma demarcação da região + </panel.string> <panel.string name="text modify warning"> O objeto contém links ligando suas partes </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Preço: L$" name="Edit Cost"/> <check_box label="Mostrar nos resultados de busca" name="search_check" tool_tip="Incluir o objeto nos resultados de busca"/> + <text name="pathfinding_attributes_label"> + Atributos do pathfinding: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index fd8f22f331..bc72b86020 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -128,7 +128,7 @@ Sair </string> <string name="create_account_url"> - http://join.secondlife.com/index.php?lang=pt-BR + http://join.secondlife.com/index.php?lang=pt-BR&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> O visualizador utilizado já não é compatível com o Second Life. Visite a página abaixo para baixar uma versão atual: http://secondlife.com/download @@ -952,6 +952,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="script_files"> Scripts </string> + <string name="dictionary_files"> + Dicionários + </string> <string name="AvatarSetNotAway"> deixar como ausente </string> @@ -1351,6 +1354,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="InvFolder favorite"> Meus favoritos </string> + <string name="InvFolder Favorites"> + Meus favoritos + </string> + <string name="InvFolder favorites"> + Meus favoritos + </string> <string name="InvFolder Current Outfit"> Look atual </string> @@ -1366,6 +1375,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para <string name="InvFolder Meshes"> Meshes: </string> + <string name="InvFolder Received Items"> + Itens recebidos + </string> + <string name="InvFolder Merchant Outbox"> + Caixa de saída do lojista + </string> <string name="InvFolder Friends"> Amigos </string> @@ -3740,6 +3755,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="LocationCtrlSeeAVsTooltip"> Avatar visíveis e bate-papo permitido fora deste terreno </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Os objetos que se movem podem não se comportar corretamente nesta região até que ela seja recarregada. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + O pathfinding dinâmico não está habilitado nesta região. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] Atualização </string> @@ -4873,6 +4894,21 @@ Tente colocar o caminho do editor entre aspas. <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Nenhum + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Afeta o navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personagem + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Múltiplo) + </string> <string name="snapshot_quality_very_low"> Muito baixo </string> @@ -4888,4 +4924,10 @@ Tente colocar o caminho do editor entre aspas. <string name="snapshot_quality_very_high"> Muito alto </string> + <string name="TeleportMaturityExceeded"> + O residente não pode visitar a região. + </string> + <string name="UserDictionary"> + [Usuário] + </string> </strings> diff --git a/indra/newview/skins/default/xui/pt/teleport_strings.xml b/indra/newview/skins/default/xui/pt/teleport_strings.xml index 3fb77a02d2..40fb4caebf 100644 --- a/indra/newview/skins/default/xui/pt/teleport_strings.xml +++ b/indra/newview/skins/default/xui/pt/teleport_strings.xml @@ -43,6 +43,9 @@ Vá para a 'Ilha Welcome Pública' para repetir o tutorial. <message name="no_inventory_host"> O sistema de inventário está indisponível no momento. </message> + <message name="MustGetAgeRegion"> + Você deve ter 18 anos ou mais para acessar esta região. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -78,5 +81,8 @@ Vá para a 'Ilha Welcome Pública' para repetir o tutorial. <message name="requesting"> Solicitando teletransporte... </message> + <message name="pending"> + Teletransporte pendente... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml index 119f104906..bb6266ac9a 100644 --- a/indra/newview/skins/default/xui/ru/floater_about.xml +++ b/indra/newview/skins/default/xui/ru/floater_about.xml @@ -62,27 +62,26 @@ </panel> <panel label="Лицензии" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK (C) 1992-2007 3Dconnexion - APR (C) 2000-2004 The Apache Software Foundation - Collada DOM (C) 2005 Sony Computer Entertainment Inc. - cURL (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) + 3Dconnexion SDK (C) 1992-2009 3Dconnexion + APR (C) 2011 The Apache Software Foundation + Collada DOM (C) 2006 Sony Computer Entertainment Inc. + cURL (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib (C) 2002, 2003 CodeFactory AB / (C) 2003, 2004 Red Hat, Inc. expat (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. - FreeType (C) 1996-2002, The FreeType Project (www.freetype.org). + FreeType (C) 1996-2002, 2006 David Turner, Robert Wilhelm и Werner Lemberg. GL (C) 1999-2004 Brian Paul. GLOD (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Университет Джона Гопкинса и David Luebke, Brenden Schubert, Университет Вирджинии. google-perftools (c) 2005, Google Inc. Havok.com(TM) (C) 1999-2001, Telekinesys Research Limited. jpeg2000 (C) 2001, David Taubman, Университет Нового Южного Уэльса (UNSW) jpeglib (C) 1991-1998, Thomas G. Lane. - ogg/vorbis (C) 2001, Xiphophorus - OpenSSL (C) 1998-2002 The OpenSSL Project. - PCRE (c) 1997-2008, Кембриджский университет + ogg/vorbis (C) 2002, Xiphophorus + OpenSSL (C) 1998-2008 The OpenSSL Project. + PCRE (c) 1997-2012, Кембриджский университет SDL (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi (C) 2000 Epinions, Inc. - zlib (C) 1995-2002 Jean-loup Gailly и Mark Adler. - google-perftools (c) 2005, Google Inc. + zlib (C) 1995-2012 Jean-loup Gailly и Mark Adler. В клиенте Second Life используется технология Havok (TM) Physics. (C) 1999-2010 Havok.com Inc. (и лицензиары компании). Все права защищены. Подробнее см. веб-сайт www.havok.com. diff --git a/indra/newview/skins/default/xui/ru/floater_about_land.xml b/indra/newview/skins/default/xui/ru/floater_about_land.xml index ee74aad5cc..12691df684 100644 --- a/indra/newview/skins/default/xui/ru/floater_about_land.xml +++ b/indra/newview/skins/default/xui/ru/floater_about_land.xml @@ -451,7 +451,7 @@ Разрешить доступ только таким жителям: </text> <check_box label="Зарегистрирована информация об оплате [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Для доступа к этому участку у жителя должна быть зарегистрирована информация об оплате. Более подробная информация находится здесь: [SUPPORT_SITE]."/> - <check_box label="Подтвержден возраст [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Для доступа к этому участку житель должен подтвердить свой возраст. Более подробная информация находится здесь: [SUPPORT_SITE]."/> + <check_box label="18 лет и старше [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Доступ к этому участку имеют только жители 18 лет и старше. Более подробная информация находится здесь: [SUPPORT_SITE]."/> <check_box label="Разрешить доступ группе: [GROUP]" name="GroupCheck" tool_tip="Группа устанавливается на основной вкладке."/> <check_box label="Продать доступ:" name="PassCheck" tool_tip="Разрешить временный доступ к участку."/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/ru/floater_animation_preview.xml b/indra/newview/skins/default/xui/ru/floater_animation_preview.xml deleted file mode 100644 index b7075fbf97..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_animation_preview.xml +++ /dev/null @@ -1,183 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview"> - <floater.string name="failed_to_initialize"> - Невозможно инициализировать движение - </floater.string> - <floater.string name="anim_too_long"> - Длина файла анимации: [LENGTH] с. -Максимальная длина анимации: [MAX_LENGTH] с. - </floater.string> - <floater.string name="failed_file_read"> - Невозможно прочитать файл анимации. -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - ОК - </floater.string> - <floater.string name="E_ST_EOF"> - Преждевременный конец файла. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Не могу прочитать определение ограничений. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - Не удалось открыть BVH-файл. - </floater.string> - <floater.string name="E_ST_NO_HIER"> - Неправильный заголовок HIERARCHY. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - Не удалось найти ROOT или JOINT. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - Не удалось получить имя JOINT. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - Не удалось найти OFFSET. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - Не удалось найти CHANNELS. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Не удалось получить порядок вращения. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Не удалось получить оси вращения. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - Не удалось найти MOTION. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - Не удалось получить количество кадров. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Не удалось получить время кадра. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Не удалось получить значения position. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Не удалось получить значения rotation. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Не удалось открыть файл перевода. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Не удалось прочитать заголовок перевода. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Не удалось прочитать имена перевода. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Не удалось прочитать значение перевода ignore. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Не удалось прочитать значение перевода relative. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Не удалось прочитать значение перевода outname. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Не удалось прочитать матрицу перевода. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Не удалось получить имя mergechild. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Не удалось получить имя mergeparent. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Не удалось получить значение priority. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Не удалось получить значение loop. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Не удалось получить значения easeIn. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - Не удалось получить значения easeOut. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Не удалось получить значение hand morph. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Не удалось прочитать имя emote. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Неверное имя корневого соединения, должно быть «hip». - </floater.string> - <text name="name_label"> - Название: - </text> - <text name="description_label"> - Описание: - </text> - <spinner label="Приоритет" name="priority" tool_tip="Управляет тем, как другие анимации могут перекрываться этой"/> - <check_box label="Цикл" name="loop_check" tool_tip="Делает анимацию зацикленной"/> - <spinner label="Начало(%)" name="loop_in_point" tool_tip="Устанавливает точку возврата цикла"/> - <spinner label="Конец(%)" name="loop_out_point" tool_tip="Устанавливает точку конца цикла"/> - <text name="hand_label"> - Положение пальцев - </text> - <combo_box name="hand_pose_combo" tool_tip="Контролирует положение пальцев во время анимации"> - <combo_box.item label="Разведены" name="Spread"/> - <combo_box.item label="Расслаблены" name="Relaxed"/> - <combo_box.item label="Указывают" name="PointBoth"/> - <combo_box.item label="Сжаты в кулаки" name="Fist"/> - <combo_box.item label="Левые расслаблены" name="RelaxedLeft"/> - <combo_box.item label="Левые указывают" name="PointLeft"/> - <combo_box.item label="Левые в кулак" name="FistLeft"/> - <combo_box.item label="Правые расслаблены" name="RelaxedRight"/> - <combo_box.item label="Правые указывают" name="PointRight"/> - <combo_box.item label="Правые в кулак" name="FistRight"/> - <combo_box.item label="Правые в приветствии" name="SaluteRight"/> - <combo_box.item label="Печатают" name="Typing"/> - <combo_box.item label="Правые «V»" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Выражение лица - </text> - <combo_box name="emote_combo" tool_tip="Контролирует выражение лица во время анимации"> - <item label="(нет)" name="[None]" value=""/> - <item label="Ааааах" name="Aaaaah" value="Ааааах"/> - <item label="Боится" name="Afraid" value="Боится"/> - <item label="Злится" name="Angry" value="Злится"/> - <item label="Широко улыбается" name="BigSmile" value="Широко улыбается"/> - <item label="Скучает" name="Bored" value="Скучает"/> - <item label="Плачет" name="Cry" value="Плачет"/> - <item label="Презирает" name="Disdain" value="Презирает"/> - <item label="Смущается" name="Embarrassed" value="Смущается"/> - <item label="Хмурится" name="Frown" value="Хмурится"/> - <item label="Целует" name="Kiss" value="Целует"/> - <item label="Смеется" name="Laugh" value="Смеется"/> - <item label="Дразнится" name="Plllppt" value="Дразнится"/> - <item label="Не соглашается" name="Repulsed" value="Не соглашается"/> - <item label="Грустит" name="Sad" value="Грустит"/> - <item label="Не понимает" name="Shrug" value="Не понимает"/> - <item label="Улыбается" name="Smile" value="Улыбается"/> - <item label="Удивляется" name="Surprise" value="Удивляется"/> - <item label="Подмигивает" name="Wink" value="Подмигивает"/> - <item label="Беспокоится" name="Worry" value="Беспокоится"/> - </combo_box> - <text name="preview_label"> - Просмотр во время - </text> - <combo_box name="preview_base_anim" tool_tip="Просмотр вашей анимации во время выполнения аватаром действий."> - <item label="Стояние" name="Standing" value="Стояние"/> - <item label="Ходьба" name="Walking" value="Ходьба"/> - <item label="Сидение" name="Sitting" value="Сидение"/> - <item label="Полет" name="Flying" value="Полет"/> - </combo_box> - <spinner label="Вход (сек.)" name="ease_in_time" tool_tip="Количество времени (в секундах) для входа в стартовое положение"/> - <spinner label="Выход (сек.)" name="ease_out_time" tool_tip="Количество времени (в секундах) для выхода из анимации"/> - <button name="play_btn" tool_tip="Проиграть анимацию"/> - <button name="pause_btn" tool_tip="Приостановить анимацию"/> - <button name="stop_btn" tool_tip="Остановить проигрывание анимации"/> - <text name="bad_animation_text"> - Невозможно прочитать файл анимации. -Рекомендуется использовать BVH-файлы, экспортированные из Poser 4. - </text> - <button label="Передать (L$[AMOUNT])" name="ok_btn"/> - <button label="Отмена" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_autoreplace.xml b/indra/newview/skins/default/xui/ru/floater_autoreplace.xml new file mode 100644 index 0000000000..6827931e5d --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Настройки автозамены"> + <check_box label="Включить автозамену" name="autoreplace_enable" tool_tip="В чате по мере ввода текста ключевые слова будут заменяться соответствующими заменителями"/> + <button label="Импорт списка..." name="autoreplace_import_list" tool_tip="Загрузить ранее экспортированный список из файла."/> + <button label="Экспорт списка..." name="autoreplace_export_list" tool_tip="Сохранить выбранный список в файл для последующего распространения."/> + <button label="Новый список..." name="autoreplace_new_list" tool_tip="Создать новый список."/> + <button label="Удалить список" name="autoreplace_delete_list" tool_tip="Удалить выбранный список."/> + <button name="autoreplace_list_up" tool_tip="Повысить приоритет списка."/> + <button name="autoreplace_list_down" tool_tip="Понизить приоритет списка."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Ключевое слово" name="keyword"/> + <scroll_list.columns label="Замена" name="replacement"/> + </scroll_list> + <button label="Добавить..." name="autoreplace_add_entry"/> + <button label="Удалить" name="autoreplace_delete_entry"/> + <button label="Сохранить запись" name="autoreplace_save_entry" tool_tip="Сохранить эту запись."/> + <button label="Сохранить изменения" name="autoreplace_save_changes" tool_tip="Сохранить все изменения."/> + <button label="Отмена" name="autoreplace_cancel" tool_tip="Отменить все изменения."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/ru/floater_env_settings.xml b/indra/newview/skins/default/xui/ru/floater_env_settings.xml deleted file mode 100644 index a3e77d61de..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_env_settings.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Environment Editor Floater" title="РЕДАКТОР СРЕДЫ"> - <floater.string name="timeStr"> - [hour,datetime,utc]:[min,datetime,utc] - </floater.string> - <text name="EnvTimeText"> - Время суток - </text> - <text name="EnvTimeText2"> - 12:00 - </text> - <text name="EnvCloudText"> - Облачность - </text> - <text name="EnvWaterColorText"> - Цвет воды - </text> - <color_swatch name="EnvWaterColor" tool_tip="Щелкните для выбора цвета"/> - <text name="EnvWaterFogText"> - Водный туман - </text> - <button label="Использовать время в землевладении" name="EnvUseEstateTimeButton"/> - <button label="Улучшенное небо" name="EnvAdvancedSkyButton"/> - <button label="Улучшенная вода" name="EnvAdvancedWaterButton"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_inventory.xml b/indra/newview/skins/default/xui/ru/floater_inventory.xml deleted file mode 100644 index 35cbcf177d..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_inventory.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="МОЙ ИНВЕНТАРЬ"> - <panel label="Панель инвентаря" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_model_preview.xml b/indra/newview/skins/default/xui/ru/floater_model_preview.xml index 5bb96b8de4..0c6d41b4ef 100644 --- a/indra/newview/skins/default/xui/ru/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/ru/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="Треугольники" name="triangles" value="Треугольники"/> <text initial_value="Вершины" name="vertices" value="Вершины"/> <text initial_value="Высокий" name="high_label" value="Высокий"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + </combo_box> <button label="Обзор..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Предельное число треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Средний" name="medium_label" value="Средний"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + <item name="Use LoD above" value="Использовать УД выше"/> + </combo_box> <button label="Обзор..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Предельное число треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Низкий" name="low_label" value="Низкий"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + <item name="Use LoD above" value="Использовать УД выше"/> + </combo_box> <button label="Обзор..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Предельное число треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="Самый низкий" name="lowest_label" value="Самый низкий"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Загрузка из файла"/> + <item name="Generate" value="Создать"/> + <item name="Use LoD above" value="Использовать УД выше"/> + </combo_box> <button label="Обзор..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Предельное число треугольников"/> + <item name="Error Threshold" value="Порог ошибки"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Генерировать нормали" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml b/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml deleted file mode 100644 index 184c753e40..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="ЛОКАЛЬНЫЙ ЧАТ"> - <check_box label="Перевод чата" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..ce7ffc3d20 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Персонажи с поиском пути"> + <floater.string name="messaging_get_inprogress"> + Опрос персонажей с поиском пути... + </floater.string> + <floater.string name="messaging_get_error"> + Ошибка при опросе персонажей с поиском пути. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Нет персонажей с поиском пути. + </floater.string> + <floater.string name="messaging_complete_available"> + Выбрано персонажей: [NUM_SELECTED] из [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + В этом регионе не разрешен поиск пути. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] мкс + </floater.string> + <floater.string name="character_owner_loading"> + [Загрузка] + </floater.string> + <floater.string name="character_owner_unknown"> + [Неизвестно] + </floater.string> + <floater.string name="character_owner_group"> + [группа] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Имя" name="name"/> + <scroll_list.columns label="Описание" name="description"/> + <scroll_list.columns label="Владелец" name="owner"/> + <scroll_list.columns label="ЦП" name="cpu_time"/> + <scroll_list.columns label="Высота" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Персонажи: + </text> + <button label="Обновить список" name="refresh_objects_list"/> + <button label="Выбрать все" name="select_all_objects"/> + <button label="Отменить выбор" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Действия с выбранными персонажами: + </text> + <check_box label="Показать метку" name="show_beacon"/> + <check_box label="Показать физическую капсулу" name="show_physics_capsule"/> + <button label="Взять" name="take_objects"/> + <button label="Сделать копию" name="take_copy_objects"/> + <button label="Телепортировать меня туда" name="teleport_me_to_object" tool_tip="Разрешено, только если выбран один персонаж."/> + <button label="Возврат" name="return_objects"/> + <button label="Удалить" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml new file mode 100644 index 0000000000..fa72df04fd --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Просмотр/тестирование поиска пути"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Не удалось найти реализацию библиотеки поиска пути + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + В этом регионе не разрешен поиск пути. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Ожидание окончания загрузки региона. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Проверка состояния навигационной сетки. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Загрузка навигационной сетки. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + На сервере изменилась навигационная сетка. Загрузка новой навигационной сетки. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + Загружена последняя навигационная сетка. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Не удалось загрузить навигационную сетку. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + В навигационной сетке есть незавершенные изменения. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Идет построение навигационной сетки. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + В некоторых регионах навигационной сетки есть незавершенные изменения. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Идет построение регионов навигационной сетки. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + В некоторых регионах навигационной сетки есть незавершенные изменения, идет построение других регионов. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Навигационная сетка уже обновлена. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Не удалось найти реализацию библиотеки поиска пути + </floater.string> + <floater.string name="pathing_region_not_enabled"> + В этом регионе не разрешен поиск пути. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Выберите начальную и конечную точки. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Выберите начальную точку. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Выберите конечную точку. + </floater.string> + <floater.string name="pathing_path_valid"> + Путь показан оранжевым цветом. + </floater.string> + <floater.string name="pathing_path_invalid"> + Не удалось найти путь между выбранными точками. + </floater.string> + <floater.string name="pathing_error"> + Ошибка при создании пути. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Вид" name="view_panel"> + <text name="show_label"> + Показать: + </text> + <check_box label="Мир" name="show_world"/> + <check_box label="Только перемещаемые предметы" name="show_world_movables_only"/> + <check_box label="Навигационная сетка" name="show_navmesh"/> + <text name="show_walkability_label"> + Показать карту проходимости: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Не показывать" name="show_heatmap_mode_none"/> + <combo_box.item label="Тип персонажа A" name="show_heatmap_mode_a"/> + <combo_box.item label="Тип персонажа B" name="show_heatmap_mode_b"/> + <combo_box.item label="Тип персонажа C" name="show_heatmap_mode_c"/> + <combo_box.item label="Тип персонажа D" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Проходимые места" name="show_walkables"/> + <check_box label="Материальные объемы" name="show_material_volumes"/> + <check_box label="Статичные препятствия" name="show_static_obstacles"/> + <check_box label="Исключающие объемы" name="show_exclusion_volumes"/> + <check_box label="Водное зеркало" name="show_water_plane"/> + <check_box label="Рентгеновское зрение" name="show_xray"/> + </panel> + <panel label="Проверить путь" name="test_panel"> + <text name="ctrl_click_label"> + Ctrl-щелчок для выбора начальной точки. + </text> + <text name="shift_click_label"> + Shift-щелчок для выбора конечной точки. + </text> + <text name="character_width_label"> + Ширина персонажа + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + м + </text> + <text name="character_type_label"> + Тип персонажа + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Нет" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Удалить путь" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..db100fa415 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Наборы связей для поиска пути"> + <floater.string name="messaging_get_inprogress"> + Запрос наборов связей для поиска пути... + </floater.string> + <floater.string name="messaging_get_error"> + Ошибка при запросе наборов связей для поиска пути. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Изменение выбранных наборов связей для поиска пути... + </floater.string> + <floater.string name="messaging_set_error"> + Ошибка при изменении выбранных наборов связей для поиска пути. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Нет наборов связей для поиска пути. + </floater.string> + <floater.string name="messaging_complete_available"> + Выбрано наборов связей: [NUM_SELECTED] из [NUM_TOTAL]. + </floater.string> + <floater.string name="messaging_not_enabled"> + В этом регионе не разрешен поиск пути. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Ландшафт] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Загрузка] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Неизвестно] + </floater.string> + <floater.string name="linkset_owner_group"> + [группа] + </floater.string> + <floater.string name="linkset_is_scripted"> + Да + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Нет + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Неизвестно + </floater.string> + <floater.string name="linkset_use_walkable"> + Проходимое место + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Статичное препятствие + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Перемещаемое препятствие + </floater.string> + <floater.string name="linkset_use_material_volume"> + Материальный объем + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Исключающий объем + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Перемещаемый фантом + </floater.string> + <floater.string name="linkset_is_terrain"> + [неизменяемый] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [ограниченный] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [вогнутый] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [ограниченный,вогнутый] + </floater.string> + <floater.string name="linkset_choose_use"> + Выберите степень использования наборов связей... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Фильтр по степени использования наборов связей..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Проходимое место" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Статичное препятствие" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Перемещаемое препятствие" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Материальный объем" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Исключающий объем" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Перемещаемый фантом" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Применить" name="apply_filters"/> + <button label="Чисто" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Имя (корневой примитив)" name="name"/> + <scroll_list.columns label="Описание (корневой примитив)" name="description"/> + <scroll_list.columns label="Владелец" name="owner"/> + <scroll_list.columns label="Скриптовые" name="scripted"/> + <scroll_list.columns label="Воздействие" name="land_impact"/> + <scroll_list.columns label="Расстояние" name="dist_from_you"/> + <scroll_list.columns label="Использование набора связей" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Наборы связей: + </text> + <button label="Обновить список" name="refresh_objects_list"/> + <button label="Выбрать все" name="select_all_objects"/> + <button label="Отменить выбор" name="select_none_objects"/> + </panel> + <panel> + <check_box label="Показать метку" name="show_beacon"/> + <button label="Взять" name="take_objects"/> + <button label="Сделать копию" name="take_copy_objects"/> + <button label="Телепортировать меня туда" name="teleport_me_to_object"/> + <button label="Возврат" name="return_objects"/> + <button label="Удалить" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Проходимость: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="Проходимость для персонажей типа A. Пример персонажа – гуманоид."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="Проходимость для персонажей типа B. Пример персонажа – существо."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="Проходимость для персонажей типа C. Пример персонажа – механизм."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="Проходимость для персонажей типа D. Пример персонажа – иное."/> + <button label="Применить изменения" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Гуманоид) + </text> + <text name="suggested_use_b_label"> + (Существо) + </text> + <text name="suggested_use_c_label"> + (Механизм) + </text> + <text name="suggested_use_d_label"> + (Иное) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_postcard.xml b/indra/newview/skins/default/xui/ru/floater_postcard.xml deleted file mode 100644 index 889d219511..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_postcard.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ПОСЛАТЬ СНИМОК ПО EMAIL"> - <floater.string name="default_subject"> - Открытка из [SECOND_LIFE]. - </floater.string> - <floater.string name="default_message"> - Побывай здесь! - </floater.string> - <floater.string name="upload_message"> - Отправка... - </floater.string> - <text name="to_label"> - Email получателя: - </text> - <text name="from_label"> - Ваш Email: - </text> - <text name="name_label"> - Ваше имя: - </text> - <text name="subject_label"> - Тема: - </text> - <line_editor label="Введите тему письма." name="subject_form"/> - <text name="msg_label"> - Сообщение: - </text> - <text_editor name="msg_form"> - Введите текст письма. - </text_editor> - <button label="Отмена" name="cancel_btn"/> - <button label="Отправить" name="send_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_spellcheck.xml b/indra/newview/skins/default/xui/ru/floater_spellcheck.xml new file mode 100644 index 0000000000..691b4a89c3 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Настройки проверки правописания"> + <check_box label="Включить проверку правописания" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Основной словарь: + </text> + <text label="Журналы:" name="spellcheck_additional"> + Дополнительные словари: + </text> + <text name="spellcheck_available"> + Доступно + </text> + <text name="spellcheck_active"> + Активно + </text> + <button label="Удалить" name="spellcheck_remove_btn"/> + <button label="Импорт..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml new file mode 100644 index 0000000000..a01866db73 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Импорт словаря"> + <button label="Обзор" label_selected="Обзор" name="dictionary_path_browse"/> + <button label="Импорт" name="ok_btn"/> + <button label="Отмена" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_stats.xml b/indra/newview/skins/default/xui/ru/floater_stats.xml index 2243c0f385..46426495dc 100644 --- a/indra/newview/skins/default/xui/ru/floater_stats.xml +++ b/indra/newview/skins/default/xui/ru/floater_stats.xml @@ -53,7 +53,13 @@ <stat_bar label="Объекты" name="simobjects"/> <stat_bar label="Активные объекты" name="simactiveobjects"/> <stat_bar label="Активные скрипты" name="simactivescripts"/> + <stat_bar label="Запущенные скрипты" name="simpctscriptsrun"/> <stat_bar label="События скрипта" name="simscripteps"/> + <stat_view label="Поиск пути" name="simpathfinding"> + <stat_bar label="Время шага ИИ" name="simsimaistepmsec"/> + <stat_bar label="Пропущенные силуэтные шаги" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Обновленные персонажи" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="Входящие пакеты" name="siminpps"/> <stat_bar label="Исходящие пакеты" name="simoutpps"/> <stat_bar label="Отложенные загрузки" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml index f8693b8359..db37089aeb 100644 --- a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml @@ -19,6 +19,8 @@ <button label="По умолчанию" label_selected="По умолчанию" name="Default"/> <button label="Очистить" label_selected="Очистить" name="Blank"/> <button label="Нет" label_selected="Нет" name="None"/> + <check_box initial_value="истина" label="Просмотр вживую" name="apply_immediate_check"/> + <text name="preview_disabled" value="Просмотр отключен"/> <filter_editor label="Фильтровать текстуры" name="inventory search editor"/> <check_box initial_value="ложь" label="Показывать папки" name="show_folders_check"/> <button label="Добавить" label_selected="Добавить" name="l_add_btn"/> @@ -30,5 +32,4 @@ </scroll_list> <button label="ОК" label_selected="ОК" name="Select"/> <button label="Отмена" label_selected="Отмена" name="Cancel"/> - <check_box initial_value="истина" label="Применить сейчас" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml index 034106f24c..628e6c5c87 100644 --- a/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, Повторное извлечение из кэша, время: [TIME] с, извлечено: [SIZE] КБ, [PIXEL] Мпикселов </text> + <text name="total_time_refetch_all_cache_label"> + 16, Повторное извлечение всех текстур из кэша, время: [TIME] с, извлечено: [SIZE] КБ, [PIXEL] Мпикселов + </text> <text name="total_time_refetch_vis_http_label"> - 16, Повторное извлечение из HTTP, время: [TIME] с, извлечено: [SIZE] КБ, [PIXEL] Мпикселов + 17, Повторное извлечение из HTTP, время: [TIME] с, извлечено: [SIZE] КБ, [PIXEL] Мпикселов + </text> + <text name="total_time_refetch_all_http_label"> + 18, Повторное извлечение всех текстур из HTTP, время: [TIME] с, извлечено: [SIZE] КБ, [PIXEL] Мпикселов + </text> + <spinner label="19, Отношение текселы/пикселы:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Истояник текстур: </text> - <spinner label="17, Отношение текселы/пикселы" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="Кэш + HTTP" name="0"/> + <radio_item label="Только HTTP" name="1"/> + </radio_group> <button label="Пуск" name="start_btn"/> <button label="Сброс" name="clear_btn"/> <button label="Закрыть" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="Декодировать" name="decode_btn"/> <button label="Текстура GL" name="gl_btn"/> <button label="Повторно извлечь из кэша" name="refetchviscache_btn"/> + <button label="Повторно извлечь все из кэша" name="refetchallcache_btn"/> <button label="Повторно извлечь из HTTP" name="refetchvishttp_btn"/> + <button label="Повторно извлечь все из HTTP" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/ru/floater_tools.xml b/indra/newview/skins/default/xui/ru/floater_tools.xml index 3d7d1198f0..c312f73428 100644 --- a/indra/newview/skins/default/xui/ru/floater_tools.xml +++ b/indra/newview/skins/default/xui/ru/floater_tools.xml @@ -150,6 +150,12 @@ <panel.string name="text modify info 4"> Эти объекты нельзя изменять </panel.string> + <panel.string name="text modify info 5"> + Этот объект нельзя изменять через границу региона + </panel.string> + <panel.string name="text modify info 6"> + Эти объекты нельзя изменять через границу региона + </panel.string> <panel.string name="text modify warning"> Чтобы задать права доступа, нужно выделить объект целиком </panel.string> @@ -199,12 +205,12 @@ <combo_box.item label="Увеличение" name="Zoom"/> </combo_box> <check_box label="Для продажи:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Копировать" name="Copy"/> <combo_box.item label="Контент" name="Contents"/> <combo_box.item label="Оригинал" name="Original"/> </combo_box> - <spinner label="Цена: L$" name="Edit Cost"/> <check_box label="Показать в поиске" name="search_check" tool_tip="Показывать объект в результатах поиска"/> <panel name="perms_build"> <text name="perm_modify"> @@ -240,6 +246,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Атрибуты поиска пути: + </text> + </panel> </panel> <panel label="Объект" name="Object"> <check_box label="Фиксированный" name="checkbox locked" tool_tip="Предотвращение перемещения или удаления объекта. Обычно эта функция полезна во время стройки для избежания нежелательных изменений."/> diff --git a/indra/newview/skins/default/xui/ru/floater_top_objects.xml b/indra/newview/skins/default/xui/ru/floater_top_objects.xml index a6ffe5c030..c7ece5c9c9 100644 --- a/indra/newview/skins/default/xui/ru/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/ru/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Время </floater.string> - <floater.string name="scripts_mono_time_label"> - Время моно - </floater.string> <floater.string name="top_colliders_title"> Лучшие столкновения </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Название" name="name"/> <scroll_list.columns label="Владелец" name="owner"/> <scroll_list.columns label="Место" name="location"/> + <scroll_list.columns label="Участок" name="parcel"/> <scroll_list.columns label="Время" name="time"/> - <scroll_list.columns label="Время моно" name="mono_time"/> <scroll_list.columns label="URL-адреса" name="URLs"/> + <scroll_list.columns label="Память (КБ)" name="memory"/> </scroll_list> <text name="id_text"> ID объекта: @@ -48,6 +46,10 @@ Владелец: </text> <button label="Фильтр" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Участок: + </text> + <button label="Фильтр" name="filter_parcel_btn"/> <button label="Вернуть выбранное" name="return_selected_btn"/> <button label="Вернуть все" name="return_all_btn"/> <button label="Отключить выбранное" name="disable_selected_btn"/> diff --git a/indra/newview/skins/default/xui/ru/floater_water.xml b/indra/newview/skins/default/xui/ru/floater_water.xml deleted file mode 100644 index 5030351f5b..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_water.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Water Floater" title="РАСШИРЕННЫЙ РЕДАКТОР ВОДЫ"> - <floater.string name="WLDefaultWaterNames"> - По умолчанию:глянец:пруд:туман:Second Plague:SNAKE!!!:Valdez - </floater.string> - <text name="KeyFramePresetsText"> - Настройки воды: - </text> - <button label="Создать" label_selected="Создать" name="WaterNewPreset"/> - <button label="Сохранить" label_selected="Сохранить" name="WaterSavePreset"/> - <button label="Удалить" label_selected="Удалить" name="WaterDeletePreset"/> - <tab_container name="Water Tabs"> - <panel label="НАСТРОЙКИ" name="Settings"> - <text name="BHText"> - Цвет водного тумана - </text> - <color_swatch name="WaterFogColor" tool_tip="Щелкните для выбора цвета"/> - <text name="WaterFogDensText"> - Плотность тумана - </text> - <text name="WaterUnderWaterFogModText"> - Подводный туман - </text> - <text name="BDensText"> - Уровень отражения волн - </text> - <slider label="1" name="WaterNormalScaleX"/> - <slider label="2" name="WaterNormalScaleY"/> - <slider label="3" name="WaterNormalScaleZ"/> - <text name="HDText"> - Масштаб Френеля - </text> - <text name="FresnelOffsetText"> - Сдвиг Френеля - </text> - <text name="DensMultText"> - Преломление над водой - </text> - <text name="WaterScaleBelowText"> - Преломление под водой - </text> - <text name="MaxAltText"> - Коэффициент размытия - </text> - </panel> - <panel label="ИЗОБРАЖЕНИЕ" name="Waves"> - <text name="BHText"> - Направление больших волн - </text> - <text name="WaterWave1DirXText"> - X - </text> - <text name="WaterWave1DirYText"> - Y - </text> - <text name="BHText2"> - Направление маленьких волн - </text> - <text name="WaterWave2DirXText"> - X - </text> - <text name="WaterWave2DirYText"> - Y - </text> - <text name="BHText3"> - Карта поверхности - </text> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_windlight_options.xml b/indra/newview/skins/default/xui/ru/floater_windlight_options.xml deleted file mode 100644 index bbb37aaaa0..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_windlight_options.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="WindLight floater" title="РАСШИРЕННЫЙ РЕДАКТОР НЕБА"> - <floater.string name="WLDefaultSkyNames"> - A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality - </floater.string> - <text name="KeyFramePresetsText"> - Настройки неба: - </text> - <button label="Новая" label_selected="Новая" name="WLNewPreset"/> - <button label="Сохранить" label_selected="Сохранить" name="WLSavePreset"/> - <button label="Удалить" label_selected="Удалить" name="WLDeletePreset"/> - <button label="Редактор суточных циклов" label_selected="Редактор суточных циклов" name="WLDayCycleMenuButton"/> - <tab_container name="WindLight Tabs"> - <panel label="АТМОСФЕРА" name="Atmosphere"> - <text name="BHText"> - Голубой горизонт - </text> - <text name="BHText2"> - R - </text> - <text name="BHText3"> - G - </text> - <text name="BHText4"> - B - </text> - <text name="BHText5"> - I - </text> - <text name="BDensText"> - Дымка на горизонте - </text> - <text name="BDensText2"> - Насыщенность голубого - </text> - <text name="BHText6"> - R - </text> - <text name="BHText7"> - G - </text> - <text name="BHText8"> - B - </text> - <text name="BHText9"> - I - </text> - <text name="HDText"> - Плотность дымки - </text> - <text name="DensMultText"> - Коэффициент плотности - </text> - <text name="WLDistanceMultText"> - Коэффициент расстояния - </text> - <text name="MaxAltText"> - Максимальная высота - </text> - </panel> - <panel label="ОСВЕЩЕНИЕ" name="Lighting"> - <text name="SLCText"> - Цвет солнца/луны - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="TODText"> - Положение солнца/луны - </text> - <text name="WLAmbientText"> - Рассеянное - </text> - <text name="BHText5"> - R - </text> - <text name="BHText6"> - G - </text> - <text name="BHText7"> - B - </text> - <text name="BHText8"> - I - </text> - <text name="WLEastAngleText"> - Смещение относительно востока - </text> - <text name="SunGlowText"> - Сияние солнца - </text> - <slider label="Фокус" name="WLGlowB"/> - <slider label="Размер" name="WLGlowR"/> - <text name="SceneGammaText"> - Гамма-коррекция сцены - </text> - <text name="WLStarText"> - Яркость звезд - </text> - </panel> - <panel label="ОБЛАКА" name="Clouds"> - <text name="WLCloudColorText"> - Цвет - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="WLCloudColorText2"> - Положение и плотность - </text> - <text name="BHText5"> - X - </text> - <text name="BHText6"> - Y - </text> - <text name="BHText7"> - П - </text> - <text name="WLCloudCoverageText"> - Облачность - </text> - <text name="WLCloudScaleText"> - Размеры - </text> - <text name="WLCloudDetailText"> - Детализация (положение/плотность) - </text> - <text name="BHText8"> - X - </text> - <text name="BHText9"> - Y - </text> - <text name="BHText10"> - П - </text> - <text name="WLCloudScrollXText"> - Скорость по X - </text> - <check_box label="На месте" name="WLCloudLockX"/> - <text name="WLCloudScrollYText"> - Скорость по Y - </text> - <check_box label="На месте" name="WLCloudLockY"/> - <check_box label="Создать классические облака" name="DrawClassicClouds"/> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/ru/menu_bottomtray.xml b/indra/newview/skins/default/xui/ru/menu_bottomtray.xml deleted file mode 100644 index fa3558945b..0000000000 --- a/indra/newview/skins/default/xui/ru/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Кнопка разговора" name="EnableVoiceChat"/> - <menu_item_check label="Кнопка жестов" name="ShowGestureButton"/> - <menu_item_check label="Кнопка движения" name="ShowMoveButton"/> - <menu_item_check label="Кнопка камеры" name="ShowCameraButton"/> - <menu_item_check label="Кнопка снимка" name="ShowSnapshotButton"/> - <menu_item_check label="Кнопка строительства" name="ShowBuildButton"/> - <menu_item_check label="Кнопка поиска" name="ShowSearchButton"/> - <menu_item_check label="Кнопка карты" name="ShowWorldMapButton"/> - <menu_item_check label="Кнопка миникарты" name="ShowMiniMapButton"/> - <menu_item_call label="Вырезать" name="NearbyChatBar_Cut"/> - <menu_item_call label="Копировать" name="NearbyChatBar_Copy"/> - <menu_item_call label="Вставить" name="NearbyChatBar_Paste"/> - <menu_item_call label="Удалить" name="NearbyChatBar_Delete"/> - <menu_item_call label="Выделить все" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/ru/menu_inventory.xml b/indra/newview/skins/default/xui/ru/menu_inventory.xml index 49f7281b4e..37ee19fc1d 100644 --- a/indra/newview/skins/default/xui/ru/menu_inventory.xml +++ b/indra/newview/skins/default/xui/ru/menu_inventory.xml @@ -68,6 +68,7 @@ <menu_item_call label="Удалить системную папку" name="Delete System Folder"/> <menu_item_call label="Начать конференцию" name="Conference Chat Folder"/> <menu_item_call label="Воспроизвести" name="Sound Play"/> + <menu_item_call label="Копировать URL SL" name="url_copy"/> <menu_item_call label="О закладке" name="About Landmark"/> <menu_item_call label="Проиграть для всех" name="Animation Play"/> <menu_item_call label="Проиграть для себя" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/ru/menu_mode_change.xml b/indra/newview/skins/default/xui/ru/menu_mode_change.xml deleted file mode 100644 index 25d6e9af27..0000000000 --- a/indra/newview/skins/default/xui/ru/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Основной" name="BasicMode"/> - <menu_item_check label="Расширенный" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/ru/menu_object.xml b/indra/newview/skins/default/xui/ru/menu_object.xml index d6abfd12a2..288df3beb9 100644 --- a/indra/newview/skins/default/xui/ru/menu_object.xml +++ b/indra/newview/skins/default/xui/ru/menu_object.xml @@ -3,6 +3,8 @@ <menu_item_call label="Коснуться" name="Object Touch"/> <menu_item_call label="Изменить" name="Edit..."/> <menu_item_call label="Строительство" name="Build"/> + <menu_item_call label="Показывать в наборах связей" name="show_in_linksets"/> + <menu_item_call label="Показывать в персонажах" name="show_in_characters"/> <menu_item_call label="Открыто" name="Open"/> <menu_item_call label="Сесть здесь" name="Object Sit"/> <menu_item_call label="Встать" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/ru/menu_text_editor.xml b/indra/newview/skins/default/xui/ru/menu_text_editor.xml index 113dd85318..0c928308a1 100644 --- a/indra/newview/skins/default/xui/ru/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/ru/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(неизвестно)" name="Suggestion 1"/> + <menu_item_call label="(неизвестно)" name="Suggestion 2"/> + <menu_item_call label="(неизвестно)" name="Suggestion 3"/> + <menu_item_call label="(неизвестно)" name="Suggestion 4"/> + <menu_item_call label="(неизвестно)" name="Suggestion 5"/> + <menu_item_call label="Добавить в словарь" name="Add to Dictionary"/> + <menu_item_call label="Добавить в список игнорируемых" name="Add to Ignore"/> <menu_item_call label="Вырезать" name="Cut"/> <menu_item_call label="Копировать" name="Copy"/> <menu_item_call label="Вставить" name="Paste"/> diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index 701f097ddb..d9425937c3 100644 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -26,6 +26,7 @@ <menu_item_call label="Настройки..." name="Preferences"/> <menu_item_call label="Кнопки панели инструментов..." name="Toolbars"/> <menu_item_call label="Скрыть все элементы управления" name="Hide UI"/> + <menu_item_check label="Показывать присоединения HUD" name="Show HUD Attachments"/> <menu_item_call label="Выход из [APP_NAME]" name="Quit"/> </menu> <menu label="Общение" name="Communicate"> @@ -37,6 +38,7 @@ <menu_item_call label="Друзья" name="My Friends"/> <menu_item_call label="Группы" name="My Groups"/> <menu_item_call label="Люди неподалеку" name="Active Speakers"/> + <menu_item_call label="Черный список" name="Block List"/> </menu> <menu label="Мир" name="World"> <menu_item_call label="Добавить закладку на это место" name="Create Landmark Here"/> @@ -122,6 +124,11 @@ <menu_item_call label="Запустить скрипты" name="Set Scripts to Running"/> <menu_item_call label="Остановить скрипты" name="Set Scripts to Not Running"/> </menu> + <menu label="Поиск пути" name="Pathfinding"> + <menu_item_call label="Наборы связей..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Персонажи..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Просмотр/тестирование..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Параметры" name="Options"> <menu_item_check label="Показать расширенные разрешения" name="DebugPermissions"/> <menu_item_check label="Выбирать только мои объекты" name="Select Only My Objects"/> @@ -172,7 +179,6 @@ <menu_item_check label="Скрыть частицы" name="Hide Particles"/> <menu_item_check label="Скрыть выбранное" name="Hide Selected"/> <menu_item_check label="Подсветка прозрачного" name="Highlight Transparent"/> - <menu_item_check label="Показывать присоединения HUD" name="Show HUD Attachments"/> <menu_item_check label="Показывать прицел при обзоре мышью" name="ShowCrosshairs"/> </menu> <menu label="Типы визуализации" name="Rendering Types"> @@ -375,7 +381,6 @@ <menu_item_call label="Активировать геометрию персонажа" name="Toggle Character Geometry"/> <menu_item_call label="Проверка мужчины" name="Test Male"/> <menu_item_call label="Проверка женщины" name="Test Female"/> - <menu_item_call label="Активировать PG-контент" name="Toggle PG"/> <menu_item_check label="Разрешить выбор аватара" name="Allow Select Avatar"/> </menu> <menu_item_call label="Скинуть параметры" name="Force Params to Default"/> diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index 97e5ee8c65..85b7074253 100644 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -360,13 +366,19 @@ Для входа в [SECOND_LIFE] нужен аккаунт. Создать его? <url name="url"> - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Повторить попытку" yestext="Создать новый аккаунт"/> </notification> <notification name="InvalidCredentialFormat"> Введите имя пользователя или имя и фамилию вашего аватара в поле «Имя пользователя», затем снова войдите в программу. </notification> + <notification name="InvalidGrid"> + «[GRID]» – недопустимый идентификатор сетки. + </notification> + <notification name="InvalidLocationSLURL"> + В месте старта не указана правильная сетка. + </notification> <notification name="DeleteClassified"> Удалить рекламу «[NAME]»? Плата за нее не будет возвращена. @@ -472,8 +484,8 @@ Ошибка при сохранении скомпилированного скрипта по следующей причине: [REASON]. Попробуйте сохранить скрипт через некоторое время. </notification> <notification name="StartRegionEmpty"> - Ай-яй-яй, ваш стартовый регион не определен. -Введите название региона в поле «Место старта» или выберите в качестве места старта «Мое последнее местоположение» или «Мой дом». + Ваш стартовый регион не определен. +Введите название региона в поле «Место старта» или выберите в качестве места старта «Мое последнее место» или «Мой дом». <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="CouldNotStartStopScript"> @@ -600,6 +612,9 @@ Убедитесь, что все объекты разблокированы и что вы владеете всеми ими. </notification> + <notification name="CannotLinkPermanent"> + Объекты нельзя связывать через границу региона. + </notification> <notification name="CannotLinkDifferentOwners"> Невозможно объединить объекты: не у всех объектов один владелец. @@ -978,6 +993,41 @@ <button name="Cancel" text="Отмена"/> </form> </notification> + <notification label="Добавить список автозамены" name="AddAutoReplaceList"> + Имя нового списка: + <form name="form"> + <button name="SetName" text="OK"/> + </form> + </notification> + <notification label="Переименовать список автозамены" name="RenameAutoReplaceList"> + Имя «[DUPNAME]» уже занято. + Введите новое уникальное имя: + <form name="form"> + <button name="ReplaceList" text="Заменить текущий список"/> + <button name="SetName" text="Использовать новое имя"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Ключевое слово должно быть одним словом, а поле замены не может быть пустым. + </notification> + <notification name="InvalidAutoReplaceList"> + Недопустимый список замены. + </notification> + <notification name="SpellingDictImportRequired"> + Следует указать файл, имя и язык. + </notification> + <notification name="SpellingDictIsSecondary"> + Словарь [DIC_NAME] не является aff-файлом, т. е. это «вспомогательный» словарь. +Он может использоваться как дополнительный, но не как основной словарь. + +См. https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Невозможно скопировать + [FROM_NAME] + в + [TO_NAME] + </notification> <notification label="Сохранить костюм" name="SaveOutfitAs"> Сохранить текущую одежду как новый костюм: <form name="form"> @@ -1157,7 +1207,7 @@ Вы перемещены в соседний регион. </notification> <notification name="AvatarMovedLast"> - Ваше последнее местоположение сейчас недоступно. + Требуемое вами местоположение сейчас недоступно. Вы перемещены в соседний регион. </notification> <notification name="AvatarMovedHome"> @@ -1176,7 +1226,6 @@ Установка [APP_NAME] завершена. Если вы используете [SECOND_LIFE] впервые, для входа в программу вам потребуется создать аккаунт. -Вернуться на [http://join.secondlife.com secondlife.com] для создания аккаунта? <usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Создать аккаунт..."/> </notification> <notification name="LoginPacketNeverReceived"> @@ -1694,83 +1743,128 @@ http://secondlife.com/download. <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/> </notification> <notification name="RegionEntryAccessBlocked"> - Вам нельзя быть в этом регионе из-за вашего рейтинга зрелости. Возможно, это результат недостатка информации, подтверждающей ваш возраст. - -Убедитесь, что у вас установлена последняя версия клиента, и прочитайте в Базе знаний о доступе к областям с этим рейтингом зрелости. + Вы пытаетесь посетить регион, контент в котором не соответствует вашим настройкам. Попробуйте изменить настройки в меню «Я > Настройки > Общие». <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Вам нельзя быть в этом регионе из-за вашего рейтинга зрелости. - -Перейти в Базу знаний и ознакомиться с рейтингами зрелости? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только для взрослых. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Я не могу войти в этот регион из-за ограничений по рейтингу зрелости" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + <usetemplate ignoretext="Пересечение региона: вы пытаетесь посетить регион, контент в котором предназначен только для взрослых." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Вам нельзя быть в этом регионе из-за вашего рейтинга зрелости. + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только для взрослых. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Вам нельзя быть в этом регионе из-за вашей настройки рейтинга зрелости. - -Для входа в желаемый регион измените настройку рейтинга зрелости. После этого вам будет разрешено искать и просматривать контент [REGIONMATURITY]. Для отмены изменений выберите команды «Я > Настройки > Общие». + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. Вы можете отказаться от посещения, или ваши настройки будут изменены. После изменения настроек вы можете попробовать войти в регион снова. <form name="form"> - <button name="OK" text="Изменить настройку"/> - <button name="Cancel" text="Закрыть"/> - <ignore name="ignore" text="Выбранная мной настройка рейтинга запрещает мне вход в регион"/> + <button name="OK" text="Изменить настройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Пересечение региона: вы пытаетесь посетить регион, контент в котором запрещен вашими настройками."/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + При телепортации возникли технические проблемы, так как ваши настройки не синхронизированы с сервером. + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Вы пытаетесь посетить регион, контент в котором не соответствует вашим настройкам. Попробуйте изменить настройки в меню «Я > Настройки > Общие». + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только для взрослых. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Телепортация: вы пытаетесь посетить регион, контент в котором предназначен только для взрослых." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только для взрослых. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. Вы можете отказаться от телепортации, или ваши настройки будут изменены. + <form name="form"> + <button name="OK" text="Изменить и продолжить"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Телепортация (возобновляемая): вы пытаетесь посетить регион, контент в котором запрещен вашими настройками."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + Вы пытаетесь посетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. Вы можете отказаться от телепортации, или ваши настройки будут изменены. После изменения настроек вы можете попробовать телепортироваться снова. + <form name="form"> + <button name="OK" text="Изменить настройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Телепортация (невозобновляемая): вы пытаетесь посетить регион, контент в котором запрещен вашими настройками."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + При телепортации возникли технические проблемы, так как ваши настройки не синхронизированы с сервером. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="PreferredMaturityChanged"> - Теперь ваша настройка рейтинга зрелости: [RATING]. + Вы больше не будете получать уведомлений о посещении региона с контентом рейтинга [RATING]. Настройки для контента можно изменить на будущее с помощью команд меню «Я > Настройки > Общие». + <usetemplate name="okbutton" yestext="OK"/> + </notification> + <notification name="MaturityChangeError"> + Не удалось изменить ваши настройки так, чтобы вы могли видеть контент с рейтингом [PREFERRED_MATURITY]. Ваши теперешние настройки разрешают просматривать контент [ACTUAL_MATURITY]. Попробуйте изменить настройки снова с помощью команд меню «Я > Настройки > Общие». + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="LandClaimAccessBlocked"> - Вы не можете претендовать на эту землю из-за вашего рейтинга зрелости. Возможно, это результат недостатка информации, подтверждающей ваш возраст. - -Убедитесь, что у вас установлена последняя версия клиента, и прочитайте в Базе знаний о доступе к областям с этим рейтингом зрелости. + Вы претендуете на землю, рейтинг зрелости контента на которой не соответствует вашим настройкам. Попробуйте изменить настройки в меню «Я > Настройки > Общие». <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Вы не можете претендовать на эту землю из-за вашего рейтинга зрелости. - -Перейти в Базу знаний и ознакомиться с рейтингами зрелости? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + На эту землю могут претендовать только взрослые. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Я не могу претендовать на эту землю из-за ограничений по рейтингу зрелости" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + <usetemplate ignoretext="На эту землю могут претендовать только взрослые." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Вы не можете претендовать на эту землю из-за вашего рейтинга зрелости. + Вы претендуете на землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Вы претендуете на землю с контентом [REGIONMATURITY], который предназначен только для взрослых. </notification> <notification name="LandClaimAccessBlocked_Change"> - Вы не можете претендовать на эту землю из-за вашей настройки рейтинга зрелости. - -Нажмите кнопку «Изменить настройку», чтобы повысить свой рейтинг зрелости. После этого вам будет разрешено искать и просматривать контент [REGIONMATURITY]. Если в будущем понадобится отменить это изменение, выберите команды «Я > Настройки > Общие». - <usetemplate ignoretext="Выбранная мной настройка рейтинга запрещает мне претендовать на землю" name="okcancelignore" notext="Закрыть" yestext="Изменить настройку"/> + Вы претендуете на землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. Мы можем изменить ваши настройки, после чего вы сможете претендовать на землю снова. + <form name="form"> + <button name="OK" text="Изменить настройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Вы претендуете на землю, контент на которой запрещен вашими настройками."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Вы не можете купить эту землю из-за вашего рейтинга зрелости. Возможно, это результат недостатка информации, подтверждающей ваш возраст. - -Убедитесь, что у вас установлена последняя версия клиента, и прочитайте в Базе знаний о доступе к областям с этим рейтингом зрелости. + Вы пытаетесь купить землю, рейтинг зрелости контента на которой не соответствует вашим настройкам. Попробуйте изменить настройки в меню «Я > Настройки > Общие». <usetemplate name="okbutton" yestext="OK"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Вы не можете купить эту землю из-за вашего рейтинга зрелости. - -Перейти в Базу знаний и ознакомиться с рейтингами зрелости? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Эту землю могут купить только взрослые. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Я не могу купить эту землю из-за ограничений по рейтингу зрелости" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> + <usetemplate ignoretext="Эту землю могут купить только взрослые." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Вы не можете купить эту землю из-за вашего рейтинга зрелости. + Вы пытаетесь купить землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Вы пытаетесь купить землю с контентом [REGIONMATURITY], который предназначен только для взрослых. </notification> <notification name="LandBuyAccessBlocked_Change"> - Вы не можете купить эту землю из-за выбранного вами рейтинга зрелости. - -Нажмите кнопку «Изменить настройку», чтобы повысить свой рейтинг зрелости. После этого вам будет разрешено искать и просматривать контент [REGIONMATURITY]. Если в будущем понадобится отменить это изменение, выберите команды «Я > Настройки > Общие». - <usetemplate ignoretext="Выбранная мной настройка рейтинга запрещает мне покупать землю" name="okcancelignore" notext="Закрыть" yestext="Изменить настройку"/> + Вы пытаетесь купить землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши настройки не допускают контента [REGIONMATURITY]. Мы можем изменить ваши настройки, после чего вы сможете попробовать купить землю снова. + <form name="form"> + <button name="OK" text="Изменить настройки"/> + <button name="Cancel" text="Отмена"/> + <ignore name="ignore" text="Вы пытаетесь купить землю, контент на которой запрещен вашими настройками."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Выбрано слишком много примитивов. Выберите [MAX_PRIM_COUNT] или меньше примитивов и повторите попытку. @@ -1824,10 +1918,9 @@ http://secondlife.com/download. </form> </notification> <notification label="Изменен рейтинг зрелости региона" name="RegionMaturityChange"> - Рейтинг зрелости для этого региона будет обновлен. + Рейтинг зрелости для этого региона был изменен. Отображение этого изменения на карте может занять некоторое время. - -Для входа в регионы для взрослых у жителя должен быть подтвержденный аккаунт: либо с подтверждением возраста, либо с подтверждением оплаты. + <usetemplate name="okbutton" yestext="OK"/> </notification> <notification label="Несоответствие версии голоса" name="VoiceVersionMismatch"> Данная версия [APP_NAME] несовместима с функцией голосового чата в этом регионе. Для правильной работы голосового чата необходимо обновить [APP_NAME]. @@ -2117,14 +2210,11 @@ http://secondlife.com/download. <usetemplate ignoretext="Надевать одежду, создаваемую при редактировании моей внешности" name="okcancelignore" notext="Нет" yestext="Да"/> </notification> <notification name="NotAgeVerified"> - Доступ к контенту и областям для взрослых в Second Life разрешен только с 18 лет. Посетите нашу страницу проверки возраста и подтвердите, что вам уже исполнилось 18. -Страница будет открыта в браузере. - -[_URL] - <url name="url"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Мой возраст не подтвержден" name="okcancelignore" notext="Отмена" yestext="Перейти к проверке возраста"/> + Вы пытаетесь посетить место, доступ в которое разрешен только жителям 18 лет и старше. + <usetemplate ignoretext="Мне еще рано посещать места с ограничениями по возрасту." name="okignore" yestext="OK"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Это место разрешено для жителей 18 лет и старше. </notification> <notification name="Cannot enter parcel: no payment info on file"> Для посещения этой области необходимо зарегистрировать платеж. Перейти на веб-сайт [SECOND_LIFE] и ввести эту информацию? @@ -2386,6 +2476,23 @@ http://secondlife.com/download. <notification name="NoBuild"> В этой области запрещено строительство. Здесь вы не сможете строить или выкладывать объекты. </notification> + <notification name="PathfindingDirty"> + В регионе есть незавершенные изменения поиска пути. Если у вас есть права на строительство, восстановите регион, нажав кнопку «Восстановить регион». + </notification> + <notification name="DynamicPathfindingDisabled"> + В этом регионе не разрешен динамический поиск пути. Возможны нарушения работы скриптовых объектов с использованием вызовов LSL поиска пути. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Изменение некоторых объектов в регионе может привести к неправильному поведению других подвижных объектов. Чтобы исправить их поведение, нажмите кнопку «Восстановить регион». Более подробная информация – по ссылке «Справка». + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Справка" ignoretext="Изменение некоторых объектов в регионе может привести к неправильному поведению других подвижных объектов." name="okhelpignore" yestext="OK"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Произошла ошибка. Возможно, неполадка в сети или на сервере, или у вас нет прав на строительство. Иногда для устранения этой проблемы достаточно выйти и снова войти. + <usetemplate name="okbutton" yestext="OK"/> + </notification> <notification name="SeeAvatars"> На этом участке аватары и текстовый чат скрыты от другого участка. Жителей за пределами этого участка не будет видно, а они не будут видеть вас. Обычный текстовый чат на канале 0 также блокируется. </notification> @@ -2404,9 +2511,7 @@ http://secondlife.com/download. Вы можете претендовать на публичную землю только в регионе, в котором вы находитесь. </notification> <notification name="RegionTPAccessBlocked"> - Вам нельзя быть в этом регионе из-за вашего рейтинга зрелости. Подтвердите свой возраст и/или установите последнюю версию клиента. - -Прочитайте в Базе знаний о доступе к областям с этим рейтингом зрелости. + Вы пытаетесь посетить регион, контент в котором не соответствует вашим настройкам. Попробуйте изменить настройки в меню «Я > Настройки > Общие». </notification> <notification name="URBannedFromRegion"> Вы забанены в регионе. @@ -2417,11 +2522,11 @@ http://secondlife.com/download. <notification name="ImproperPaymentStatus"> У вас нет необходимого статуса оплаты для входа в этот регион. </notification> - <notification name="MustGetAgeRgion"> - Для входа в этот регион необходимо подтверждение возраста. + <notification name="MustGetAgeRegion"> + Входить в этот регион могут только жители 18 лет и старше. </notification> <notification name="MustGetAgeParcel"> - Для входа на этот участок необходимо подтверждение возраста. + Входить на этот участок могут только жители 18 лет и старше. </notification> <notification name="NoDestRegion"> Не найден регион назначения. @@ -2523,12 +2628,33 @@ http://secondlife.com/download. <notification name="TeleportOffered"> [NAME_SLURL] предложил(а) телепортировать вас к себе: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +«[MESSAGE]» +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Телепортация"/> <button name="Cancel" text="Отмена"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] предложил(а) телепортировать вас к себе: + +«[MESSAGE]» +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Этот регион содержит контент с рейтингом [REGION_CONTENT_MATURITY], но ваши настройки не допускают контента [REGION_CONTENT_MATURITY]. Вы можете отказаться от телепортации, или ваши настройки будут изменены. + <form name="form"> + <button name="Teleport" text="Изменить и продолжить"/> + <button name="Cancel" text="Отмена"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] предложил(а) телепортировать вас к себе: + +«[MESSAGE]» +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Однако этот регион содержит контент, доступный только для взрослых. + </notification> <notification name="TeleportOfferSent"> Предложение телепортации отправлено [TO_NAME] </notification> @@ -2932,6 +3058,10 @@ http://secondlife.com/download. ( [EXISTENCE] сек. жизни ) Вы локально обновили готовую текстуру [RESOLUTION] для «[BODYREGION]» через [TIME] сек. </notification> + <notification name="LivePreviewUnavailable"> + Просмотр этой текстуры невозможен, так как запрещено ее копирование и/или перенос. + <usetemplate ignoretext="Предупреждать, если режим просмотра вживую недоступен для текстур с запрещенным копированием и/или переносом" name="okignore" yestext="OK"/> + </notification> <notification name="ConfirmLeaveCall"> Действительно покинуть этот разговор? <usetemplate ignoretext="Подтверждать перед выходом из разговора" name="okcancelignore" notext="Нет" yestext="Да"/> @@ -3103,6 +3233,62 @@ http://secondlife.com/download. Это действие приведет к скрытию всех меню и кнопок. Чтобы вернуть их, щелкните [SHORTCUT] снова. <usetemplate ignoretext="Подтверждать перед скрытием интерфейса" name="okcancelignore" notext="Отмена" yestext="OK"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Признак фантомности некоторых выбранных наборов связей будет изменен. + +Продолжить? + <usetemplate ignoretext="Признак фантомности некоторых выбранных наборов связей будет изменен." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Для некоторых выбранных наборов связей нельзя задать тип «[REQUESTED_TYPE]» из-за ограничений этих наборов. Эти наборы связей будут иметь тип «[RESTRICTED_TYPE]». + +Продолжить? + <usetemplate ignoretext="Нельзя задать некоторые выбранные наборы связей из-за ограничений этих наборов." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Для некоторых выбранных наборов связей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклая. + +Продолжить? + <usetemplate ignoretext="Нельзя задать некоторые выбранные наборы связей, так как фигура не выпуклая." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Признак фантомности некоторых выбранных наборов связей будет изменен. + +Для некоторых выбранных наборов связей нельзя задать тип «[REQUESTED_TYPE]» из-за ограничений этих наборов. Эти наборы связей будут иметь тип «[RESTRICTED_TYPE]». + +Продолжить? + <usetemplate ignoretext="Для некоторых выбранных наборов связей будет изменен признак фантомности, а другие наборы нельзя задать из-за ограничений этих наборов." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Признак фантомности некоторых выбранных наборов связей будет изменен. + +Для некоторых выбранных наборов связей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклая. + +Продолжить? + <usetemplate ignoretext="Для некоторых выбранных наборов связей будет изменен признак фантомности, а другие наборы нельзя задать, так как фигура не выпуклая." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Для некоторых выбранных наборов связей нельзя задать тип «[REQUESTED_TYPE]» из-за ограничений этих наборов. Эти наборы связей будут иметь тип «[RESTRICTED_TYPE]». + +Для некоторых выбранных наборов связей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклая. Тип использования этих наборов связей не изменится. + +Продолжить? + <usetemplate ignoretext="Нельзя задать некоторые выбранные наборы связей из-за ограничений этих наборов и потому, что фигура не выпуклая." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Признак фантомности некоторых выбранных наборов связей будет изменен. + +Для некоторых выбранных наборов связей нельзя задать тип «[REQUESTED_TYPE]» из-за ограничений этих наборов. Эти наборы связей будут иметь тип «[RESTRICTED_TYPE]». + +Для некоторых выбранных наборов связей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклая. Тип использования этих наборов связей не изменится. + +Продолжить? + <usetemplate ignoretext="Для некоторых выбранных наборов связей будет изменен признак фантомности, а другие наборы нельзя задать из-за ограничений этих наборов и потому, что фигура не выпуклая." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + Выбранный объект влияет на навигационную сетку. Если заменить его на гибкий путь, он будет удален из навигационной сетки. + <usetemplate ignoretext="Выбранный объект влияет на навигационную сетку. Если заменить его на гибкий путь, он будет удален из навигационной сетки." name="okcancelignore" notext="Отмена" yestext="OK"/> + </notification> <global name="UnsupportedGLRequirements"> По-видимому, ваше оборудование не удовлетворяет требованиям [APP_NAME]. Для работы [APP_NAME] необходима графическая карта OpenGL с поддержкой мультитекстур. Если у вас есть такая карта, убедитесь, что установлены новейшие версии драйверов для нее и пакеты обновлений и исправления для операционной системы. @@ -3139,4 +3325,12 @@ http://secondlife.com/download. Попытка добавить недопустимый или нечитаемый файл изображения [FNAME], который не удалось открыть или декодировать. Попытка отменена. </notification> + <notification name="PathfindingReturnMultipleItems"> + Возвращено [NUM_ITEMS] элементов. Продолжить? + <usetemplate ignoretext="Возвратить несколько предметов?" name="okcancelignore" notext="Нет" yestext="Да"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + Вы удаляете несколько предметов ([NUM_ITEMS]). Продолжить? + <usetemplate ignoretext="Удалить несколько предметов?" name="okcancelignore" notext="Нет" yestext="Да"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/ru/panel_bottomtray.xml b/indra/newview/skins/default/xui/ru/panel_bottomtray.xml deleted file mode 100644 index ebf6c4264b..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Включить/выключить микрофон"/> - <string name="VoiceControlBtnToolTip" value="Показать/скрыть панель управления голосом"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Говорить" label_selected="Говорить" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Жесты" name="Gesture" tool_tip="Показать/скрыть жесты"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Перемещение" name="movement_btn" tool_tip="Показать/скрыть панель управления движением"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Камера" name="camera_btn" tool_tip="Показать/скрыть управление камерой"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button name="snapshots" tool_tip="Сделать снимок"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="Строительство" name="build_btn" tool_tip="Показать/скрыть инструменты"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Поиск" name="search_btn" tool_tip="Показать/скрыть поиск"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Карта" name="world_map_btn" tool_tip="Показать/скрыть карту мира"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Миникарта" name="mini_map_btn" tool_tip="Показать/скрыть миникарту"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Общение"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Уведомления"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_group_invite.xml b/indra/newview/skins/default/xui/ru/panel_group_invite.xml index 3041046041..68dac5cd7e 100644 --- a/indra/newview/skins/default/xui/ru/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/ru/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Несколько выбранных жителей уже состоят в группе. Им приглашения не были отправлены. </panel.string> + <panel.string name="invite_selection_too_large"> + Групповые приглашения не отправлены: выбрано слишком много жителей. Групповые приглашения могут охватывать не более 100 пользователей за один запрос. + </panel.string> <text name="help_text"> Можно выбрать несколько жителей для приглашения в группу. Чтобы начать, щелкните «Выбрать жителей». </text> diff --git a/indra/newview/skins/default/xui/ru/panel_login.xml b/indra/newview/skins/default/xui/ru/panel_login.xml index 7928191fa6..f0877731c6 100644 --- a/indra/newview/skins/default/xui/ru/panel_login.xml +++ b/indra/newview/skins/default/xui/ru/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + ВОЙТИ + </text> <text name="username_text"> Имя пользователя: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Пароль: </text> - <check_box label="Запомнить пароль" name="remember_check"/> - <button label="Войти" name="connect_btn"/> - <text name="mode_selection_text"> - Режим: - </text> - <combo_box name="mode_combo" tool_tip="Выберите режим. Основной – для быстрого и простого ознакомления с игрой, а также общения. Расширенный – для доступа к более широким возможностям."> - <combo_box.item label="Основной" name="Basic"/> - <combo_box.item label="Расширенный" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Место старта: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Введите название региона>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Регистрация + <layout_panel name="links_login_panel"> + <text name="login_help"> + Нужна помощь при входе? </text> <text name="forgot_password_text"> Забыли имя или пароль? </text> - <text name="login_help"> - Нужна помощь при входе? + <button label="Войти" name="connect_btn"/> + <check_box label="Запомнить пароль" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + СОЗДАЙТЕ СВОЙ АККАУНТ </text> + <button label="Начать" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/ru/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..fdc374a024 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="Восстановить регион" name="navmesh_btn" tool_tip="Восстановить навигационную сетку региона."/> + <button label="Запрос на восстановление" name="navmesh_btn_sending" tool_tip="Отправка запроса на восстановление на сервер."/> + <button label="Идет восстановление региона" name="navmesh_btn_baking" tool_tip="Идет восстановление региона. Когда оно завершится, эта кнопка исчезнет."/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml index a9d5569c7f..9283fc9e6e 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="Текстовые чаты" name="EnableIMChatPopups" tool_tip="Отображать всплывающие уведомления при получении IM-сообщений"/> <spinner label="Время отображения всплывающих реплик:" name="nearby_toasts_lifetime"/> <spinner label="Время затухания всплывающих реплик:" name="nearby_toasts_fadingtime"/> - <button label="Настройки перевода чата" name="ok_btn"/> + <button label="Перевод..." name="ok_btn"/> + <button label="Автозамена..." name="autoreplace_showgui"/> + <button label="Проверка правописания..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_region_debug.xml b/indra/newview/skins/default/xui/ru/panel_region_debug.xml index c21d2d7051..4be1e781fa 100644 --- a/indra/newview/skins/default/xui/ru/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/ru/panel_region_debug.xml @@ -30,5 +30,5 @@ <button label="Самые активные участники столкновений..." name="top_colliders_btn" tool_tip="Список объектов, для которых столкновения наиболее вероятны"/> <button label="Список лучших скриптов..." name="top_scripts_btn" tool_tip="Объекты, в которых скрипты выполняются дольше всего"/> <button label="Перезагрузить регион" name="restart_btn" tool_tip="Отсчитать 2 минуты и перезагрузить регион"/> - <button label="Отложить перезагрузку" name="cancel_restart_btn" tool_tip="Отложить перезагрузку региона на час"/> + <button label="Отменить перезапуск" name="cancel_restart_btn" tool_tip="Отменить перезапуск региона"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_region_estate.xml b/indra/newview/skins/default/xui/ru/panel_region_estate.xml index 93b21704bc..bcfb974fcb 100644 --- a/indra/newview/skins/default/xui/ru/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/ru/panel_region_estate.xml @@ -23,7 +23,7 @@ Разрешить доступ только таким жителям: </text> <check_box label="Зарегистрирована информация об оплате" name="limit_payment" tool_tip="Для доступа к этому землевладению у жителя должна быть зарегистрирована информация об оплате. Более подробная информация находится здесь: [SUPPORT_SITE]."/> - <check_box label="Подтвержден возраст" name="limit_age_verified" tool_tip="Для доступа к этому землевладению житель должен подтвердить свой возраст. Более подробная информация находится здесь: [SUPPORT_SITE]."/> + <check_box label="18 лет и старше" name="limit_age_verified" tool_tip="Доступ к этому землевладению имеют только жители 18 лет и старше. Более подробная информация находится здесь: [SUPPORT_SITE]."/> <check_box label="Разрешить голосовое общение" name="voice_chat_check"/> <check_box label="Разрешить прямой телепорт" name="allow_direct_teleport"/> <button label="Применить" name="apply_btn"/> diff --git a/indra/newview/skins/default/xui/ru/panel_region_texture.xml b/indra/newview/skins/default/xui/ru/panel_region_texture.xml deleted file mode 100644 index c4b35a536d..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_region_texture.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Текстуры земли" name="Textures"> - <text name="region_text_lbl"> - Регион: - </text> - <text name="region_text"> - неизвестен - </text> - <text name="detail_texture_text"> - Текстуры ландшафта (требования: 512x512, 24-битные TGA-файлы) - </text> - <text name="height_text_lbl"> - 1 (низ) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (верх) - </text> - <text name="height_text_lbl5"> - Диапазон высот текстур - </text> - <text name="height_text_lbl6"> - Северо-запад - </text> - <text name="height_text_lbl7"> - Северо-восток - </text> - <spinner label="Низ" name="height_start_spin_1"/> - <spinner label="Низ" name="height_start_spin_3"/> - <spinner label="Верх" name="height_range_spin_1"/> - <spinner label="Верх" name="height_range_spin_3"/> - <text name="height_text_lbl8"> - Юго-запад - </text> - <text name="height_text_lbl9"> - Юго-восток - </text> - <spinner label="Низ" name="height_start_spin_0"/> - <spinner label="Низ" name="height_start_spin_2"/> - <spinner label="Верх" name="height_range_spin_0"/> - <spinner label="Верх" name="height_range_spin_2"/> - <text name="height_text_lbl10"> - Эти значения отображают диапазон перекрытия вышеуказанных текстур. - </text> - <text name="height_text_lbl11"> - Измеряется в метрах, значение «Низ» – это МАКСИМАЛЬНАЯ высота текстуры №1, значение «Верх» – это МИНИМАЛЬНАЯ высота текстуры №4. - </text> - <button label="Применить" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_side_tray.xml b/indra/newview/skins/default/xui/ru/panel_side_tray.xml deleted file mode 100644 index 10c5775291..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Открыть/закрыть боковую панель" name="sidebar_openclose" tab_title="Открыть/закрыть боковую панель"/> - <sidetray_tab description="Дом." name="sidebar_home" tab_title="Дом"> - <panel label="дом" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Изменение своего профиля и подборки." name="sidebar_me" tab_title="Мой профиль"> - <panel_container name="panel_container"> - <panel label="Я" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Поиск друзей, контактов и находящихся поблизости людей." name="sidebar_people" tab_title="Люди"> - <panel_container name="panel_container"> - <panel label="Профиль группы" name="panel_group_info_sidetray"/> - <panel label="Черный список жителей и объектов" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Поиск мест, которые можно было бы посетить или которые вы уже посещали ранее." label="Места" name="sidebar_places" tab_title="Места"> - <panel label="Места" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Просмотрите свой инвентарь." name="sidebar_inventory" tab_title="Мой инвентарь"> - <panel label="Изменить инвентарь" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Изменение внешнего вида и текущего образа." name="sidebar_appearance" tab_title="Мой внешний вид"> - <panel label="Изменить внешний вид" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml new file mode 100644 index 0000000000..fe044cd083 --- /dev/null +++ b/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="Общая" name="System Volume"/> + <slider label="Кнопки" name="UI Volume"/> + <slider label="Окружающая" name="Wind Volume"/> + <slider label="Звуки" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Включить звуки от жестов"/> + <slider label="Музыка" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Включить потоковую музыку"/> + <slider label="Медиа" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Включить потоковое медиа"/> + <slider label="Голос" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Включить голосовой чат"/> +</panel> diff --git a/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml index 62095acbaf..0106ed50ac 100644 --- a/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (неизвестно) </panel.string> + <panel.string name="unknown_multiple"> + (неизвестно/несколько) + </panel.string> <panel.string name="public"> (публичное) </panel.string> diff --git a/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml b/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml index 8e56dd80c0..e9dd3760b5 100644 --- a/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Эти объекты нельзя изменять </panel.string> + <panel.string name="text modify info 5"> + Этот объект нельзя изменять через границу региона + </panel.string> + <panel.string name="text modify info 6"> + Эти объекты нельзя изменять через границу региона + </panel.string> <panel.string name="text modify warning"> Этот объект содержит объединенные части </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Цена: L$" name="Edit Cost"/> <check_box label="Показать в результатах поиска" name="search_check" tool_tip="Показывать объект в результатах поиска"/> + <text name="pathfinding_attributes_label"> + Атрибуты поиска пути: + </text> <text name="B:"> Н: </text> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 6461e10e2d..f9ded799bf 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -137,7 +137,7 @@ Выйти </string> <string name="create_account_url"> - http://join.secondlife.com/ + http://join.secondlife.com/index.php?lang=ru-RU&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> У клиента, которым вы пользуетесь, больше нет доступа к игре Second Life. Загрузить новую версию клиента можно по адресу @@ -1003,6 +1003,9 @@ support@secondlife.com. <string name="script_files"> Скрипты </string> + <string name="dictionary_files"> + Словари + </string> <string name="AvatarSetNotAway"> На месте </string> @@ -1408,6 +1411,12 @@ support@secondlife.com. <string name="InvFolder favorite"> Мое избранное </string> + <string name="InvFolder Favorites"> + Мое избранное + </string> + <string name="InvFolder favorites"> + Мое избранное + </string> <string name="InvFolder Current Outfit"> Текущий костюм </string> @@ -1423,6 +1432,12 @@ support@secondlife.com. <string name="InvFolder Meshes"> Меши </string> + <string name="InvFolder Received Items"> + Полученные вещи + </string> + <string name="InvFolder Merchant Outbox"> + Торговые исходящие + </string> <string name="InvFolder Friends"> Друзья </string> @@ -3858,6 +3873,12 @@ support@secondlife.com. <string name="LocationCtrlSeeAVsTooltip"> Все жители с других участков могут видеть аватары и общаться в чате </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Возможны неполадки подвижных объектов в этом регионе, пока регион не будет восстановлен. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + В этом регионе не разрешен динамический поиск пути. + </string> <string name="UpdaterWindowTitle"> Обновление [APP_NAME] </string> @@ -5012,6 +5033,21 @@ support@secondlife.com. <string name="Normal"> Нормальный </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Нет + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Влияет на навигационную сетку + </string> + <string name="Pathfinding_Object_Attr_Character"> + Персонаж + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (несколько) + </string> <string name="snapshot_quality_very_low"> Очень низкий </string> @@ -5027,4 +5063,10 @@ support@secondlife.com. <string name="snapshot_quality_very_high"> Очень высокий </string> + <string name="TeleportMaturityExceeded"> + Житель не может посетить этот регион. + </string> + <string name="UserDictionary"> + [Пользователь] + </string> </strings> diff --git a/indra/newview/skins/default/xui/ru/teleport_strings.xml b/indra/newview/skins/default/xui/ru/teleport_strings.xml index feff286111..40c9267408 100644 --- a/indra/newview/skins/default/xui/ru/teleport_strings.xml +++ b/indra/newview/skins/default/xui/ru/teleport_strings.xml @@ -45,6 +45,9 @@ <message name="no_inventory_host"> Система инвентаря сейчас недоступна. </message> + <message name="MustGetAgeRegion"> + Входить в этот регион могут только жители 18 лет и старше. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ <message name="requesting"> Запрос телепортации… </message> + <message name="pending"> + Телепортация не закончена... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml index 8fa12ea759..9cc9c7a220 100644 --- a/indra/newview/skins/default/xui/tr/floater_about.xml +++ b/indra/newview/skins/default/xui/tr/floater_about.xml @@ -63,27 +63,26 @@ Ses Sunucusu Sürümü: [VOICE_VERSION] </panel> <panel label="Lisanslar" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Telif Hakkı (C) 1992-2007 3Dconnexion - APR Telif Hakkı (C) 2000-2004 The Apache Software Foundation - Collada DOM Telif Hakkı 2005 Sony Computer Entertainment Inc. - cURL Telif Hakkı (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) + 3Dconnexion SDK Telif Hakkı (C) 1992-2009 3Dconnexion + APR Telif Hakkı (C) 2011 The Apache Software Foundation + Collada DOM Telif Hakkı 2006 Sony Computer Entertainment Inc. + cURL Telif Hakkı (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Telif Hakkı (C) 2002, 2003 CodeFactory AB / Telif Hakkı (C) 2003, 2004 Red Hat, Inc. expat Telif Hakkı (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. - FreeType Telif Hakkı (C) 1996-2002, The FreeType Project (www.freetype.org). + FreeType Telif Hakkı (C) 1996-2002, 2006 David Turner, Robert Wilhelm ve Werner Lemberg. GL Telif Hakkı (C) 1999-2004 Brian Paul. GLOD Telif Hakkı (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University ve David Luebke, Brenden Schubert, University of Virginia. google-perftools Telif Hakkı (c) 2005, Google Inc. Havok.com(TM) Telif Hakkı (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Telif Hakkı (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Telif Hakkı (C) 1991-1998, Thomas G. Lane. - ogg/vorbis Telif Hakkı (C) 2001, Xiphophorus - OpenSSL Telif Hakkı (C) 1998-2002 The OpenSSL Project. - PCRE Telif Hakkı (c) 1997-2008 University of Cambridge + ogg/vorbis Telif Hakkı (C) 2002, Xiphophorus + OpenSSL Telif Hakkı (C) 1998-2008 The OpenSSL Project. + PCRE Telif Hakkı (c) 1997-2012 University of Cambridge SDL Telif Hakkı (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Telif Hakkı (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Telif Hakkı (C) 2000 Epinions, Inc. - zlib Telif Hakkı (C) 1995-2002 Jean-loup Gailly ve Mark Adler. - google-perftools Telif Hakkı (c) 2005, Google Inc. + zlib Telif Hakkı (C) 1995-2012 Jean-loup Gailly ve Mark Adler. Second Life Görüntüleyicisi Havok (TM) Fizik motorunu kullanmaktadır. (c)Telif Hakkı 1999-2010 Havok.com Inc. (ve Lisans Verenleri). Tüm Hakları Saklıdır. Ayrıntılı bilgi için bkz. www.havok.com diff --git a/indra/newview/skins/default/xui/tr/floater_about_land.xml b/indra/newview/skins/default/xui/tr/floater_about_land.xml index a478d347a8..481fc540d0 100644 --- a/indra/newview/skins/default/xui/tr/floater_about_land.xml +++ b/indra/newview/skins/default/xui/tr/floater_about_land.xml @@ -451,7 +451,7 @@ Sadece büyük parseller aramada görünür. Sadece şu Sakinlere erişim izni verin: </text> <check_box label="Ödeme bilgileri kayıtlı [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Sakinlerin bu parsele erişebilmesi için ödeme bilgilerinin kayıtlı olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> - <check_box label="Yaş doğrulaması yapılmış [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Sakinlerin bu parsele erişebilmesi için yaş doğrulamalarının yapılmış olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> + <check_box label="18 veya üzeri bir yaşta [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Sakinlerin bu parsele erişebilmesi için 18 veya üzeri bir yaşta olmaları gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> <check_box label="Grup Erişimine İzin Ver: [GROUP]" name="GroupCheck" tool_tip="Genel sekmesinde grup ayarla."/> <check_box label="Geçiş haklr. şuna sat:" name="PassCheck" tool_tip="Bu parsele geçici erişim verir"/> <combo_box name="pass_combo"> diff --git a/indra/newview/skins/default/xui/tr/floater_animation_preview.xml b/indra/newview/skins/default/xui/tr/floater_animation_preview.xml deleted file mode 100644 index f8800c674d..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_animation_preview.xml +++ /dev/null @@ -1,186 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview"> - <floater.string name="failed_to_initialize"> - Hareket başlatılamadı - </floater.string> - <floater.string name="anim_too_long"> - Animasyon dosyası [LENGTH] saniye uzunluğunda. - -Maksimum animasyon uzunluğu [LENGTH] saniye. - </floater.string> - <floater.string name="failed_file_read"> - Animasyon dosyası okunamadı. - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - Tamam - </floater.string> - <floater.string name="E_ST_EOF"> - Dosyanın zamanından önce sonu. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Kısıtlama tanımı okunamadı. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - BVH dosyası açılamadı. - </floater.string> - <floater.string name="E_ST_NO_HIER"> - Geçersiz HİYERARŞİ üst bilgisi. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - KÖK veya EKLEM bulunamadı. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - EKLEM adı alınamadı. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - OFSET bulunamadı. - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - KANALLAR bulunamadı. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Döndürme sırası alınamadı. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Döndürme ekseni alınamadı. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - HAREKET bulunamadı. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - kARE SAYISI alınamadı. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Kare zamanı alınamadı. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Konum değerleri alınamadı. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Döndürme değerleri alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Çeviri dosyası açılamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Çeviri üst bilgisi okunamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Çeviri adları okunamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Çeviri yoksay değeri okunamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Çeviri nisbi değeri okunamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Çeviri çıkış adı değeri okunamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Çeviri matrisi okunamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Birleştirme alt birim adı alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Birleştirme üst birim adı alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Öncelik değerleri alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Döngü (tekrar) değerleri alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Easln (Yavaş Başlangıç) değerleri alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - EaseOut (Yavaş Bitiş) değerleri alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - El şekillendirme değeri alınamadı. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Duygu ifadesi adı okunamadı. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Yanlış kök eklem adı, "kalça" kullanın - </floater.string> - <text name="name_label"> - Ad: - </text> - <text name="description_label"> - Açıklama: - </text> - <spinner label="Öncelik" name="priority" tool_tip="Bu animasyonun diğer animasyonları geçersiz kılabileceği kontrolleri"/> - <check_box label="Döngü" name="loop_check" tool_tip="Bu animasyonun döngülenmesini (tekrarlanmasını) sağlar"/> - <spinner label="İç (%)" name="loop_in_point" tool_tip="Döngünün döndüğü animasyon noktasını belirler"/> - <spinner label="Dış (%)" name="loop_out_point" tool_tip="Animasyonda döngünün bittiği noktayı belirler"/> - <text name="hand_label"> - El Duruşu - </text> - <combo_box name="hand_pose_combo" tool_tip="Ellerin animasyon sırasında neler yaptığını kontrol eder"> - <combo_box.item label="Yayılım" name="Spread"/> - <combo_box.item label="Rahat" name="Relaxed"/> - <combo_box.item label="Her İkisi de İşaret Ediyor" name="PointBoth"/> - <combo_box.item label="Yumruk" name="Fist"/> - <combo_box.item label="Sol Rahat" name="RelaxedLeft"/> - <combo_box.item label="Sol İşaret Ediyor" name="PointLeft"/> - <combo_box.item label="Sol Yumruk" name="FistLeft"/> - <combo_box.item label="Sağ Rahat" name="RelaxedRight"/> - <combo_box.item label="Sağ İşaret Ediyor" name="PointRight"/> - <combo_box.item label="Sağ Yumruk" name="FistRight"/> - <combo_box.item label="Sağı Selamlıyor" name="SaluteRight"/> - <combo_box.item label="Yazı Yazıyor" name="Typing"/> - <combo_box.item label="Sağ Barış" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - İfade - </text> - <combo_box name="emote_combo" tool_tip="Yüzün animasyon sırasındaki ifadesini kontrol eder"> - <item label="(Hiçbiri)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Korkmuş" name="Afraid" value="Korkmuş"/> - <item label="Kızgın" name="Angry" value="Kızgın"/> - <item label="Yaygın Gülümseyiş" name="BigSmile" value="Yaygın Gülümseyiş"/> - <item label="Canı Sıkılmış" name="Bored" value="Canı Sıkılmış"/> - <item label="Ağlama" name="Cry" value="Ağlama"/> - <item label="Dudak Bükme" name="Disdain" value="Dudak Bükme"/> - <item label="Utanmış" name="Embarrassed" value="Utanmış"/> - <item label="Kaş Çatma" name="Frown" value="Kaş Çatma"/> - <item label="Öpücük" name="Kiss" value="Öpücük"/> - <item label="Gülme" name="Laugh" value="Gülme"/> - <item label="Kahkaha" name="Plllppt" value="Kahkaha"/> - <item label="Tiksinmiş" name="Repulsed" value="Tiksinmiş"/> - <item label="Üzgün" name="Sad" value="Üzgün"/> - <item label="Omuz Silkme" name="Shrug" value="Omuz Silkme"/> - <item label="Gülümseme" name="Smile" value="Gülümseme"/> - <item label="Sürpriz" name="Surprise" value="Sürpriz"/> - <item label="Göz Kırpma" name="Wink" value="Göz Kırpma"/> - <item label="Endişelenme" name="Worry" value="Endişelenme"/> - </combo_box> - <text name="preview_label"> - Şu sırada önizle - </text> - <combo_box name="preview_base_anim" tool_tip="Animasyon davranışınızı avatarınız genel hareketleri yaparken test etmek için bunu kullanın."> - <item label="Ayakta Duruyor" name="Standing" value="Ayakta Duruyor"/> - <item label="Yürüyor" name="Walking" value="Yürüyor"/> - <item label="Oturuyor" name="Sitting" value="Oturuyor"/> - <item label="Uçuyor" name="Flying" value="Uçuyor"/> - </combo_box> - <spinner label="Yavaş Başlangıç (saniye)" name="ease_in_time" tool_tip="Animasyonun kaynaştığı süre (saniye olarak)"/> - <spinner label="Yavaş Bitiş (saniye)" name="ease_out_time" tool_tip="Animasyonun ayrıştığı süre (saniye olarak)"/> - <button name="play_btn" tool_tip="Animasyonunu oynat"/> - <button name="pause_btn" tool_tip="Animasyonunu duraklat"/> - <button name="stop_btn" tool_tip="Animasyo oynatmayı durdur"/> - <text name="bad_animation_text"> - Animasyon dosyası okunamadı. - -Poser 4'ten aktarılan BHV dosyalarını tavsiye ederiz. - </text> - <button label="Karşıya Yükle (L$[AMOUNT])" name="ok_btn"/> - <button label="İptal" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_autoreplace.xml b/indra/newview/skins/default/xui/tr/floater_autoreplace.xml new file mode 100644 index 0000000000..e52e05dc61 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="Otomatik Yerine Koyma Ayarları"> + <check_box label="Otomatik Yerine Koymayı Etkinleştir" name="autoreplace_enable" tool_tip="Siz sohbet metni girdikçe, girilen herhangi bir anahtar kelimenin yerine karşılık gelen değiştirmeyi koyabilirsiniz"/> + <button label="Listeyi İçeri Aktar..." name="autoreplace_import_list" tool_tip="Daha önce aktarılan bir listeyi yükler."/> + <button label="Listeyi Aktarın..." name="autoreplace_export_list" tool_tip="Seçilen listeyi bir dosyaya kaydederek paylaşın."/> + <button label="Yeni Liste..." name="autoreplace_new_list" tool_tip="Yeni bir liste oluşturun."/> + <button label="Listeyi Sil" name="autoreplace_delete_list" tool_tip="Seçilen listeyi silin."/> + <button name="autoreplace_list_up" tool_tip="Bu listenin önceliğini yükseltin."/> + <button name="autoreplace_list_down" tool_tip="Bu listenin önceliğini azaltın."/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="Anahtar kelime" name="keyword"/> + <scroll_list.columns label="Değiştirme" name="replacement"/> + </scroll_list> + <button label="Ekle..." name="autoreplace_add_entry"/> + <button label="Kaldır" name="autoreplace_delete_entry"/> + <button label="Girişi Kaydet" name="autoreplace_save_entry" tool_tip="Bu girişi kaydet."/> + <button label="Değişiklikleri Kaydet" name="autoreplace_save_changes" tool_tip="Tüm değişiklikleri kaydet."/> + <button label="İptal" name="autoreplace_cancel" tool_tip="Tüm değişiklikleri iptal et."/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/tr/floater_env_settings.xml b/indra/newview/skins/default/xui/tr/floater_env_settings.xml deleted file mode 100644 index d53629f6fe..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_env_settings.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Environment Editor Floater" title="ÇEVRE DÜZENLEYİCİ"> - <floater.string name="timeStr"> - [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc] - </floater.string> - <text name="EnvTimeText"> - Günün Saati - </text> - <text name="EnvTimeText2"> - 12:00 PM - </text> - <text name="EnvCloudText"> - Bulut Örtüsü - </text> - <text name="EnvWaterColorText"> - Su Rengi - </text> - <color_swatch name="EnvWaterColor" tool_tip="Renk seçiciyi açmak için tıklayın"/> - <text name="EnvWaterFogText"> - Su Sisi - </text> - <button label="Gayrimenkul Saati Kullan" name="EnvUseEstateTimeButton"/> - <button label="Gelişmiş Gökyüzü" name="EnvAdvancedSkyButton"/> - <button label="Gelişmiş Su" name="EnvAdvancedWaterButton"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_inventory.xml b/indra/newview/skins/default/xui/tr/floater_inventory.xml deleted file mode 100644 index cfb12d4b68..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_inventory.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="ENVANTERİM"> - <panel label="Envanter Paneli" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_model_preview.xml b/indra/newview/skins/default/xui/tr/floater_model_preview.xml index 0c7cabc6ea..c00cadd3bd 100644 --- a/indra/newview/skins/default/xui/tr/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/tr/floater_model_preview.xml @@ -92,19 +92,54 @@ <text initial_value="Üçgenler" name="triangles" value="Üçgenler"/> <text initial_value="Köşeler" name="vertices" value="Köşeler"/> <text initial_value="Yüksek" name="high_label" value="Yüksek"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="Oluştur"/> + </combo_box> <button label="Gözat..." name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata Eşiği"/> + </combo_box> <text initial_value="0" name="high_triangles" value="0"/> <text initial_value="0" name="high_vertices" value="0"/> <text initial_value="Orta" name="medium_label" value="Orta"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="Oluştur"/> + <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/> + </combo_box> <button label="Gözat..." name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata Eşiği"/> + </combo_box> <text initial_value="0" name="medium_triangles" value="0"/> <text initial_value="0" name="medium_vertices" value="0"/> <text initial_value="Düşük" name="low_label" value="Düşük"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="Oluştur"/> + <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/> + </combo_box> <button label="Gözat..." name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata Eşiği"/> + </combo_box> <text initial_value="0" name="low_triangles" value="0"/> <text initial_value="0" name="low_vertices" value="0"/> <text initial_value="En Düşük" name="lowest_label" value="En Düşük"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="Dosyadan yükle"/> + <item name="Generate" value="Oluştur"/> + <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/> + </combo_box> <button label="Gözat..." name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="Üçgen Limiti"/> + <item name="Error Threshold" value="Hata Eşiği"/> + </combo_box> <text initial_value="0" name="lowest_triangles" value="0"/> <text initial_value="0" name="lowest_vertices" value="0"/> <check_box label="Normalleri Oluştur" name="gen_normals"/> diff --git a/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml b/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml deleted file mode 100644 index 6b12ad0ef5..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="YAKINDAKİ SOHBET"> - <check_box label="Sohbeti çevir" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..f38d8c84c6 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="Yol bulma karakterleri"> + <floater.string name="messaging_get_inprogress"> + Yol bulma karakterleri için sorgulama yapılıyor ... + </floater.string> + <floater.string name="messaging_get_error"> + Yol bulma karakterleri için sorgulama yapılırken hata saptandı. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Yol bulma karakterleri yok. + </floater.string> + <floater.string name="messaging_complete_available"> + Toplam [NUM_TOTAL] karakter içerisinden [NUM_SELECTED] adet seçildi. + </floater.string> + <floater.string name="messaging_not_enabled"> + Bu bölgede yol bulma etkin değil. + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] µs + </floater.string> + <floater.string name="character_owner_loading"> + [Yükleniyor] + </floater.string> + <floater.string name="character_owner_unknown"> + [Bilinmiyor] + </floater.string> + <floater.string name="character_owner_group"> + [grup] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Ad" name="name"/> + <scroll_list.columns label="Açıklama" name="description"/> + <scroll_list.columns label="Sahip" name="owner"/> + <scroll_list.columns label="CPU" name="cpu_time"/> + <scroll_list.columns label="İrtifa" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + Karakterler: + </text> + <button label="Listeyi yenile" name="refresh_objects_list"/> + <button label="Tümünü seç" name="select_all_objects"/> + <button label="Hiçbirini seçme" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + Seçilen karakterler üzerinde eylemler: + </text> + <check_box label="İşareti göster" name="show_beacon"/> + <check_box label="Fizik kapsülünü göster" name="show_physics_capsule"/> + <button label="Al" name="take_objects"/> + <button label="Kopya al" name="take_copy_objects"/> + <button label="Beni ona ışınla" name="teleport_me_to_object" tool_tip="Sadece bir karakter seçildiğinde etkindir."/> + <button label="İade Et" name="return_objects"/> + <button label="Sil" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml new file mode 100644 index 0000000000..6eecc7fb77 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="Yol bulma görüntüleme / test"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + Yol bulma kütüphanesi uygulaması bulunamıyor. + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + Bu bölgede yol bulma etkin değil. + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + Bölgenin yüklenmesinin bitmesi bekleniyor. + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + Navigasyon örgüsünün durumu kontrol ediliyor. + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + Navigasyon örgüsü indiriliyor. + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + Sunucudaki navigasyon örgüsü değişti. En son navigasyon örgüsü indiriliyor. + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + En son navigasyon örgüsü indirildi. + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + Navigasyon örgüsü başarıyla indirilemedi. + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + Navigasyon örgüsünde bekleyen değişiklikler var. + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + Navigasyon örgüsü oluşturuluyor. + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + Bazı navigasyon örgüsü bölgelerinde bekleyen değişiklikler var. + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + Bazı navigasyon örgüsü bölgeleri oluşturuluyor. + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + Bazı navigasyon örgüsü bölgelerinde bekleyen değişiklikler var, bazıları ise oluşturuluyor. + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + Navigasyon örgüsü güncel. + </floater.string> + <floater.string name="pathing_library_not_implemented"> + Yol bulma kütüphanesi uygulaması bulunamıyor. + </floater.string> + <floater.string name="pathing_region_not_enabled"> + Bu bölgede yol bulma etkin değil. + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + Lütfen başlangıç ve bitim noktalarını seçin. + </floater.string> + <floater.string name="pathing_choose_start_point"> + Lütfen başlangıç noktasını seçin. + </floater.string> + <floater.string name="pathing_choose_end_point"> + Lütfen bitim noktasını seçin. + </floater.string> + <floater.string name="pathing_path_valid"> + Yol turuncu olarak gösterilmiştir. + </floater.string> + <floater.string name="pathing_path_invalid"> + Seçilen noktalar arasında bir yol bulunamıyor. + </floater.string> + <floater.string name="pathing_error"> + Yol oluşturma sırasında bir hata meydana geldi. + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="Görünüm" name="view_panel"> + <text name="show_label"> + Göster: + </text> + <check_box label="Dünya" name="show_world"/> + <check_box label="Sadece hareket ettirilebilir nesneler" name="show_world_movables_only"/> + <check_box label="Navigasyon örgüsü" name="show_navmesh"/> + <text name="show_walkability_label"> + Yürüyebilirlik haritasını göster: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="Gösterme" name="show_heatmap_mode_none"/> + <combo_box.item label="A karakter tipi" name="show_heatmap_mode_a"/> + <combo_box.item label="B karakter tipi" name="show_heatmap_mode_b"/> + <combo_box.item label="C karakter tipi" name="show_heatmap_mode_c"/> + <combo_box.item label="D karakter tipi" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="Yürüyebilirler" name="show_walkables"/> + <check_box label="Maddi hacimler" name="show_material_volumes"/> + <check_box label="Statik engeller" name="show_static_obstacles"/> + <check_box label="Hariç tutma hacimleri" name="show_exclusion_volumes"/> + <check_box label="Su düzlemi" name="show_water_plane"/> + <check_box label="X-ışını görünümü ile" name="show_xray"/> + </panel> + <panel label="Yolu test et" name="test_panel"> + <text name="ctrl_click_label"> + Başlangıç noktasını seçmek için Ctrl tuşuna basarak tıklayın. + </text> + <text name="shift_click_label"> + Bitim noktasını seçmek için Shift tuşuna basarak tıklayın. + </text> + <text name="character_width_label"> + Karakter genişliği + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + m + </text> + <text name="character_type_label"> + Karakter tipi + </text> + <combo_box name="path_character_type"> + <combo_box.item label="Hiçbiri" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="Yolu temizle" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..2e416c9311 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="Yol bulma bağlantı kümeleri"> + <floater.string name="messaging_get_inprogress"> + Yol bulma bağlantı kümeleri için sorgulama yapılıyor ... + </floater.string> + <floater.string name="messaging_get_error"> + Yol bulma bağlantı kümeleri için sorgulama yapılırken hata saptandı. + </floater.string> + <floater.string name="messaging_set_inprogress"> + Seçilen yol bulma bağlantı kümeleri değiştiriliyor ... + </floater.string> + <floater.string name="messaging_set_error"> + Seçilen yol bulma bağlantı kümeleri değiştirilirken hata saptandı. + </floater.string> + <floater.string name="messaging_complete_none_found"> + Yol bulma bağlantı kümeleri yok. + </floater.string> + <floater.string name="messaging_complete_available"> + Toplam [NUM_TOTAL] bağlantı kümesi içerisinden [NUM_SELECTED] adet seçildi. + </floater.string> + <floater.string name="messaging_not_enabled"> + Bu bölgede yol bulma etkin değil. + </floater.string> + <floater.string name="linkset_terrain_name"> + [Yüzey] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Yükleniyor] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Bilinmiyor] + </floater.string> + <floater.string name="linkset_owner_group"> + [grup] + </floater.string> + <floater.string name="linkset_is_scripted"> + Evet + </floater.string> + <floater.string name="linkset_is_not_scripted"> + Hayır + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + Bilinmiyor + </floater.string> + <floater.string name="linkset_use_walkable"> + Yürüyebilir + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + Statik engel + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + Hareket ettirilebilir engel + </floater.string> + <floater.string name="linkset_use_material_volume"> + Maddi hacim + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + Hariç tutma hacmi + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + Hareket ettirilebilir fantom + </floater.string> + <floater.string name="linkset_is_terrain"> + [değiştirilemez] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [kısıtlı] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [konkav] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [kısıtlı, konkav] + </floater.string> + <floater.string name="linkset_choose_use"> + Bağlantı kümesi kullanımını seç... + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="Bağlantı kümesi kullanımına göre filtrele..." name="filter_by_linkset_use_none"/> + <combo_box.item label="Yürüyebilir" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="Statik engel" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="Hareket ettirilebilir engel" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="Maddi hacim" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="Hariç tutma hacmi" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="Hareket ettirilebilir fantom" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="Uygula" name="apply_filters"/> + <button label="Temizle" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="Ad (kök prim)" name="name"/> + <scroll_list.columns label="Açıklama (kök prim)" name="description"/> + <scroll_list.columns label="Sahip" name="owner"/> + <scroll_list.columns label="Komut Dosyalı" name="scripted"/> + <scroll_list.columns label="Etki" name="land_impact"/> + <scroll_list.columns label="Mesafe" name="dist_from_you"/> + <scroll_list.columns label="Bağlantı kümesi kullanımı" name="linkset_use"/> + <scroll_list.columns label="% A" name="a_percent"/> + <scroll_list.columns label="% B" name="b_percent"/> + <scroll_list.columns label="% C" name="c_percent"/> + <scroll_list.columns label="% D" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + Bağlantı kümeleri: + </text> + <button label="Listeyi yenile" name="refresh_objects_list"/> + <button label="Tümünü seç" name="select_all_objects"/> + <button label="Hiçbirini seçme" name="select_none_objects"/> + </panel> + <panel> + <check_box label="İşareti göster" name="show_beacon"/> + <button label="Al" name="take_objects"/> + <button label="Kopya al" name="take_copy_objects"/> + <button label="Beni ona ışınla" name="teleport_me_to_object"/> + <button label="İade Et" name="return_objects"/> + <button label="Sil" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + Yürüyebilirlik: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="A tipi karakterleri için yürüyebilirlik. Örnek karakter tipi humanoiddir."/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="B tipi karakterleri için yürüyebilirlik. Örnek karakter tipi yaratıktır."/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="C tipi karakterleri için yürüyebilirlik. Örnek karakter tipi mekaniktir."/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="D tipi karakterleri için yürüyebilirlik. Örnek karakter tipi diğerdir."/> + <button label="Değişiklikleri uygula" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (Humanoid) + </text> + <text name="suggested_use_b_label"> + (Yaratık) + </text> + <text name="suggested_use_c_label"> + (Mekanik) + </text> + <text name="suggested_use_d_label"> + (Diğer) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_postcard.xml b/indra/newview/skins/default/xui/tr/floater_postcard.xml deleted file mode 100644 index ef11c68afe..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_postcard.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ANLIK GÖRÜNTÜYÜ E-POSTAYLA GÖNDER"> - <floater.string name="default_subject"> - SECOND_LIFE]'dan posta kartı. - </floater.string> - <floater.string name="default_message"> - Buna bakın! - </floater.string> - <floater.string name="upload_message"> - Gönderiyor... - </floater.string> - <text name="to_label"> - Alıcının E-postası: - </text> - <text name="from_label"> - E-postanız: - </text> - <text name="name_label"> - Adınız: - </text> - <text name="subject_label"> - Konu: - </text> - <line_editor label="Konunuzu buraya yazın." name="subject_form"/> - <text name="msg_label"> - İleti: - </text> - <text_editor name="msg_form"> - İletinizi buraya yazın. - </text_editor> - <button label="İptal" name="cancel_btn"/> - <button label="Gönder" name="send_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_spellcheck.xml b/indra/newview/skins/default/xui/tr/floater_spellcheck.xml new file mode 100644 index 0000000000..f5f0ba8fd9 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="Yazım Denetimcisi Ayarları"> + <check_box label="Yazım denetimcisini etkinleştir" name="spellcheck_enable"/> + <text name="spellcheck_main"> + Ana sözlük : + </text> + <text label="Günlükler:" name="spellcheck_additional"> + İlave sözlükler : + </text> + <text name="spellcheck_available"> + Mevcut + </text> + <text name="spellcheck_active"> + Etkin + </text> + <button label="Kaldır" name="spellcheck_remove_btn"/> + <button label="İçeri Aktar..." name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml new file mode 100644 index 0000000000..ded71cad40 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="Sözlüğü İçeri Aktar"> + <button label="Gözat" label_selected="Gözat" name="dictionary_path_browse"/> + <button label="İçeri Aktar" name="ok_btn"/> + <button label="İptal" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_stats.xml b/indra/newview/skins/default/xui/tr/floater_stats.xml index e3f54fc338..afce87bdaa 100644 --- a/indra/newview/skins/default/xui/tr/floater_stats.xml +++ b/indra/newview/skins/default/xui/tr/floater_stats.xml @@ -53,7 +53,13 @@ <stat_bar label="Nesneler" name="simobjects"/> <stat_bar label="Etkin Nesneler" name="simactiveobjects"/> <stat_bar label="Etkin Komut Dosyaları" name="simactivescripts"/> + <stat_bar label="Çalıştırılan Komut Dosyaları" name="simpctscriptsrun"/> <stat_bar label="Komut Dosyası Etkinlikleri" name="simscripteps"/> + <stat_view label="Yol bulma" name="simpathfinding"> + <stat_bar label="Yapay Zeka Adım Süresi" name="simsimaistepmsec"/> + <stat_bar label="Atlanan Siluet Adımları" name="simsimskippedsilhouettesteps"/> + <stat_bar label="Güncellenen Karakterler" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="Gelen Paketler" name="siminpps"/> <stat_bar label="Giden Paketler" name="simoutpps"/> <stat_bar label="Bekleyen Karşıdan Yüklemeler" name="simpendingdownloads"/> diff --git a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml index 67bf9071b3..889425f23a 100644 --- a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml @@ -19,6 +19,8 @@ <button label="Varsayılan" label_selected="Varsayılan" name="Default"/> <button label="Boş" label_selected="Boş" name="Blank"/> <button label="Hiçbiri" label_selected="Hiçbiri" name="None"/> + <check_box initial_value="true" label="Canlı Önizleme" name="apply_immediate_check"/> + <text name="preview_disabled" value="Önizleme Devre Dışı"/> <filter_editor label="Dokuları Filtrele" name="inventory search editor"/> <check_box initial_value="false" label="Klasörleri göster" name="show_folders_check"/> <button label="Ekle" label_selected="Ekle" name="l_add_btn"/> @@ -30,5 +32,4 @@ </scroll_list> <button label="Tamam" label_selected="Tamam" name="Select"/> <button label="İptal" label_selected="İptal" name="Cancel"/> - <check_box initial_value="true" label="Şimdi uygula" name="apply_immediate_check"/> </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml index a592479b6c..42426225c7 100644 --- a/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml @@ -45,10 +45,23 @@ <text name="total_time_refetch_vis_cache_label"> 15, Görünür dokuların önbellekten tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel </text> + <text name="total_time_refetch_all_cache_label"> + 16, Tüm dokuların önbellekten tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + </text> <text name="total_time_refetch_vis_http_label"> - 16, Görünür dokuların HTTP'den tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + 17, Görünür dokuların HTTP'den tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + </text> + <text name="total_time_refetch_all_http_label"> + 18, Tüm dokuların HTTP'den tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel + </text> + <spinner label="19, Teksel/Piksel Oranı:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20, Doku Kaynağı: </text> - <spinner label="17, Teksel/Piksel Oranı:" name="texel_pixel_ratio"/> + <radio_group name="texture_source"> + <radio_item label="Önbellek + HTTP" name="0"/> + <radio_item label="Sadece HTTP" name="1"/> + </radio_group> <button label="Başla" name="start_btn"/> <button label="Sıfırla" name="clear_btn"/> <button label="Kapat" name="close_btn"/> @@ -58,5 +71,7 @@ <button label="Şifre Çöz" name="decode_btn"/> <button label="GL Dokusu" name="gl_btn"/> <button label="Görünür Dokuları Önbellekten Tekrar Al" name="refetchviscache_btn"/> + <button label="Tüm Önbelleği Tekrar Al" name="refetchallcache_btn"/> <button label="Görünür Dokuları HTTP'den Tekrar Al" name="refetchvishttp_btn"/> + <button label="Tüm HTTP'yi Tekrar Al" name="refetchallhttp_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_tools.xml b/indra/newview/skins/default/xui/tr/floater_tools.xml index b0c59ced42..4bf0372a8a 100644 --- a/indra/newview/skins/default/xui/tr/floater_tools.xml +++ b/indra/newview/skins/default/xui/tr/floater_tools.xml @@ -150,6 +150,12 @@ <panel.string name="text modify info 4"> Bu nesneleri değiştiremezsiniz </panel.string> + <panel.string name="text modify info 5"> + Bir bölge sınırı üzerinden bu nesneyi değiştiremezsiniz + </panel.string> + <panel.string name="text modify info 6"> + Bir bölge sınırı üzerinden bu nesneleri değiştiremezsiniz + </panel.string> <panel.string name="text modify warning"> İzinleri ayarlamak için tüm nesneyi seçmelisiniz </panel.string> @@ -199,12 +205,12 @@ <combo_box.item label="Yakınlaştır" name="Zoom"/> </combo_box> <check_box label="Satılık:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> <combo_box.item label="Kopyala" name="Copy"/> <combo_box.item label="İçerik" name="Contents"/> <combo_box.item label="Orijinal" name="Original"/> </combo_box> - <spinner label="Fiyat: L$" name="Edit Cost"/> <check_box label="Aramada göster" name="search_check" tool_tip="Kişiler arama sonuçlarında bu nesneyi görebilsin"/> <panel name="perms_build"> <text name="perm_modify"> @@ -240,6 +246,11 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + Yol bulma özellikleri: + </text> + </panel> </panel> <panel label="Nesne" name="Object"> <check_box label="Kilitli" name="checkbox locked" tool_tip="Nesnenin hareket ettirilmesini veya silinmesini engeller. Arzulanmayan düzenlemelerden kaçınmak için inşa işlemleri sırasında oldukça faydalıdır."/> diff --git a/indra/newview/skins/default/xui/tr/floater_top_objects.xml b/indra/newview/skins/default/xui/tr/floater_top_objects.xml index e726f583cc..19420c68e3 100644 --- a/indra/newview/skins/default/xui/tr/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/tr/floater_top_objects.xml @@ -9,9 +9,6 @@ <floater.string name="scripts_score_label"> Süre </floater.string> - <floater.string name="scripts_mono_time_label"> - Mono Süre - </floater.string> <floater.string name="top_colliders_title"> En Çok Çarpışanlar </floater.string> @@ -32,9 +29,10 @@ <scroll_list.columns label="Ad" name="name"/> <scroll_list.columns label="Sahip" name="owner"/> <scroll_list.columns label="Konum" name="location"/> + <scroll_list.columns label="Parsel" name="parcel"/> <scroll_list.columns label="Süre" name="time"/> - <scroll_list.columns label="Mono Süre" name="mono_time"/> <scroll_list.columns label="URL'ler" name="URLs"/> + <scroll_list.columns label="Bellek (KB)" name="memory"/> </scroll_list> <text name="id_text"> Nesne Kimliği: @@ -48,6 +46,10 @@ Sahip: </text> <button label="Filtrele" name="filter_owner_btn"/> + <text name="parcel_name_text"> + Parsel: + </text> + <button label="Filtrele" name="filter_parcel_btn"/> <button label="Seçileni İade Et" name="return_selected_btn"/> <button label="Tümünü İade Et" name="return_all_btn"/> <button label="Seçileni Devre Dışı Bırak" name="disable_selected_btn"/> diff --git a/indra/newview/skins/default/xui/tr/floater_water.xml b/indra/newview/skins/default/xui/tr/floater_water.xml deleted file mode 100644 index 66d6c1e30d..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_water.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Water Floater" title="GELİŞMİŞ SU DÜZENLEYİCİ"> - <floater.string name="WLDefaultWaterNames"> - Varsayılan:Camsı:Havuz:çamurlu:İkinci Veba:YILAN!!!:Valdez - </floater.string> - <text name="KeyFramePresetsText"> - Su Ön Ayarları: - </text> - <button label="Yeni" label_selected="Yeni" name="WaterNewPreset"/> - <button label="Kaydet" label_selected="Kaydet" name="WaterSavePreset"/> - <button label="Sil" label_selected="Sil" name="WaterDeletePreset"/> - <tab_container name="Water Tabs"> - <panel label="AYARLAR" name="Settings"> - <text name="BHText"> - Su Sisi Rengi - </text> - <color_swatch name="WaterFogColor" tool_tip="Renk seçiciyi açmak için tıklayın"/> - <text name="WaterFogDensText"> - Su Yoğunluk Üssü - </text> - <text name="WaterUnderWaterFogModText"> - Sualtı Sis Değiştiricisi - </text> - <text name="BDensText"> - Yansıma Dalgacığı Ölçeği - </text> - <slider label="1" name="WaterNormalScaleX"/> - <slider label="2" name="WaterNormalScaleY"/> - <slider label="3" name="WaterNormalScaleZ"/> - <text name="HDText"> - Fresnel Ölçeği - </text> - <text name="FresnelOffsetText"> - Fresnel Dengeleyicisi - </text> - <text name="DensMultText"> - Yukarıdan Kırılma Ölçeği - </text> - <text name="WaterScaleBelowText"> - Aşağıdan Kırılma Ölçeği - </text> - <text name="MaxAltText"> - Bulanıklaştırma Çarpanı - </text> - </panel> - <panel label="GÖRÜNTÜ" name="Waves"> - <text name="BHText"> - Büyük Dalga Yönü - </text> - <text name="WaterWave1DirXText"> - X - </text> - <text name="WaterWave1DirYText"> - Y - </text> - <text name="BHText2"> - Küçük Dalga Yönü - </text> - <text name="WaterWave2DirXText"> - X - </text> - <text name="WaterWave2DirYText"> - Y - </text> - <text name="BHText3"> - Normal Harita - </text> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_windlight_options.xml b/indra/newview/skins/default/xui/tr/floater_windlight_options.xml deleted file mode 100644 index 6c5fba374c..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_windlight_options.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="WindLight floater" title="GELİŞMİŞ GÖKYÜZÜ DÜZENLEYİCİ"> - <floater.string name="WLDefaultSkyNames"> - A-12:A-24:A-3:A-15:A-16.30:A-6:A-18:A-9:A-21:Barselona:Tipi:Mavi Gün Ortası:Sahilde Öğleden Sonra:Sahilde Gün Batımı:Varsayılan:Çölde Gün Batımı:Güzel Bir Gün:Kabarık Büyük Bulutlar:Sisli:Şık Şık:Şık Şık Şık:Dondurma:Hayalet:Uygunsuz Gerçekler:Gün Ortası1:Gün Ortası 2:Gün Ortası 3:Gün Ortası 4:Gece:Korsan:Mor:Denizcinin Keyfi:Saf Tensel - </floater.string> - <text name="KeyFramePresetsText"> - Gökyüzü Ön Ayarları: - </text> - <button label="Yeni" label_selected="Yeni" name="WLNewPreset"/> - <button label="Kaydet" label_selected="Kaydet" name="WLSavePreset"/> - <button label="Sil" label_selected="Sil" name="WLDeletePreset"/> - <button label="Gün Döngüsü Düzenleyici" label_selected="Gün Döngüsü Düzenleyici" name="WLDayCycleMenuButton"/> - <tab_container name="WindLight Tabs"> - <panel label="ATMOSFER" name="Atmosphere"> - <text name="BHText"> - Mavi Ufuk - </text> - <text name="BHText2"> - R - </text> - <text name="BHText3"> - G - </text> - <text name="BHText4"> - B - </text> - <text name="BHText5"> - I - </text> - <text name="BDensText"> - Puslu Ufuk - </text> - <text name="BDensText2"> - Mavi Yoğunluğu - </text> - <text name="BHText6"> - R - </text> - <text name="BHText7"> - G - </text> - <text name="BHText8"> - B - </text> - <text name="BHText9"> - I - </text> - <text name="HDText"> - Pus Yoğunluğu - </text> - <text name="DensMultText"> - Yoğunluk Çarpanı - </text> - <text name="WLDistanceMultText"> - Mesafe Çarpanı - </text> - <text name="MaxAltText"> - Maks İrtifa - </text> - </panel> - <panel label="AYDINLATMA" name="Lighting"> - <text name="SLCText"> - Güneş/Ay Rengi - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="TODText"> - Güneş/Ay Konumu - </text> - <text name="WLAmbientText"> - Ortam - </text> - <text name="BHText5"> - R - </text> - <text name="BHText6"> - G - </text> - <text name="BHText7"> - B - </text> - <text name="BHText8"> - I - </text> - <text name="WLEastAngleText"> - Doğu Açısı - </text> - <text name="SunGlowText"> - Güneş Parıltısı - </text> - <slider label="Odak" name="WLGlowB"/> - <slider label="Büyüklük" name="WLGlowR"/> - <text name="SceneGammaText"> - Sahne Gaması - </text> - <text name="WLStarText"> - Yıldız Parlaklığı - </text> - </panel> - <panel label="BULUTLAR" name="Clouds"> - <text name="WLCloudColorText"> - Bulut Rengi - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="WLCloudColorText2"> - Bulut XY/Yoğunluğu - </text> - <text name="BHText5"> - X - </text> - <text name="BHText6"> - Y - </text> - <text name="BHText7"> - D - </text> - <text name="WLCloudCoverageText"> - Bulut Örtüsü - </text> - <text name="WLCloudScaleText"> - Bulut Yüksekliği - </text> - <text name="WLCloudDetailText"> - Bulut Ayrıntısı (XY/Yoğunluğu) - </text> - <text name="BHText8"> - X - </text> - <text name="BHText9"> - Y - </text> - <text name="BHText10"> - D - </text> - <text name="WLCloudScrollXText"> - Bulut Kaydırma X - </text> - <check_box label="Kilitle" name="WLCloudLockX"/> - <text name="WLCloudScrollYText"> - Bulut Kaydırma Y - </text> - <check_box label="Kilitle" name="WLCloudLockY"/> - <check_box label="Klasik Bulutlar Çiz" name="DrawClassicClouds"/> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/tr/menu_bottomtray.xml b/indra/newview/skins/default/xui/tr/menu_bottomtray.xml deleted file mode 100644 index f17c0f9971..0000000000 --- a/indra/newview/skins/default/xui/tr/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="Konuşma Düğmesi" name="EnableVoiceChat"/> - <menu_item_check label="Mimik düğmesi" name="ShowGestureButton"/> - <menu_item_check label="Taşıma düğmesi" name="ShowMoveButton"/> - <menu_item_check label="Görüntüleme düğmesi" name="ShowCameraButton"/> - <menu_item_check label="Anlık görüntü düğmesi" name="ShowSnapshotButton"/> - <menu_item_check label="İnşa Et düğmesi" name="ShowBuildButton"/> - <menu_item_check label="Arama düğmesi" name="ShowSearchButton"/> - <menu_item_check label="Harita düğmesi" name="ShowWorldMapButton"/> - <menu_item_check label="Mini-harita düğmesi" name="ShowMiniMapButton"/> - <menu_item_call label="Kes" name="NearbyChatBar_Cut"/> - <menu_item_call label="Kopyala" name="NearbyChatBar_Copy"/> - <menu_item_call label="Yapıştır" name="NearbyChatBar_Paste"/> - <menu_item_call label="Sil" name="NearbyChatBar_Delete"/> - <menu_item_call label="Tümünü Seç" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/tr/menu_inventory.xml b/indra/newview/skins/default/xui/tr/menu_inventory.xml index 170cdebd24..51049427af 100644 --- a/indra/newview/skins/default/xui/tr/menu_inventory.xml +++ b/indra/newview/skins/default/xui/tr/menu_inventory.xml @@ -68,6 +68,7 @@ <menu_item_call label="Sistem Klasörünü Sil" name="Delete System Folder"/> <menu_item_call label="Konferans Sohbeti Başlat" name="Conference Chat Folder"/> <menu_item_call label="Oyna" name="Sound Play"/> + <menu_item_call label="SLurl'i Kopyala" name="url_copy"/> <menu_item_call label="Yer İmi Hakkında" name="About Landmark"/> <menu_item_call label="SL Dünyasında Oynat" name="Animation Play"/> <menu_item_call label="Yerel Olarak Oynat" name="Animation Audition"/> diff --git a/indra/newview/skins/default/xui/tr/menu_mode_change.xml b/indra/newview/skins/default/xui/tr/menu_mode_change.xml deleted file mode 100644 index 678950b633..0000000000 --- a/indra/newview/skins/default/xui/tr/menu_mode_change.xml +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Mode Change"> - <menu_item_check label="Temel" name="BasicMode"/> - <menu_item_check label="Gelişmiş" name="AdvancedMode"/> -</toggleable_menu> diff --git a/indra/newview/skins/default/xui/tr/menu_object.xml b/indra/newview/skins/default/xui/tr/menu_object.xml index d60c68e5e9..72f7adf016 100644 --- a/indra/newview/skins/default/xui/tr/menu_object.xml +++ b/indra/newview/skins/default/xui/tr/menu_object.xml @@ -3,6 +3,8 @@ <menu_item_call label="Dokun" name="Object Touch"/> <menu_item_call label="Düzenle" name="Edit..."/> <menu_item_call label="İnşa Et" name="Build"/> + <menu_item_call label="Bağlantı kümelerinde göster" name="show_in_linksets"/> + <menu_item_call label="Karakterlerde göster" name="show_in_characters"/> <menu_item_call label="Aç" name="Open"/> <menu_item_call label="Buraya Otur" name="Object Sit"/> <menu_item_call label="Kalk" name="Object Stand Up"/> diff --git a/indra/newview/skins/default/xui/tr/menu_text_editor.xml b/indra/newview/skins/default/xui/tr/menu_text_editor.xml index ffbf309e84..76c7b43e1e 100644 --- a/indra/newview/skins/default/xui/tr/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/tr/menu_text_editor.xml @@ -1,5 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(bilinmiyor)" name="Suggestion 1"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 2"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 3"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 4"/> + <menu_item_call label="(bilinmiyor)" name="Suggestion 5"/> + <menu_item_call label="Sözlüğe Ekle" name="Add to Dictionary"/> + <menu_item_call label="Yok saya ekle" name="Add to Ignore"/> <menu_item_call label="Kes" name="Cut"/> <menu_item_call label="Kopyala" name="Copy"/> <menu_item_call label="Yapıştır" name="Paste"/> diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index ea84e7d24b..7a7faf6ac4 100644 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -26,6 +26,7 @@ <menu_item_call label="Tercihler..." name="Preferences"/> <menu_item_call label="Araç çubuğu düğmeleri..." name="Toolbars"/> <menu_item_call label="Tüm denetimleri sakla" name="Hide UI"/> + <menu_item_check label="BÜG Aksesuarlarını Göster" name="Show HUD Attachments"/> <menu_item_call label="[APP_NAME]'den Çık" name="Quit"/> </menu> <menu label="İletişim Kur" name="Communicate"> @@ -37,6 +38,7 @@ <menu_item_call label="Arkadaşlar" name="My Friends"/> <menu_item_call label="Gruplar" name="My Groups"/> <menu_item_call label="Yakındaki kişiler" name="Active Speakers"/> + <menu_item_call label="Engelleme Listesi" name="Block List"/> </menu> <menu label="Dünya" name="World"> <menu_item_call label="Bu Yeri Yer İmlerine Ekle" name="Create Landmark Here"/> @@ -122,6 +124,11 @@ <menu_item_call label="Komut Dosyalarını Çalışıyor Olarak Ayarla" name="Set Scripts to Running"/> <menu_item_call label="Komut Dosyalarını Çalışmıyor Olarak Ayarla" name="Set Scripts to Not Running"/> </menu> + <menu label="Yol bulma" name="Pathfinding"> + <menu_item_call label="Bağlantı kümeleri..." name="pathfinding_linksets_menu_item"/> + <menu_item_call label="Karakterler..." name="pathfinding_characters_menu_item"/> + <menu_item_call label="Görüntüleme / test..." name="pathfinding_console_menu_item"/> + </menu> <menu label="Seçenklr." name="Options"> <menu_item_check label="Gelişmiş İzinleri Göster" name="DebugPermissions"/> <menu_item_check label="Sadece Nesnelerimi Seç" name="Select Only My Objects"/> @@ -172,7 +179,6 @@ <menu_item_check label="Parçacıkları Gizle" name="Hide Particles"/> <menu_item_check label="Seçilenleri Gizle" name="Hide Selected"/> <menu_item_check label="Saydamı Vurgula" name="Highlight Transparent"/> - <menu_item_check label="BÜG Aksesuarlarını Göster" name="Show HUD Attachments"/> <menu_item_check label="Fare Üzerinden Görünüm Artı İşaretini Göster" name="ShowCrosshairs"/> </menu> <menu label="İşleme Türleri" name="Rendering Types"> @@ -375,7 +381,6 @@ <menu_item_call label="Karakter Geometrisini Aç/Kapa" name="Toggle Character Geometry"/> <menu_item_call label="Test Erkeği" name="Test Male"/> <menu_item_call label="Test Dişisi" name="Test Female"/> - <menu_item_call label="PG'yi Aç/Kapa" name="Toggle PG"/> <menu_item_check label="Avatar Seçimine İzin Ver" name="Allow Select Avatar"/> </menu> <menu_item_call label="Parametreleri Varsayılana Zorla" name="Force Params to Default"/> diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml index 27f0deaf4a..488702f9ca 100644 --- a/indra/newview/skins/default/xui/tr/notifications.xml +++ b/indra/newview/skins/default/xui/tr/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -360,13 +366,19 @@ Avatarınızın Kullanıcı adını girmeniz gerekmektedir. [SECOND_LIFE]'a giriş yapmak için bir hesabınız olması gerekir. Şimdi bir hesap oluşturmak ister misiniz? <url name="url"> - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="Tekrar dene" yestext="Yeni bir hesap oluştur"/> </notification> <notification name="InvalidCredentialFormat"> Kullanıcı adı alanına Avatarınızın Kullanıcı adını ya da Ad ve Soyadını girmeniz ve yeniden oturum açmanız gerekmektedir. </notification> + <notification name="InvalidGrid"> + '[GRID]' geçerli bir ağ tanımlayıcısı değil. + </notification> + <notification name="InvalidLocationSLURL"> + Başlangıç konumunuz için geçerli bir ağ belirtilmedi. + </notification> <notification name="DeleteClassified"> '[NAME]' ilanı silinsin mi? Ödenen ücretler iade edilmeyecektir. @@ -472,8 +484,8 @@ Nesne aralık dışında ya da silinmiş olabilir. Aşağıdaki nedenden dolayı, derlenen komut dosyası kaydedilirken bir sorun oluştu: [REASON]. Lütfen komut dosyasını kaydetmeyi daha sonra tekrar deneyin. </notification> <notification name="StartRegionEmpty"> - Hata. Başlangıç Bölgeniz tanımlanmamış. -Lütfen Başlangıç Konumu kutusuna Bölge adını yazın ya da Son Konumum veya Ana Konumumu Başlangıç Konumu olarak seçin. + Başlangıç Bölgeniz tanımlanmamış. +Lütfen Başlangıç Konumu kutusuna Bölge adını yazın ya da Son Bulunduğum Konum veya Ana Konumumu Başlangıç Konumu olarak seçin. <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification name="CouldNotStartStopScript"> @@ -600,6 +612,9 @@ En fazla [MAX] nesneyi birbirine bağlayabilirsiniz. Lütfen hiçbirinin kilitli olmadığından ve hepsine sahip olduğunuzdan emin olun. </notification> + <notification name="CannotLinkPermanent"> + Nesneler bölge sınırları üzerinden bağlantılandırılamaz. + </notification> <notification name="CannotLinkDifferentOwners"> Nesnelerin hepsinin sahibi aynı olmadığı için nesneler birbirine bağlanamıyor. @@ -978,6 +993,41 @@ Etkin grubunuz adına arazi satın almak için gerekli izne sahip değilsiniz. <button name="Cancel" text="İptal"/> </form> </notification> + <notification label="Otomatik Yerine Koyma Listesine Ekle" name="AddAutoReplaceList"> + Yeni liste için isim: + <form name="form"> + <button name="SetName" text="Tamam"/> + </form> + </notification> + <notification label="Otomatik Yerine Koyma Listesinin Adını Değiştir" name="RenameAutoReplaceList"> + '[DUPNAME]' adı kullanılıyor + Benzersiz yeni bir ad girin: + <form name="form"> + <button name="ReplaceList" text="Mevcut Listenin Yerine Koy"/> + <button name="SetName" text="Yeni Adı Kullan"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + Anahtar kelime tek bir kelime olmalıdır; değiştirme boş olamaz. + </notification> + <notification name="InvalidAutoReplaceList"> + Bu değiştirme listesi geçerli değil. + </notification> + <notification name="SpellingDictImportRequired"> + Bir dosya, ad ve dil belirtmelisiniz. + </notification> + <notification name="SpellingDictIsSecondary"> + [DIC_NAME] sözlüğünde bir "aff" dosyası yok gibi görünüyor; bu da "ikincil" bir sözlük olduğu anlamına gelir. +İlave bir sözlük olarak kullanılabilir; ancak Ana sözlüğünüz olarak kullanılamaz. + +Bkz. https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + Şu kopyalama yapılamıyor: + [FROM_NAME] + kaynağından şuraya: + [TO_NAME] + </notification> <notification label="Dış Görünümü Kaydet" name="SaveOutfitAs"> Üzerimdekileri yeni bir Dış Görünüm olarak kaydet: <form name="form"> @@ -1157,7 +1207,7 @@ sonraki: '[THIS_GPU]' Yakınındaki başka bir bölgeye taşındınız. </notification> <notification name="AvatarMovedLast"> - Son konumunuz şu anda kullanılamıyor. + Talep ettiğiniz konum şu anda kullanılamıyor. Yakınındaki başka bir bölgeye taşındınız. </notification> <notification name="AvatarMovedHome"> @@ -1173,11 +1223,10 @@ Yeni bir ana konum ayarlamak isteyebilirsiniz. </form> </notification> <notification name="FirstRun"> - [APP_NAME] kurulumu tamamlandı. + [APP_NAME] yüklemesi tamamlandı. [SECOND_LIFE]'ı ilk kez kullanıyorsanız, oturum açmadan önce bir hesap oluşturmalısınız. -Yeni bir hesap oluşturmak için [http://join.secondlife.com secondlife.com] adresine dönülsün mü? - <usetemplate name="okcancelbuttons" notext="Devam" yestext="Yeni Hesap..."/> + <usetemplate name="okcancelbuttons" notext="Devam" yestext="Hesap Oluştur..."/> </notification> <notification name="LoginPacketNeverReceived"> Bağlantıda sorun yaşıyoruz. İnternet bağlantınızda ya da [SECOND_LIFE_GRID] uygulamasında bir problem olabilir. @@ -1694,83 +1743,128 @@ Binlerce bölgeyi değiştirecek ve alan sunucusunu kesintiye uğratacaktır. <usetemplate name="okcancelbuttons" notext="İptal" yestext="Tamam"/> </notification> <notification name="RegionEntryAccessBlocked"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu Bölgeye giremezsiniz. Bu sorun yaşınızı doğrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir. - -Lütfen en son Görüntüleyicinin yüklü olduğunu doğrulayın ve bu erişkinlik seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'nı ziyaret edin. + Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aşan içeriğe sahip. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu bölgeye giremezsiniz. - -Erişkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası'nı ziyaret etmek ister misiniz? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Erişkinlik Seviyesi ile ilgili kısıtlamalardan dolayı bu Bölgeye giremiyorum" name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + <usetemplate ignoretext="Bölge geçişi: Ziyaret etmeye çalıştığınız bölge, sadece yetişkinlerin erişebileceği içeriğe sahip." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu bölgeye giremezsiniz. + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir. </notification> <notification name="RegionEntryAccessBlocked_Change"> - Erişkinlik Seviyesi tercihlerinizden dolayı bu Bölgeye giremezsiniz. - -İstenilen bölgeye girmek için, lütfen erişkinlik Seviyesi tercihinizi değiştirin. Bu tercih [REGIONMATURITY] içerikli alanlar içinde arama yapabilmenizi ve bu alanlara erişebilmenizi sağlayacak. Değişiklikleri geri almak için, Ben > Tercihler > Genel sekmesine gidin. + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz veya iptal edebilirsiniz. Tercihleriniz değiştikten sonra bölgeye tekrar girmeye çalışabilirsiniz. + <form name="form"> + <button name="OK" text="Tercihleri değiştirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Bölge geçişi: Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/> + </form> + </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + Tercihleriniz ile sunucu arasında senkronizasyon eksikliği olduğu için ışınlama işleminizde teknik sorunlar yaşanıyoruz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aşan içeriğe sahip. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir. + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="Işınla: Ziyaret etmeye çalıştığınız bölge, sadece yetişkinlerin erişebileceği içeriğe sahip." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir. + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz ve ışınlamaya devam edebilirsiniz veya bu ışınlama işlemini iptal edebilirsiniz. <form name="form"> - <button name="OK" text="Tercihi Değiştir"/> - <button name="Cancel" text="Kapat"/> - <ignore name="ignore" text="Seçtiğim Seviye tercihleri bir bölgeye girmemi engelliyor"/> + <button name="OK" text="Değiştir ve devam et"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Işınlama (yeniden başlatılabilir): Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/> </form> </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz veya ışınlamayı iptal edebilirsiniz. Tercihleriniz değiştikten sonra ışınlamayı tekrar yapmaya kalkışmanız gerekecek. + <form name="form"> + <button name="OK" text="Tercihleri değiştirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Işınlama (yeniden başlatılamaz): Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + Tercihleriniz ile sunucu arasında senkronizasyon eksikliği olduğu için ışınlama işleminizde teknik sorunlar yaşanıyoruz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="PreferredMaturityChanged"> - Erişkinlik Seviyesi tercihiniz artık [RATING]. + [RATING] içeriğine sahip bir bölgeyi ziyaret edeceğiniz hakkında başka bildirim almayacaksınız. Daha sonra menü çubuğunda Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> + <notification name="MaturityChangeError"> + Şu anda [PREFERRED_MATURITY] içeriğini görüntüleyecek şekilde tercihlerinizi değiştiremedik. Tercihleriniz, [ACTUAL_MATURITY] içeriğini görüntüleyecek şekilde sıfırlandı. Menü çubuğunda Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi tekrar değiştirmeyi deneyebilirsiniz. + <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification name="LandClaimAccessBlocked"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız. Bu sorun yaşınızı doğrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir. - -Lütfen en son Görüntüleyicinin yüklü olduğunu doğrulayın ve bu erişkinlik seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'nı ziyaret edin. + Hak talebinde bulunduğunuz arazinin erişkinlik seviyesi mevcut tercihlerinizi aşıyor. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız. - -Erişkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası'nı ziyaret etmek ister misiniz? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + Bu arazi üzerinde sadece yetişkinler hak talebinde bulunabilir. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Erişkinlik Seviyesi ile ilgili kısıtlandırmalardan dolayı bu Arazi üzerinde hak talebinde bulunamıyorum." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + <usetemplate ignoretext="Bu arazi üzerinde sadece yetişkinler hak talebinde bulunabilir." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız. + Hak talebinde bulunduğunuz arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + Hak talebinde bulunduğunuz arazi [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir. </notification> <notification name="LandClaimAccessBlocked_Change"> - Erişkinlik Seviyesi tercihinizden dolayı bu arazi üzerinde hak talebinde bulunamazsınız. - -Erişkinlik Seviyesi tercihinizi şimdi yükseltmek ve araziye girebilmek için 'Tercihi Değiştir' seçeneğini tıklatabilirsiniz. Böylece [REGIONMATURITY] içerikli alanlar içinde arama yapabilecek ve bu alanlara erişebileceksiniz. İleride bu ayarı eski haline döndürmek isterseniz, Ben > Tercihler > Genel sekmesine gidin. - <usetemplate ignoretext="Seçtiğim Seviye tercihi Arazi üzerinde hak talebinde bulunmamı engelliyor" name="okcancelignore" notext="Kapat" yestext="Tercihi Değiştir"/> + Hak talebinde bulunduğunuz arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz, sonra arazi üzerinde tekar hak talebinde bulunabilirsiniz. + <form name="form"> + <button name="OK" text="Tercihleri değiştirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Hak talebinde bulunduğunuz arazi, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız. Bu sorun yaşınızı doğrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir. - -Lütfen en son Görüntüleyicinin yüklü olduğunu doğrulayın ve bu erişkinlik seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'nı ziyaret edin. + Satın almaya çalıştığınız arazinin erişkinlik seviyesi mevcut tercihlerinizi aşıyor. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz. <usetemplate name="okbutton" yestext="Tamam"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız. - -Erişkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası'nı ziyaret etmek ister misiniz? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + Bu araziyi sadece yetişkinler satın alabilir. <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="Erişkinlik Seviyesi ile ilgili kısıtlandırmalardan dolayı bu Araziyi satın alamıyorum" name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> + <usetemplate ignoretext="Bu araziyi sadece yetişkinler satın alabilir." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası'na Git"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız. + Satın almaya çalıştığınız arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + Ziyaret etmeye çalıştığınız arazi [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir. </notification> <notification name="LandBuyAccessBlocked_Change"> - Erişkinlik Seviyesi tercihinizden dolayı bu araziyi satın alamazsınız. - -Erişkinlik Seviyesi tercihinizi şimdi yükseltmek ve araziye girebilmek için 'Tercihi Değiştir' seçeneğini tıklatabilirsiniz. Böylece [REGIONMATURITY] içerikli alanlar içinde arama yapabilecek ve bu alanlara erişebileceksiniz. İleride bu ayarı eski haline döndürmek isterseniz, Ben > Tercihler > Genel sekmesine gidin. - <usetemplate ignoretext="Seçtiğim Seviye tercihi Araziyi satın almamı engelliyor" name="okcancelignore" notext="Kapat" yestext="Tercihi Değiştir"/> + Satın almaya çalıştığınız arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz, sonra araziyi tekrar satın almaya çalışabilirsiniz. + <form name="form"> + <button name="OK" text="Tercihleri değiştirin"/> + <button name="Cancel" text="İptal"/> + <ignore name="ignore" text="Satın almaya çalıştığınız arazi, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/> + </form> </notification> <notification name="TooManyPrimsSelected"> Çok fazla prim seçilmiş. Lütfen [MAX_PRIM_COUNT] ya da daha az prim seçin ve tekrar deneyin @@ -1824,10 +1918,9 @@ Erişkinlik Seviyesi tercihinizi şimdi yükseltmek ve araziye girebilmek için </form> </notification> <notification label="Bölgenin Erişkinlik Seviyesi Değişti" name="RegionMaturityChange"> - Bu bölgenin erişkinlik seviyesi güncellendi. -Değişikliğin harita üzerine yansıtılması biraz zaman alabilir. - -Yetişkin bölgelerine girebilmek için, Sakinlerin yaş doğrulama ya da ödeme doğrulama yoluyla Doğrulanmış bir Hesaba sahip olmaları gerekmektedir. + Bu bölgenin yetişkin içerik seviyesi değişti. +Bu değişikliğin harita üzerine yansıtılması biraz zaman alabilir. + <usetemplate name="okbutton" yestext="Tamam"/> </notification> <notification label="Sesli Sohbet Sürüm Uyumsuzluğu" name="VoiceVersionMismatch"> [APP_NAME] uygulamasının bu sürümü bu bölgedeki Sesli Sohbet özelliği ile uyumlu değil. Sesli Sohbet özelliğinin düzgün bir şekilde çalışabilmesi için [APP_NAME] uygulamasını güncellemeniz gerekiyor. @@ -2117,14 +2210,11 @@ Diğer kişilerin bu konuma kolayca erişmesini sağlamak için bu adrese bir we <usetemplate ignoretext="Görünümümü düzenlerken oluşturduğum giysiyi giy" name="okcancelignore" notext="Hayır" yestext="Evet"/> </notification> <notification name="NotAgeVerified"> - Second Life içinde yetişkinlere yönelik içeriğe ve bölgelere erişmek için en az 18 yaşında olmalısınız. 18 yaşından büyük olduğunuzu onaylamak için lütfen yaş doğrulama sayfamızı ziyaret edin. -Bu adımda web tarayıcınızın başlatılacağına dikkat edin. - -[_URL] - <url name="url"> - https://secondlife.com/my/account/verification.php - </url> - <usetemplate ignoretext="Yaşımı doğrulatmadım" name="okcancelignore" notext="İptal" yestext="Yaş Doğrulamasına Git"/> + Ziyaret etmeye çalıştığınız konum, yaşı 18 ve üzeri olan sakinlere kısıtlanmıştır. + <usetemplate ignoretext="Yaş kısıtı olan alanları ziyaret etmek için yaşım yeterli değil." name="okignore" yestext="Tamam"/> + </notification> + <notification name="NotAgeVerified_Notify"> + Konum, 18 veya üzeri bir yaşta olanlara kısıtlanmıştır. </notification> <notification name="Cannot enter parcel: no payment info on file"> Bu alanı ziyaret edebilmek için ödeme bilgilerinizin kayıtlı olması gerekir. [SECOND_LIFE] web sitesine gitmek ve bunu ayarlamak istiyor musunuz? @@ -2185,7 +2275,7 @@ Bu adımda web tarayıcınızın başlatılacağına dikkat edin. Terrain.raw karşıdan yüklendi </notification> <notification name="GestureMissing"> - Hmm. [NAME] mimiği veri tabanında yok. + [NAME] mimiği veri tabanında yok. </notification> <notification name="UnableToLoadGesture"> [NAME] mimiği karşıya yüklenemiyor. @@ -2386,6 +2476,23 @@ Burada uçamazsınız. <notification name="NoBuild"> Bu alanda inşa etme özelliği devre dışı. Burada nesne inşa edemez ve oluşturamazsınız. </notification> + <notification name="PathfindingDirty"> + Bu bölgede bekleyen yol bulma değişiklikleri var. Eğer oluşturma haklarına sahipseniz, “Bölgeyi yeniden kaydet” düğmesine tıklayarak bölgeyi yeniden kaydedebilirsiniz. + </notification> + <notification name="DynamicPathfindingDisabled"> + Bu bölgede dinamik yol bulma etkin değil. Yol bulma LSL çağrılarını kullanan komut dosyalı nesneler, bu bölgede beklendiiği gibi çalışmayabilir. + </notification> + <notification name="PathfindingRebakeNavmesh"> + Bu bölgede belirli diğer nesneleri değiştirmek, hareket eden başka nesnelerin yanlış davranmasına neden olabilir. Hareket eden başka nesnelerin doğru davranmasını sağlamak için “Bölgeyi yeniden kaydet” düğmesine tıklayın. Daha fazla bilgi edinmek için “Yardım” seçimini yapın. + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="Yardım" ignoretext="Bu bölgede belirli diğer nesneleri değiştirmek, hareket eden başka nesnelerin yanlış davranmasına neden olabilir." name="okhelpignore" yestext="Tamam"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + Bir hata meydana geldi. Bir ağ veya sunucu sorunu olabilir ya da oluşturma haklarına sahip olmayabilirsiniz. Bazen oturumu kapatıp, tekrar açmak bu sorunu çözer. + <usetemplate name="okbutton" yestext="Tamam"/> + </notification> <notification name="SeeAvatars"> Bu parsel, avatarları ve metin sohbetini başka bir parselden saklar. Parselin dışındaki diğer sakinleri göremezsiniz, dışardakiler de sizi göremez. 0. kanaldaki normal metin sohbeti de engellenmiştir. </notification> @@ -2404,9 +2511,7 @@ Arazi sahibine ait olanlar dışında hiçbir komut dosyası çalışmayacak. İçinde bulunduğunuz Bölgede sadece kamuya ait araziler üzerinde hak talebinde bulunabilirsiniz. </notification> <notification name="RegionTPAccessBlocked"> - Erişkinlik Seviyesi ayarlarınızdan dolayı bu Bölgeye giremezsiniz. Yaşınızı doğrulatmanız ve/veya en son Görüntüleyici'yi yüklemeniz gerekebilir. - -Lütfen bu erişkinlik Seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası'na gidin. + Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aşan içeriğe sahip. Ben > Tercihler > Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz. </notification> <notification name="URBannedFromRegion"> Bu bölgeye erişiminiz yasaklandı. @@ -2417,11 +2522,11 @@ Lütfen bu erişkinlik Seviyesi ile erişilecek alanlar hakkında ayrıntılı b <notification name="ImproperPaymentStatus"> Bu bölgeye girmek için gerekli ödeme durumuna sahip değilsiniz. </notification> - <notification name="MustGetAgeRgion"> - Bu bölgeye girebilmek için yaş doğrulamanızın yapılmış olması gerekir. + <notification name="MustGetAgeRegion"> + Bu bölgeye girebilmek için 18 veya üzeri bir yaşta olmanız gerekir. </notification> <notification name="MustGetAgeParcel"> - Bu parsele girebilmek için yaş doğrulamanızın yapılmış olması gerekir. + Bu parsele girebilmek için 18 veya üzeri bir yaşta olmanız gerekir. </notification> <notification name="NoDestRegion"> Seçili hedef bölge yok. @@ -2523,12 +2628,33 @@ Lütfen biraz sonra tekrar deneyin. <notification name="TeleportOffered"> [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="Işınla"/> <button name="Cancel" text="İptal"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Bu bölgede [REGION_CONTENT_MATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGION_CONTENT_MATURITY] içeriğini dışlayacak şekilde ayarlanmış durumda. Tercihlerinizi değiştirebilirsiniz ve ışınlamaya devam edebilirsiniz veya bu ışınlama işlemini iptal edebilirsiniz. + <form name="form"> + <button name="Teleport" text="Değiştir ve Devam Et"/> + <button name="Cancel" text="İptal"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +Ancak bu bölge sadece yetişkinlerin erişebileceği içeriğe sahip. + </notification> <notification name="TeleportOfferSent"> Işınlanma teklifi [TO_NAME] adlı kişiye gönderildi </notification> @@ -2932,6 +3058,10 @@ Lütfen ağ ve güvenlik duvarı ayarlarınızı kontrol edin. ( [EXISTENCE] saniyedir hayatta ) '[BODYREGION]' için [RESOLUTION] çözünürlükte kaydedilmiş bir dokuyu [TIME] saniye sonra yerel olarak güncellediniz. </notification> + <notification name="LivePreviewUnavailable"> + Kopyalanamaz ve/veya aktarılamaz olduğu için bu dokunun bir önizlemesini görüntüleyemiyoruz. + <usetemplate ignoretext="Kopyalanamayan ve/veya aktarılamayan dokular için Canlı Önizleme modu mevcut olmayınca beni uyar" name="okignore" yestext="Tamam"/> + </notification> <notification name="ConfirmLeaveCall"> Bu aramadan çıkmak istediğinize emin misiniz? <usetemplate ignoretext="Aramadan çıkmadan önce doğrulama iste" name="okcancelignore" notext="Hayır" yestext="Evet"/> @@ -3103,6 +3233,62 @@ Görünümünüzü döndürmek için dünya üzerindeki herhangi bir yeri tıkla Bu eylem tüm menü öğelerini ve düğmelerini gizler. Bunları geri almak için [SHORTCUT] üzerine tekrar tıklayın. <usetemplate ignoretext="KA'ni gizlemeden önce onayla" name="okcancelignore" notext="İptal" yestext="Tamam"/> </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + Seçilen bazı bağlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü şekil konveks değil. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Seçilen bazı bağlantı kümeleri ayarlanamaz, çünkü şekil konveks değil." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek, diğerleri ise bağlantı kümesi için izin kısıtlamaları nedeniyle ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Seçilen bazı bağlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü şekil konveks değil. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek, diğerleri ise şekil konveks olmadığı için ayarlanamıyor" name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Seçilen bazı bağlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü şekil konveks değil. Bu bağlantı kümelerinin kullanım tipleri değişmez. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle ve şekil konveks olmadığı için ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek. + +Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle '[REQUESTED_TYPE]' olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri '[RESTRICTED_TYPE]' olarak ayarlanacak. + +Seçilen bazı bağlantı kümeleri '[REQUESTED_TYPE]' olarak ayarlanamaz, çünkü şekil konveks değil. Bu bağlantı kümelerinin kullanım tipleri değişmez. + +Devam etmek istiyor musunuz? + <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek, diğerleri ise bağlantı kümesi için izin kısıtlamaları nedeniyle ve şekil konveks olmadığı için ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + Seçilen nesne navigasyon örgüsünü etkiliyor. Bunu bir Esnek Yol olarak değiştirirseniz, navigasyon örgüsünden çıkartmış olursunuz. + <usetemplate ignoretext="Seçilen nesne navigasyon örgüsünü etkiliyor. Bunu bir Esnek Yol olarak değiştirirseniz, navigasyon örgüsünden çıkartmış olursunuz." name="okcancelignore" notext="İptal" yestext="Tamam"/> + </notification> <global name="UnsupportedGLRequirements"> [APP_NAME] uygulaması için gerekli donanım gereksinimlerine sahip olmadığınız görünüyor. [APP_NAME] çoklu doku desteği sunan bir OpenGL grafik kartı gerektiriyor. Eğer grafik kartınız bu özellikteyse, grafik kartınızın en son sürücülerine ve işletim sisteminiz için gerekli Service Pack ve yamalara sahip olup olmadığınızı kontrol etmeyi deneyebilirsiniz. @@ -3139,4 +3325,12 @@ Bundan sonra bu dosya için güncellemeler devre dışı bırakılacak. Geçersiz veya okunamayan bir görüntü dosyası [FNAME] eklenmeye kalkışıldı, ancak dosya açılamadı veya şifresi çözülemedi. Girişim iptal edildi. </notification> + <notification name="PathfindingReturnMultipleItems"> + [NUM_ITEMS] öğeyi iade ediyorsunuz. Devam etmek istediğinize emin misiniz? + <usetemplate ignoretext="Birden çok öğeyi iade etmek istediğinize emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + [NUM_ITEMS] öğeyi siliyorsunuz. Devam etmek istediğinize emin misiniz? + <usetemplate ignoretext="Birden çok öğeyi silmek istediğinize emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/tr/panel_bottomtray.xml b/indra/newview/skins/default/xui/tr/panel_bottomtray.xml deleted file mode 100644 index 26118d8b39..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Mikrofonu açar/kapatır"/> - <string name="VoiceControlBtnToolTip" value="Ses kontrol panelini gösterir/gizler"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Konuş" label_selected="Konuş" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="Mimik" name="Gesture" tool_tip="Mimikleri gösterir/gizler"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="Hareket Et" name="movement_btn" tool_tip="Hareket kontrollerini gösterir/gizler"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="Görünüm" name="camera_btn" tool_tip="Kamera kontrollerini gösterir/gizler"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button name="snapshots" tool_tip="Anlık görüntü al"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="İnşa Et" name="build_btn" tool_tip="İnşa Et Aracını gösterir/gizler"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="Ara" name="search_btn" tool_tip="Aramayı gösterir/gizler"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="Harita" name="world_map_btn" tool_tip="Dünya Haritasını gösterir/gizler"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="Mini-Harita" name="mini_map_btn" tool_tip="Mini Haritayı gösterir/gizler"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Sohbetler"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="Bildirimler"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_group_invite.xml b/indra/newview/skins/default/xui/tr/panel_group_invite.xml index 9b0c7f799a..4ba5761edb 100644 --- a/indra/newview/skins/default/xui/tr/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/tr/panel_group_invite.xml @@ -9,6 +9,9 @@ <panel.string name="already_in_group"> Seçtiğiniz bazı Sakinler zaten grupta yer alıyor, bu yüzden bunlara davetiye gönderilmedi. </panel.string> + <panel.string name="invite_selection_too_large"> + Gönderilmeyen Grup Davetiyeleri: Çok fazla Sakin seçilmiş. Grup Davetiyelerinde talep başına 100 sınırı vardır. + </panel.string> <text name="help_text"> Grubunuza davet etmek için birden fazla Sakin seçebilirsiniz. Başlamak için "Sakin Seçiciyi Aç" üzerine tıklayın. </text> diff --git a/indra/newview/skins/default/xui/tr/panel_login.xml b/indra/newview/skins/default/xui/tr/panel_login.xml index acd6aa1921..28d316e46b 100644 --- a/indra/newview/skins/default/xui/tr/panel_login.xml +++ b/indra/newview/skins/default/xui/tr/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + OTURUM AÇ + </text> <text name="username_text"> Kullanıcı Adı: </text> @@ -15,15 +15,8 @@ <text name="password_text"> Parola: </text> - <check_box label="Parolayı hatırla" name="remember_check"/> - <button label="Oturum Aç" name="connect_btn"/> - <text name="mode_selection_text"> - Mod: - </text> - <combo_box name="mode_combo" tool_tip="Modunuzu seçin. Hızlı, kolay keşif yapmak ve sohbet için Temel seçimini yapın. Daha fazla özelliğe erişmek için Gelişmiş seçimini yapın."> - <combo_box.item label="Temel" name="Basic"/> - <combo_box.item label="Gelişmiş" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> Buradan başla: </text> @@ -33,16 +26,21 @@ <combo_box.item label="<Bölge adını girin>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - Kaydolun + <layout_panel name="links_login_panel"> + <text name="login_help"> + Oturum açarken yardım mı gerekiyor? </text> <text name="forgot_password_text"> Kullanıcı adınızı veya parolanızı mı unuttunuz? </text> - <text name="login_help"> - Oturum açarken yardım mı gerekiyor? + <button label="Oturum Aç" name="connect_btn"/> + <check_box label="Parolayı hatırla" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + HESABINIZI OLUŞTURUN </text> + <button label="Şimdi başla" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/tr/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..78cb8bcc02 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="Bölgeyi yeniden kaydet" name="navmesh_btn" tool_tip="Bölgenin navigasyon örgüsünü tekrar kaydetmek için tıkla."/> + <button label="Yeniden kaydetme talep ediliyor" name="navmesh_btn_sending" tool_tip="Yeniden kaydetme talebi sunucuya gönderiliyor."/> + <button label="Bölge yeniden kaydediliyor" name="navmesh_btn_baking" tool_tip="Bölge yeniden kaydediliyor. Tamamlandığında bu düğme kaybolacak."/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml index 9caf95a122..231e8fc5fe 100644 --- a/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml @@ -29,5 +29,7 @@ <check_box label="Aİ Sohbetleri" name="EnableIMChatPopups" tool_tip="Bir anlık ileti geldiğinde açılır pencereleri görmek için işaretle"/> <spinner label="Yakındaki sohbet iletilerinin vurgulanma süresi:" name="nearby_toasts_lifetime"/> <spinner label="Yakındaki sohbet iletilerinin sönme süresi:" name="nearby_toasts_fadingtime"/> - <button label="Sohbet Çevirisi Ayarları" name="ok_btn"/> + <button label="Çeviri..." name="ok_btn"/> + <button label="Otomatik Yerine Koy..." name="autoreplace_showgui"/> + <button label="Yazım Denetimi Yapılıyor..." name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_region_debug.xml b/indra/newview/skins/default/xui/tr/panel_region_debug.xml index 6e15e0f6f6..834ece563f 100644 --- a/indra/newview/skins/default/xui/tr/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/tr/panel_region_debug.xml @@ -30,5 +30,5 @@ <button label="En Çok Çarpışanlar..." name="top_colliders_btn" tool_tip="En çok potansiyel çarpışma yaşayan nesnelerin listesi"/> <button label="En Çok Komut Dsy. Çalştr...." name="top_scripts_btn" tool_tip="Komut dosyalarını çalıştırırken en çok zaman harcayan nesnelerin listesi"/> <button label="Bölgeyi Yeniden Başlat" name="restart_btn" tool_tip="2 dakikalık bir geri sayımdan sonra bölgeyi yeniden başlat"/> - <button label="Yeniden Başlatmayı Ertele" name="cancel_restart_btn" tool_tip="Bölgenin yeniden başlatılmasını 1 saat ertele"/> + <button label="Yeniden Başlatmayı İptal Et" name="cancel_restart_btn" tool_tip="Bölge yeniden başlatmasını iptal et"/> </panel> diff --git a/indra/newview/skins/default/xui/tr/panel_region_estate.xml b/indra/newview/skins/default/xui/tr/panel_region_estate.xml index f1df13df61..4a9028643f 100644 --- a/indra/newview/skins/default/xui/tr/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/tr/panel_region_estate.xml @@ -23,7 +23,7 @@ Sadece şu Sakinlere erişim izni verin: </text> <check_box label="Ödeme bilgileri kayıtlı" name="limit_payment" tool_tip="Sakinlerin bu gayrimenkule erişebilmesi için ödeme bilgilerinin kayıtlı olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> - <check_box label="Yaş doğrulaması yapılmış" name="limit_age_verified" tool_tip="Sakinlerin bu gayrimenkule erişebilmesi için yaş doğrulamalarının yapılmış olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> + <check_box label="18 veya üzeri bir yaşta" name="limit_age_verified" tool_tip="Sakinlerin bu gayrimenkule erişebilmesi için 18 veya üzeri bir yaşta olmaları gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/> <check_box label="Sesli Sohbete İzin Ver" name="voice_chat_check"/> <check_box label="Doğrudan Işınlamaya İzin Ver" name="allow_direct_teleport"/> <button label="Uygula" name="apply_btn"/> diff --git a/indra/newview/skins/default/xui/tr/panel_region_texture.xml b/indra/newview/skins/default/xui/tr/panel_region_texture.xml deleted file mode 100644 index fd7ca2a893..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_region_texture.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Zemin Dokuları" name="Textures"> - <text name="region_text_lbl"> - Bölge: - </text> - <text name="region_text"> - bilinmiyor - </text> - <text name="detail_texture_text"> - Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir) - </text> - <text name="height_text_lbl"> - 1 (Düşük) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (Yüksek) - </text> - <text name="height_text_lbl5"> - Doku Yükselti Aralıkları - </text> - <text name="height_text_lbl6"> - Kuzeybatı - </text> - <text name="height_text_lbl7"> - Kuzeydoğu - </text> - <spinner label="Düşük" name="height_start_spin_1"/> - <spinner label="Düşük" name="height_start_spin_3"/> - <spinner label="Yüksek" name="height_range_spin_1"/> - <spinner label="Yüksek" name="height_range_spin_3"/> - <text name="height_text_lbl8"> - Güneybatı - </text> - <text name="height_text_lbl9"> - Güneydoğu - </text> - <spinner label="Düşük" name="height_start_spin_0"/> - <spinner label="Düşük" name="height_start_spin_2"/> - <spinner label="Yüksek" name="height_range_spin_0"/> - <spinner label="Yüksek" name="height_range_spin_2"/> - <text name="height_text_lbl10"> - Bu değerler yukarıdaki dokular için karışım aralığını temsil eder. - </text> - <text name="height_text_lbl11"> - Metre cinsinden olan bu değerler için, DÜŞÜK değer 1. Dokunun MAKSİMUM yüksekliği, YÜKSEK değer ise 4. Dokunun MİNİMUM yüksekliğidir. - </text> - <button label="Uygula" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_side_tray.xml b/indra/newview/skins/default/xui/tr/panel_side_tray.xml deleted file mode 100644 index 97bca38a50..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="Yan Çubuğu Aç/Kapa." name="sidebar_openclose" tab_title="Yan Çubuğu Aç/Kapa"/> - <sidetray_tab description="Ana konum." name="sidebar_home" tab_title="Ana konum"> - <panel label="ana konum" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="Kamuya açık profilinizi ve Favorilerinizi düzenleyin." name="sidebar_me" tab_title="Profilim"> - <panel_container name="panel_container"> - <panel label="Ben" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Yakındaki arkadaşlarınızı, irtibatları ve kişileri bulun." name="sidebar_people" tab_title="Kişiler"> - <panel_container name="panel_container"> - <panel label="Grup Profili" name="panel_group_info_sidetray"/> - <panel label="Engellenmiş Sakinler ve Nesneler" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Gitmek istediğiniz yerleri ve daha önce uğradığınız yerleri bulun." label="Yerler" name="sidebar_places" tab_title="Yerler"> - <panel label="Yerler" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="Envanterinize göz atın." name="sidebar_inventory" tab_title="Envanterim"> - <panel label="Envanteri Düzenle" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="Görünümünüzü değiştirin." name="sidebar_appearance" tab_title="Görünümüm"> - <panel label="Görünümü Düzenle" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml new file mode 100644 index 0000000000..0c8c7b68b5 --- /dev/null +++ b/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="Ana" name="System Volume"/> + <slider label="Düğmeler" name="UI Volume"/> + <slider label="Ortam" name="Wind Volume"/> + <slider label="Sesler" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="Mimiklerdeki sesleri etkinleştir"/> + <slider label="Müzik" name="Music Volume"/> + <check_box name="enable_music" tool_tip="Müzik Akışını Etkinleştir"/> + <slider label="Ortam" name="Media Volume"/> + <check_box name="enable_media" tool_tip="Akış Ortamını Etkinleştir"/> + <slider label="Ses" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="Sesli Sohbeti Etkinleştir"/> +</panel> diff --git a/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml index 81291a431c..86b684c497 100644 --- a/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (bilinmiyor) </panel.string> + <panel.string name="unknown_multiple"> + (bilinmiyor veya birden çok değer) + </panel.string> <panel.string name="public"> (kamuya açık) </panel.string> diff --git a/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml b/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml index 2fa6281f05..b0b9ab7716 100644 --- a/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml @@ -18,6 +18,12 @@ <panel.string name="text modify info 4"> Bu nesneleri değiştiremezsiniz </panel.string> + <panel.string name="text modify info 5"> + Bir bölge sınırı üzerinden bu nesneyi değiştiremezsiniz + </panel.string> + <panel.string name="text modify info 6"> + Bir bölge sınırı üzerinden bu nesneleri değiştiremezsiniz + </panel.string> <panel.string name="text modify warning"> Bu nesne bağlantılı parçalara sahip </panel.string> @@ -95,6 +101,9 @@ </combo_box> <spinner label="Fiyat: L$" name="Edit Cost"/> <check_box label="Aramada göster" name="search_check" tool_tip="Kişiler arama sonuçlarında bu nesneyi görebilsin"/> + <text name="pathfinding_attributes_label"> + Yol bulma özellikleri: + </text> <text name="B:"> B: </text> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index a8a691a98e..1be8f5974c 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -137,7 +137,7 @@ Çık </string> <string name="create_account_url"> - http://join.secondlife.com/ + http://join.secondlife.com/index.php?lang=tr-TR&sourceid=[sourceid] </string> <string name="LoginFailedViewerNotPermitted"> Kullandığınız görüntüleyici ile artık Second Life'a erişemezsiniz. Yeni bir görüntüleyiciyi karşıdan yüklemek için lütfen şu sayfayı ziyaret edin: @@ -1003,6 +1003,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="script_files"> Komut Dosyaları </string> + <string name="dictionary_files"> + Sözlükler + </string> <string name="AvatarSetNotAway"> Uzakta Değil </string> @@ -1408,6 +1411,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="InvFolder favorite"> Favorilerim </string> + <string name="InvFolder Favorites"> + Sık Kullanılanlarım + </string> + <string name="InvFolder favorites"> + Sık Kullanılanlarım + </string> <string name="InvFolder Current Outfit"> Mevcut Dış Görünüm </string> @@ -1423,6 +1432,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. <string name="InvFolder Meshes"> Örgüler </string> + <string name="InvFolder Received Items"> + Alınan Öğeler + </string> + <string name="InvFolder Merchant Outbox"> + Satıcı Giden Kutusu + </string> <string name="InvFolder Friends"> Arkadaşlar </string> @@ -3861,6 +3876,12 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. <string name="LocationCtrlSeeAVsTooltip"> Bu parselin dışında avatarlar görünür durumda ve sohbete izin veriliyor </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Bölge yeniden kaydedilinceye kadar hareket eden nesneler bu bölgede doğru davranmayabilir. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Bu bölgede dinamik yol bulma etkin değil. + </string> <string name="UpdaterWindowTitle"> [APP_NAME] Güncelleştirme </string> @@ -5013,6 +5034,21 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. <string name="Normal"> Normal </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Hiçbiri + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Navigasyon örgüsünü etkiler + </string> + <string name="Pathfinding_Object_Attr_Character"> + Karakter + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Birden çok) + </string> <string name="snapshot_quality_very_low"> Çok Düşük </string> @@ -5028,4 +5064,10 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. <string name="snapshot_quality_very_high"> Çok Yüksek </string> + <string name="TeleportMaturityExceeded"> + Sakin bu bölgeyi ziyaret edemez. + </string> + <string name="UserDictionary"> + [User] + </string> </strings> diff --git a/indra/newview/skins/default/xui/tr/teleport_strings.xml b/indra/newview/skins/default/xui/tr/teleport_strings.xml index 62aaaf671f..20d09b1ee2 100644 --- a/indra/newview/skins/default/xui/tr/teleport_strings.xml +++ b/indra/newview/skins/default/xui/tr/teleport_strings.xml @@ -45,6 +45,9 @@ Bir dakika sonra tekrar deneyin. <message name="no_inventory_host"> Envanter sistemi şu anda kullanılamıyor. </message> + <message name="MustGetAgeRegion"> + Bu bölgeye girebilmek için 18 veya üzeri bir yaşta olmanız gerekir. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ Bir dakika sonra tekrar deneyin. <message name="requesting"> Işınlanma talep ediliyor... </message> + <message name="pending"> + Işınlama Bekliyor... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/zh/floater_aaa.xml b/indra/newview/skins/default/xui/zh/floater_aaa.xml index 0d110c0456..e2d6a2b004 100644 --- a/indra/newview/skins/default/xui/zh/floater_aaa.xml +++ b/indra/newview/skins/default/xui/zh/floater_aaa.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Test Floater" title="測試浮動視窗"> <string name="test_the_vlt"> - This string CHANGE2 is extracted. + 字串 CHANGE2 已抽取。 </string> <string name="testing_eli"> 這只是測試 - 變更。 diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index 7e19c124a1..643881e416 100644 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -5,10 +5,10 @@ [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </floater.string> <floater.string name="AboutCompiler"> - Built with [COMPILER] version [COMPILER_VERSION] + 以 [COMPILER_VERSION] 版本 [COMPILER] 建置 </floater.string> <floater.string name="AboutPosition"> - You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) + 你的方位是 [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1],地區名:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </floater.string> @@ -20,10 +20,10 @@ 顯示卡:[GRAPHICS_CARD] </floater.string> <floater.string name="AboutDriver"> - Windows Graphics Driver Version: [GRAPHICS_DRIVER_VERSION] + Windows 顯示驅動程式版本:[GRAPHICS_DRIVER_VERSION] </floater.string> <floater.string name="AboutLibs"> - OpenGL Version: [OPENGL_VERSION] + OpenGL 版本:[OPENGL_VERSION] libcurl 版本: [LIBCURL_VERSION] J2C 解碼器版本: [J2C_VERSION] @@ -37,47 +37,60 @@ Qt Webkit 版本: [QT_WEBKIT_VERSION] <floater.string name="AboutTraffic"> 封包損失:[PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) </floater.string> + <floater.string name="ErrorFetchingServerReleaseNotesURL"> + 擷取伺服器版本說明 URL 時出錯。 + </floater.string> <tab_container name="about_tab"> <panel label="資訊" name="support_panel"> <button label="覆製到剪貼簿" name="copy_btn"/> </panel> - <panel label="Credits" name="credits_panel"> - <text_editor name="credits_editor"> - Second Life is brought to you by ..., and many others. - -Thank you to the following Residents for helping to ensure that this is the best version yet: ..., and many others. - - - - -"The work goes on, the cause endures, the hope still lives, and the dreams shall never die" - Edward Kennedy + <panel label="貸記" name="credits_panel"> + <text name="linden_intro"> + 「第二人生」由以下的 Linden 家族帶給你: + </text> + <text name="contrib_intro"> + 這些人士做了開放源碼的貢獻: + </text> + <text_editor name="contrib_names"> + 執行時期被取代的假名稱 + </text_editor> + <text name="trans_intro"> + 以下人士提供翻譯: + </text> + <text_editor name="trans_names"> + 執行時期被取代的假名稱 </text_editor> </panel> - <panel label="Licenses" name="licenses_panel"> + <panel label="許可" name="licenses_panel"> <text_editor name="credits_editor"> - 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion -APR Copyright (C) 2000-2004 The Apache Software Foundation -cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) -DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. -expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. -FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). -GL Copyright (C) 1999-2004 Brian Paul. -google-perftools Copyright (c) 2005, Google Inc. -Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. -jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) -jpeglib Copyright (C) 1991-1998, Thomas G. Lane. -ogg/vorbis Copyright (C) 2001, Xiphophorus -OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. -Pth Copyright (C) 1999-2006 Ralf S. Engelschall <rse@gnu.org> -SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga -SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -xmlrpc-epi Copyright (C) 2000 Epinions, Inc. -zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. -google-perftools Copyright (c) 2005, Google Inc. + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion + APR Copyright (C) 2011 The Apache Software Foundation + Collada DOM Copyright 2006 Sony Computer Entertainment Inc. + cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) + DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. + expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. + FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. + GL Copyright (C) 1999-2004 Brian Paul. + GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. + google-perftools Copyright (c) 2005, Google Inc. + Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. + jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) + jpeglib Copyright (C) 1991-1998, Thomas G. Lane. + ogg/vorbis Copyright (C) 2002, Xiphophorus + OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. + PCRE Copyright (c) 1997-2012 University of Cambridge + SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. + + 第二人生 Viewer 採用 Havok (TM) 物理引擎。 (c)Copyright 1999-2010 Havok.com Inc.(及其放照人)。 保留一切權利。 詳情見 www.havok.com。 + + 本軟體含有 NVIDIA Corporation 提供的源程式碼。 -All rights reserved. See licenses.txt for details. + 保留一切權利。 詳情見 licenses.txt。 -語音聊天音頻編碼:Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) + 語音聊天音頻技術:Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) </text_editor> </panel> </tab_container> diff --git a/indra/newview/skins/default/xui/zh/floater_about_land.xml b/indra/newview/skins/default/xui/zh/floater_about_land.xml index 2568d492f0..76db621951 100644 --- a/indra/newview/skins/default/xui/zh/floater_about_land.xml +++ b/indra/newview/skins/default/xui/zh/floater_about_land.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floaterland" title="關於土地"> +<floater name="floaterland" title="土地資料"> <floater.string name="maturity_icon_general"> "Parcel_PG_Dark" </floater.string> @@ -10,39 +10,39 @@ "Parcel_R_Dark" </floater.string> <floater.string name="Minutes"> - [MINUTES] minutes + [MINUTES] 分鐘 </floater.string> <floater.string name="Minute"> - minute + 分鐘 </floater.string> <floater.string name="Seconds"> - [SECONDS] seconds + [SECONDS] 秒 </floater.string> <floater.string name="Remaining"> - remaining + 剩餘時間 </floater.string> <tab_container name="landtab"> <panel label="一般" name="land_general_panel"> <panel.string name="new users only"> - New Residents only + 僅限新居民 </panel.string> <panel.string name="anyone"> - Anyone + 任何人 </panel.string> <panel.string name="area_text"> 區域 </panel.string> <panel.string name="area_size_text"> - [AREA] m² + [AREA] 平方公尺 </panel.string> <panel.string name="auction_id_text"> - Auction ID: [ID] + 拍賣 ID:[ID] </panel.string> <panel.string name="need_tier_to_modify"> - You must approve your purchase to modify this land. + 你必須批准購買才能修改這塊土地。 </panel.string> <panel.string name="group_owned_text"> - (群組所擁有) + (由群組所擁有) </panel.string> <panel.string name="profile_text"> 檔案 @@ -57,10 +57,10 @@ (無) </panel.string> <panel.string name="sale_pending_text"> - (Sale Pending) + (擱置銷售) </panel.string> <panel.string name="no_selection_text"> - No parcel selected. + 未選擇地段。 </panel.string> <panel.string name="time_stamp_template"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -75,7 +75,7 @@ 類型: </text> <text name="LandTypeText"> - Mainland / Homestead + 大陸 / 家園 </text> <text name="ContentRating"> 分級: @@ -84,37 +84,37 @@ 完全成人 </text> <text name="Owner:"> - 擁有者: + 所有人: </text> <text name="Group:"> 群組: </text> <button label="設定" name="Set..."/> - <check_box label="允許讓渡給群組" name="check deed" tool_tip="A group officer can deed this land to the group, so it will be supported by the group's land allocation."/> - <button label="讓渡" name="Deed..." tool_tip="You may only deed land if you are an officer in the selected group."/> - <check_box label="Owner Makes Contribution With Deed" name="check contrib" tool_tip="When the land is deeded to the group, the former owner contributes enough land allocation to support it."/> + <check_box label="允許讓渡給群組" name="check deed" tool_tip="群組工作人員可將這土地讓渡給群組,使其得到群組土地配置的支援。"/> + <button label="讓渡" name="Deed..." tool_tip="你必須是所選群組的工作人員才能讓渡土地。"/> + <check_box label="所有人透過讓渡動作進行捐獻" name="check contrib" tool_tip="將土地讓渡給群組,表示上一個所有人會捐獻足夠土地來支持讓渡。"/> <text name="For Sale:"> - 出售: + 出售中: </text> <text name="Not for sale."> 不出售 </text> <text name="For Sale: Price L$[PRICE]."> - Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + 價格:L$[PRICE] (L$[PRICE_PER_SQM]/平方公尺) </text> <button label="出售土地" name="Sell Land..."/> <text name="For sale to"> 出售給:[BUYER] </text> <text name="Sell with landowners objects in parcel."> - Objects included in sale + 物件連帶一起出售 </text> <text name="Selling with no objects in parcel."> - Objects not included in sale + 此次出售不含物件 </text> - <button label="Cancel Land Sale" label_selected="Cancel Land Sale" name="Cancel Land Sale"/> + <button label="取消土地出售" label_selected="取消土地出售" name="Cancel Land Sale"/> <text name="Claimed:"> - Claimed: + 已收取: </text> <text name="DateClaimText"> Tue Aug 15 13:47:25 2006 @@ -123,52 +123,52 @@ 面積: </text> <text name="PriceText"> - 4048 m² + 4048 平方公尺 </text> <text name="Traffic:"> 流量: </text> <text name="DwellText"> - 0 + 載入中... </text> <button label="購買土地" name="Buy Land..."/> + <button label="Linden 出售" name="Linden Sale..." tool_tip="土地必須有人擁有、已設有內容,並且不在拍賣中。"/> <button label="腳本資訊" name="Scripts..."/> <button label="為群組購買" name="Buy For Group..."/> <button label="購買通行權" name="Buy Pass..." tool_tip="通行權允許你暫時可出入這塊土地。"/> <button label="放棄土地" name="Abandon Land..."/> - <button label="Reclaim Land" name="Reclaim Land..."/> - <button label="Linden Sale" name="Linden Sale..." tool_tip="Land must be owned, set content, and not already for auction."/> + <button label="收回土地" name="Reclaim Land..."/> </panel> <panel label="契約" name="land_covenant_panel"> <panel.string name="can_resell"> - Purchased land in this region may be resold. + 購買這地區的土地允許轉售。 </panel.string> <panel.string name="can_not_resell"> - Purchased land in this region may not be resold. + 購買這地區的土地不允許轉售。 </panel.string> <panel.string name="can_change"> - Purchased land in this region may be joined or subdivided. + 購買這地區的土地允許進行合併或分割。 </panel.string> <panel.string name="can_not_change"> - Purchased land in this region may not be joined or subdivided. + 購買這地區的土地不允許進行合併或分割。 </panel.string> <text name="estate_section_lbl"> 領地: </text> <text name="estate_name_text"> - mainland + 大陸 </text> <text name="estate_owner_lbl"> - 擁有者: + 所有人: </text> <text name="estate_owner_text"> (無) </text> <text_editor name="covenant_editor"> - There is no Covenant provided for this Estate. + 此領地沒有任何契約要求。 </text_editor> <text name="covenant_timestamp_text"> - Last Modified Wed Dec 31 16:00:00 1969 + 上次修改於 Wed Dec 31 16:00:00 1969 </text> <text name="region_section_lbl"> 地區: @@ -180,7 +180,7 @@ 類型: </text> <text name="region_landtype_text"> - Mainland / Homestead + 大陸 / 家園 </text> <text name="region_maturity_lbl"> 分級: @@ -189,54 +189,54 @@ 完全成人 </text> <text name="resellable_lbl"> - Resale: + 轉售: </text> <text name="resellable_clause"> - Land in this region may not be resold. + 這地區的土地不能轉售。 </text> <text name="changeable_lbl"> - Subdivide: + 分割: </text> <text name="changeable_clause"> - Land in this region may not be joined/subdivided. + 這地區的土地不能合併或分割。 </text> </panel> <panel label="物件" name="land_objects_panel"> <panel.string name="objects_available_text"> - [COUNT] out of [MAX] ([AVAILABLE] available) + 使用 [MAX] 中的 [COUNT] (剩餘 [AVAILABLE] 可用) </panel.string> <panel.string name="objects_deleted_text"> - [COUNT] out of [MAX] ([DELETED] will be deleted) + 目前 [COUNT],最多允許 [MAX] ([DELETED] 將被刪除) </panel.string> <text name="parcel_object_bonus"> - Region Object Bonus Factor: [BONUS] + 地區物件負荷倍數:[BONUS] </text> <text name="Simulator primitive usage:"> - 幾何元件使用: + 地區容納量: </text> <text name="objects_available"> 使用 [MAX] 中的 [COUNT] (剩餘 [AVAILABLE] 可用) </text> <text name="Primitives parcel supports:"> - 地段所提供的幾何元件數: + 地段土地容納量: </text> <text name="object_contrib_text"> [COUNT] </text> <text name="Primitives on parcel:"> - 地段上的幾何元件數: + 地段土地衝擊量: </text> <text name="total_objects_text"> [COUNT] </text> <text name="Owned by parcel owner:"> - 地段擁有者所擁有: + 地段所有人所擁有: </text> <text name="owner_objects_text"> [COUNT] </text> <button label="顯示" label_selected="顯示" name="ShowOwner"/> - <button label="退回" name="ReturnOwner..." tool_tip="退回物件給它們的擁有者。"/> + <button label="退回" name="ReturnOwner..." tool_tip="退回物件給它們的所有人。"/> <text name="Set to group:"> 設定群組: </text> @@ -244,7 +244,7 @@ [COUNT] </text> <button label="顯示" label_selected="顯示" name="ShowGroup"/> - <button label="退回" name="ReturnGroup..." tool_tip="退回物件給它們的擁有者。"/> + <button label="退回" name="ReturnGroup..." tool_tip="退回物件給它們的所有人。"/> <text name="Owned by others:"> 其他人所擁有: </text> @@ -252,26 +252,26 @@ [COUNT] </text> <button label="顯示" label_selected="顯示" name="ShowOther"/> - <button label="退回" name="ReturnOther..." tool_tip="退回物件給它們的擁有者。"/> + <button label="退回" name="ReturnOther..." tool_tip="退回物件給它們的所有人。"/> <text name="Selected / sat upon:"> - Selected / sat upon: + 已選 / 坐在上面: </text> <text name="selected_objects_text"> [COUNT] </text> <text name="Autoreturn"> - Auto return other Residents' objects (minutes, 0 for off): + 自動送返其他居民的物件(分鐘,設為 0 可取消自動): </text> <text name="Object Owners:"> - 物件擁有者: + 物件所有人: </text> <button name="Refresh List" tool_tip="刷新物件清單"/> <button label="退回物件" name="Return objects..."/> <name_list name="owner list"> - <name_list.columns label="Type" name="type"/> + <name_list.columns label="類型" name="type"/> <name_list.columns label="名稱" name="name"/> - <name_list.columns label="Count" name="count"/> - <name_list.columns label="Most Recent" name="mostrecent"/> + <name_list.columns label="計數" name="count"/> + <name_list.columns label="最近" name="mostrecent"/> </name_list> </panel> <panel label="選項" name="land_options_panel"> @@ -279,8 +279,8 @@ 讓其他人可以在搜尋結果中看到這塊地段 </panel.string> <panel.string name="search_disabled_small_tooltip"> - This option is disabled because this parcel's area is 128 m² or smaller. -Only large parcels can be listed in search. + 這個選項已停用,因為這個地段面積小於 128 平方公尺。 +大面積地段才可列入搜尋結果。 </panel.string> <panel.string name="search_disabled_permissions_tooltip"> 這個選項已關閉因為你不能修改這個地段的選項。 @@ -292,10 +292,10 @@ Only large parcels can be listed in search. 完全成人內容 </panel.string> <panel.string name="mature_check_mature_tooltip"> - Your parcel information or content is considered moderate. + 你的地段資訊或內容被視為適度成人分級。 </panel.string> <panel.string name="mature_check_adult_tooltip"> - Your parcel information or content is considered adult. + 你的地段資訊或內容被視為完全成人分級。 </panel.string> <panel.string name="landing_point_none"> (無) @@ -309,8 +309,10 @@ Only large parcels can be listed in search. <text name="allow_label"> 允許其他居民去: </text> - <check_box label="編輯地形" name="edit land check" tool_tip="若勾選則任何人將可以變形你的土地,最好是保持未勾選,因為你隨時可以編輯變更你的土地。"/> - <check_box label="飛行" name="check fly" tool_tip="逤勾選則居民可以在你飛行,不然就只能由外面飛入或飛越你的土地。"/> + <text name="allow_label0"> + 飛行: + </text> + <check_box label="任何人" name="check fly" tool_tip="如果勾選,居民可在你土地上飛行。 如果不勾選,居民僅可飛越你土地。"/> <text name="allow_label2"> 建造: </text> @@ -326,67 +328,68 @@ Only large parcels can be listed in search. </text> <check_box label="任何人" name="check other scripts"/> <check_box label="群組" name="check group scripts"/> - <text name="land_options_label"> - 土地選項: - </text> - <check_box label="安全(無傷害)" name="check safe" tool_tip="若勾選則設應土地為安全的,傷害性的戰鬥將被關閉。清除勾選後才能進行傷害性的戰鬥。"/> - <check_box label="禁止推撞" name="PushRestrictCheck" tool_tip="防止使用腳本推撞。勾選這個選項將可以有效防止你土地上的破壞行為。"/> + <check_box label="安全(無傷害)" name="check safe" tool_tip="若勾選,將把土地設為安全,禁絕傷害性的戰鬥。 若未勾選,則允許傷害性的戰鬥。"/> + <check_box label="禁止推撞" name="PushRestrictCheck" tool_tip="禁止使用腳本推撞。 勾選這選項可有效防止你土地上出現滋事行為。"/> <check_box label="將地點刊登顯示在搜尋中(L$30 / 每週)" name="ShowDirectoryCheck" tool_tip="讓其他人可以在搜尋結果中看到這塊地段"/> <combo_box name="land category with adult"> <combo_box.item label="任何類別" name="item0"/> - <combo_box.item label="Linden Location" name="item1"/> + <combo_box.item label="林登位置" name="item1"/> <combo_box.item label="完全成人" name="item2"/> <combo_box.item label="藝術與文化" name="item3"/> <combo_box.item label="商業" name="item4"/> <combo_box.item label="教育" name="item5"/> <combo_box.item label="遊戲" name="item6"/> <combo_box.item label="聚會所" name="item7"/> - <combo_box.item label="新手友善" name="item8"/> - <combo_box.item label="公園與自然" name="item9"/> + <combo_box.item label="歡迎新手光臨" name="item8"/> + <combo_box.item label="公園與自然景觀" name="item9"/> <combo_box.item label="住宅" name="item10"/> - <combo_box.item label="採購" name="item11"/> - <combo_box.item label="Rental" name="item13"/> - <combo_box.item label="Other" name="item12"/> + <combo_box.item label="購物" name="item11"/> + <combo_box.item label="出租" name="item13"/> + <combo_box.item label="其他" name="item12"/> </combo_box> <combo_box name="land category"> <combo_box.item label="任何類別" name="item0"/> - <combo_box.item label="Linden Location" name="item1"/> + <combo_box.item label="林登位置" name="item1"/> <combo_box.item label="藝術與文化" name="item3"/> <combo_box.item label="商業" name="item4"/> <combo_box.item label="教育" name="item5"/> <combo_box.item label="遊戲" name="item6"/> <combo_box.item label="聚會所" name="item7"/> - <combo_box.item label="新手友善" name="item8"/> - <combo_box.item label="公園與自然" name="item9"/> + <combo_box.item label="歡迎新手光臨" name="item8"/> + <combo_box.item label="公園與自然景觀" name="item9"/> <combo_box.item label="住宅" name="item10"/> - <combo_box.item label="採購" name="item11"/> - <combo_box.item label="Rental" name="item13"/> - <combo_box.item label="Other" name="item12"/> + <combo_box.item label="購物" name="item11"/> + <combo_box.item label="出租" name="item13"/> + <combo_box.item label="其他" name="item12"/> </combo_box> <check_box label="適度成人內容" name="MatureCheck" tool_tip=" "/> <text name="Snapshot:"> 快照: </text> - <texture_picker name="snapshot_ctrl" tool_tip="點擊以挑選圖像"/> + <texture_picker name="snapshot_ctrl" tool_tip="點按以挑選圖片"/> + <text name="allow_label5"> + 其他地段的化身可以看見本地段裡的化身,並與之交談 + </text> + <check_box label="察看化身" name="SeeAvatarsCheck" tool_tip="允許其他地段的化身看到本地段包括你在內的化身,並可互相交談。"/> <text name="landing_point"> 登陸點:[LANDING] </text> - <button label="設定" label_selected="設定" name="Set" tool_tip="Sets the landing point where visitors arrive. Sets to your avatar's location inside this parcel."/> + <button label="設定" label_selected="設定" name="Set" tool_tip="設定訪客登陸地點。 設定你的化身在此地段內的位置。"/> <button label="清除" label_selected="清除" name="Clear" tool_tip="清除登陸點"/> <text name="Teleport Routing: "> 瞬間傳送路徑: </text> - <combo_box name="landing type" tool_tip="Teleport Routing -- select how to handle teleports onto your land"> - <combo_box.item label="Blocked" name="Blocked"/> - <combo_box.item label="Landing Point" name="LandingPoint"/> - <combo_box.item label="Anywhere" name="Anywhere"/> + <combo_box name="landing type" tool_tip="瞬間傳送繞路 -- 設定如何處理前往你土地的瞬間傳送"> + <combo_box.item label="封鎖的" name="Blocked"/> + <combo_box.item label="登陸點" name="LandingPoint"/> + <combo_box.item label="任何地點" name="Anywhere"/> </combo_box> </panel> - <panel label="MEDIA" name="land_media_panel"> + <panel label="媒體" name="land_media_panel"> <text name="with media:"> 類型: </text> - <combo_box name="media type" tool_tip="Specify if the URL is a movie, web page, or other media"/> + <combo_box name="media type" tool_tip="指明這 URL 是影片、網頁還是其他媒體類型"/> <text name="at URL:"> 首頁: </text> @@ -394,27 +397,27 @@ Only large parcels can be listed in search. <text name="Description:"> 描述: </text> - <line_editor name="url_description" tool_tip="Text displayed next to play/load button"/> + <line_editor name="url_description" tool_tip="播放 / 載入按鈕旁顯示的文字"/> <text name="Media texture:"> 取代材質: </text> - <texture_picker name="media texture" tool_tip="點擊以挑選圖像"/> + <texture_picker name="media texture" tool_tip="點按以挑選圖片"/> <text name="replace_texture_help"> - Objects using this texture will show the movie or web page after you click the play arrow. Select the thumbnail to choose a different texture. + 使用此材質的物件,將在你點按「播放」箭頭後播放影片或顯示網頁。 選取縮圖即可選擇不同的材質。 </text> - <check_box label="自動縮放" name="media_auto_scale" tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required."/> - <text name="media_size" tool_tip="Size to render Web media, leave 0 for default."> + <check_box label="自動縮放" name="media_auto_scale" tool_tip="勾選此選項將會在此地段自動變更內容的比例。 速度可能稍慢,視覺效果可能略遜,但不需要調整其他材質的比例或加以對齊。"/> + <text name="media_size" tool_tip="網上媒體的顯示尺寸,設 0 將採用預設值。"> 尺寸: </text> - <spinner name="media_size_width" tool_tip="Size to render Web media, leave 0 for default."/> - <spinner name="media_size_height" tool_tip="Size to render Web media, leave 0 for default."/> + <spinner name="media_size_width" tool_tip="網上媒體的顯示尺寸,設 0 將採用預設值。"/> + <spinner name="media_size_height" tool_tip="網上媒體的顯示尺寸,設 0 將採用預設值。"/> <text name="pixels"> 像素 </text> <text name="Options:"> 選項: </text> - <check_box label="Loop" name="media_loop" tool_tip="Play media in a loop. When the media has finished playing, it will restart from the beginning."/> + <check_box label="連續" name="media_loop" tool_tip="連續播放媒體。 媒體播放結束後,會從頭繼續播放。"/> </panel> <panel label="聲音" name="land_audio_panel"> <text name="MusicURL:"> @@ -423,45 +426,45 @@ Only large parcels can be listed in search. <text name="Sound:"> 聲音: </text> - <check_box label="Restrict gesture and object sounds to this parcel" name="check sound local"/> + <check_box label="將姿勢和物件的聲音限制於此地段" name="check sound local"/> + <text name="Avatar Sounds:"> + 化身聲音: + </text> + <check_box label="任何人" name="all av sound check"/> + <check_box label="群組" name="group av sound check"/> <text name="Voice settings:"> - Voice: + 語音: </text> - <check_box label="Enable Voice" name="parcel_enable_voice_channel"/> - <check_box label="Enable Voice (established by the Estate)" name="parcel_enable_voice_channel_is_estate_disabled"/> - <check_box label="Restrict Voice to this parcel" name="parcel_enable_voice_channel_local"/> + <check_box label="啟用語音" name="parcel_enable_voice_channel"/> + <check_box label="啟用聲音(由領地所確立)" name="parcel_enable_voice_channel_is_estate_disabled"/> + <check_box label="將聲音限制於此地段" name="parcel_enable_voice_channel_local"/> </panel> - <panel label="ACCESS" name="land_access_panel"> + <panel label="出入許可" name="land_access_panel"> <panel.string name="access_estate_defined"> - (Defined by the Estate) - </panel.string> - <panel.string name="allow_public_access"> - Allow Public Access ([MATURITY]) (Note: Unchecking this will create ban lines) + (由領地定義) </panel.string> <panel.string name="estate_override"> - One or more of these options is set at the estate level + 至少一個選項在領地的層級設定 </panel.string> - <text name="Limit access to this parcel to:"> - 出入此地段 - </text> + <check_box label="允許公開出入(若未勾選,將設立禁越線)" name="public_access"/> <text name="Only Allow"> - Restrict Access to Residents verified by: + 僅允許符合以下條件的居民進入: </text> - <check_box label="Payment Information on File [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Ban unidentified Residents."/> - <check_box label="年齡驗證 [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/> + <check_box label="已預留付款資料 [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="居民必須提供付款資料才能進入這地段。 參閱 [SUPPORT_SITE] 獲取進一步資訊。"/> + <check_box label="年滿 18 歲 [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="居民必須年滿 18 歲才能進入這地段。 參閱 [SUPPORT_SITE] 獲取進一步資訊。"/> <check_box label="允許出入的群組:[GROUP]" name="GroupCheck" tool_tip="設定群組於一般頁籤。"/> <check_box label="出售通行權給:" name="PassCheck" tool_tip="允許暫時出入這個地段"/> <combo_box name="pass_combo"> - <combo_box.item label="Anyone" name="Anyone"/> + <combo_box.item label="任何人" name="Anyone"/> <combo_box.item label="群組" name="Group"/> </combo_box> - <spinner label="Price in L$:" name="PriceSpin"/> - <spinner label="Hours of access:" name="HoursSpin"/> + <spinner label="價格(L$):" name="PriceSpin"/> + <spinner label="出入時間:" name="HoursSpin"/> <panel name="Allowed_layout_panel"> - <text label="Always Allow" name="AllowedText"> - Allowed Residents + <text label="永遠允許" name="AllowedText"> + 允許的居民 </text> - <name_list name="AccessList" tool_tip="([LISTED] listed, [MAX] max)"/> + <name_list name="AccessList" tool_tip="(已列入 [LISTED],最多可列 [MAX])"/> <button label="添加" name="add_allowed"/> <button label="移除" label_selected="移除" name="remove_allowed"/> </panel> @@ -469,7 +472,7 @@ Only large parcels can be listed in search. <text label="禁止" name="BanCheck"> 被封鎖的居民 </text> - <name_list name="BannedList" tool_tip="([LISTED] listed, [MAX] max)"/> + <name_list name="BannedList" tool_tip="(已列入 [LISTED],最多可列 [MAX])"/> <button label="添加" name="add_banned"/> <button label="移除" label_selected="移除" name="remove_banned"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/floater_activeim.xml b/indra/newview/skins/default/xui/zh/floater_activeim.xml index 93017bf5b2..b148ca8eb4 100644 --- a/indra/newview/skins/default/xui/zh/floater_activeim.xml +++ b/indra/newview/skins/default/xui/zh/floater_activeim.xml @@ -1,2 +1,2 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_activeim" title="ACTIVE IM"/> +<floater name="floater_activeim" title="進行中的 IM"/> diff --git a/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml new file mode 100644 index 0000000000..76cb9079c4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Anim Preview" title="ANIMATION.ANIM"> + <text name="name_label"> + 名稱: + </text> + <text name="description_label"> + 描述: + </text> + <button label="上傳(L$[AMOUNT])" name="ok_btn"/> + <button label="取消" label_selected="取消" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml new file mode 100644 index 0000000000..ffb0de8a68 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Animation Preview"> + <floater.string name="failed_to_initialize"> + 動作初始化失敗 + </floater.string> + <floater.string name="anim_too_long"> + 動作檔長度為 [LENGTH] 秒。 + +動作檔長度最多可為 [MAX_LENGTH] 秒。 + </floater.string> + <floater.string name="failed_file_read"> + 無法讀取動作檔。 + +[STATUS] + </floater.string> + <floater.string name="E_ST_OK"> + 確定 + </floater.string> + <floater.string name="E_ST_EOF"> + 檔案結尾不正常。 + </floater.string> + <floater.string name="E_ST_NO_CONSTRAINT"> + 無法讀取約束定義。 + </floater.string> + <floater.string name="E_ST_NO_FILE"> + 無法開啟 BVH 檔案。 + </floater.string> + <floater.string name="E_ST_NO_HIER"> + HIERARCHY 檔頭無效。 + </floater.string> + <floater.string name="E_ST_NO_JOINT"> + 找不到 ROOT 或 JOINT。 + </floater.string> + <floater.string name="E_ST_NO_NAME"> + 無法取得 JOINT 名稱。 + </floater.string> + <floater.string name="E_ST_NO_OFFSET"> + 無法尋找位移。 + </floater.string> + <floater.string name="E_ST_NO_CHANNELS"> + 找不到頻道。 + </floater.string> + <floater.string name="E_ST_NO_ROTATION"> + 無法取得旋轉序。 + </floater.string> + <floater.string name="E_ST_NO_AXIS"> + 無法取得旋轉軸。 + </floater.string> + <floater.string name="E_ST_NO_MOTION"> + 找不到動作。 + </floater.string> + <floater.string name="E_ST_NO_FRAMES"> + 無法取得幀數。 + </floater.string> + <floater.string name="E_ST_NO_FRAME_TIME"> + 無法取得幀時間。 + </floater.string> + <floater.string name="E_ST_NO_POS"> + 無法取得位置值。 + </floater.string> + <floater.string name="E_ST_NO_ROT"> + 無法取得旋轉值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_FILE"> + 無法開啟平移檔案。 + </floater.string> + <floater.string name="E_ST_NO_XLT_HEADER"> + 無法讀取平移檔頭。 + </floater.string> + <floater.string name="E_ST_NO_XLT_NAME"> + 無法讀取平移名稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_IGNORE"> + 無法讀取平移忽略值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_RELATIVE"> + 無法讀取平移相對值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_OUTNAME"> + 無法讀取平移輸出名稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_MATRIX"> + 無法讀取平移矩陣。 + </floater.string> + <floater.string name="E_ST_NO_XLT_MERGECHILD"> + 無法取得 mergechild 名稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_MERGEPARENT"> + 無法取得 mergeparent 名稱。 + </floater.string> + <floater.string name="E_ST_NO_XLT_PRIORITY"> + 無法取得優先值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_LOOP"> + 無法取得迴圈值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_EASEIN"> + 無法取得 easeIn 值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_EASEOUT"> + 無法取得 easeOut 值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_HAND"> + 無法取得 hand morph 值。 + </floater.string> + <floater.string name="E_ST_NO_XLT_EMOTE"> + 無法讀取表情符號名稱。 + </floater.string> + <floater.string name="E_ST_BAD_ROOT"> + root joint 名稱不正確,使用 "hip"。 + </floater.string> + <text name="name_label"> + 名稱: + </text> + <text name="description_label"> + 描述: + </text> + <spinner label="優先度" name="priority" tool_tip="其他動作的控制可被此動作強行取代"/> + <check_box label="連續" name="loop_check" tool_tip="讓此動作不斷重覆演繹"/> + <spinner label="入(%)" name="loop_in_point" tool_tip="設定動作中重覆演繹的起始點"/> + <spinner label="出(%)" name="loop_out_point" tool_tip="設定動作中重覆演繹的結束點"/> + <text name="hand_label"> + 手部姿勢 + </text> + <combo_box name="hand_pose_combo" tool_tip="控制動作演繹時雙手的姿勢"> + <combo_box.item label="張開" name="Spread"/> + <combo_box.item label="放鬆" name="Relaxed"/> + <combo_box.item label="雙手伸出指頭" name="PointBoth"/> + <combo_box.item label="拳頭" name="Fist"/> + <combo_box.item label="左邊放鬆" name="RelaxedLeft"/> + <combo_box.item label="左邊伸指" name="PointLeft"/> + <combo_box.item label="左邊握拳" name="FistLeft"/> + <combo_box.item label="右邊放鬆" name="RelaxedRight"/> + <combo_box.item label="右邊伸指" name="PointRight"/> + <combo_box.item label="右邊握拳" name="FistRight"/> + <combo_box.item label="右手敬禮" name="SaluteRight"/> + <combo_box.item label="打字" name="Typing"/> + <combo_box.item label="右手比出和平手勢" name="PeaceRight"/> + </combo_box> + <text name="emote_label"> + 表情 + </text> + <combo_box name="emote_combo" tool_tip="控制動作演繹時臉部的姿態"> + <item label="(無)" name="[None]" value=""/> + <item label="張口吶喊貌" name="Aaaaah" value="張口吶喊貌"/> + <item label="害怕" name="Afraid" value="害怕"/> + <item label="生氣" name="Angry" value="生氣"/> + <item label="燦爛笑容" name="BigSmile" value="燦爛笑容"/> + <item label="無聊" name="Bored" value="無聊"/> + <item label="哭泣" name="Cry" value="哭泣"/> + <item label="鄙視" name="Disdain" value="鄙視"/> + <item label="尷尬" name="Embarrassed" value="尷尬"/> + <item label="皺眉" name="Frown" value="皺眉"/> + <item label="親吻" name="Kiss" value="親吻"/> + <item label="笑" name="Laugh" value="笑"/> + <item label="嫌惡貌" name="Plllppt" value="嫌惡貌"/> + <item label="作噁" name="Repulsed" value="作噁"/> + <item label="傷心" name="Sad" value="傷心"/> + <item label="聳聳肩" name="Shrug" value="聳聳肩"/> + <item label="微笑" name="Smile" value="微笑"/> + <item label="驚喜" name="Surprise" value="驚喜"/> + <item label="眨眼" name="Wink" value="眨眼"/> + <item label="擔心" name="Worry" value="擔心"/> + </combo_box> + <text name="preview_label"> + 預覽… + </text> + <combo_box name="preview_base_anim" tool_tip="用這個來測試你的化身從一般動作轉入動作演繹時的情況。"> + <item label="站立" name="Standing" value="站立"/> + <item label="步行中" name="Walking" value="步行中"/> + <item label="坐著" name="Sitting" value="坐著"/> + <item label="飛行" name="Flying" value="飛行"/> + </combo_box> + <spinner label="淡入(秒)" name="ease_in_time" tool_tip="動作攙混植入的時間長度(秒)"/> + <spinner label="淡出(秒)" name="ease_out_time" tool_tip="動作攙混淡出的時間長度(秒)"/> + <button name="play_btn" tool_tip="播放你的動作"/> + <button name="pause_btn" tool_tip="暫停你的動做"/> + <button name="stop_btn" tool_tip="停止播放動作"/> + <text name="bad_animation_text"> + 無法讀取動作檔。 + +我們建議採用由 Poser 4 匯出的 BVH 檔案格式。 + </text> + <button label="上傳(L$[AMOUNT])" name="ok_btn"/> + <button label="取消" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_animation_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_preview.xml deleted file mode 100644 index c5e2eac446..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_animation_preview.xml +++ /dev/null @@ -1,186 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Animation Preview"> - <floater.string name="failed_to_initialize"> - Failed to initialize motion - </floater.string> - <floater.string name="anim_too_long"> - Animation file is [LENGTH] seconds in length. - -Maximum animation length is [MAX_LENGTH] seconds. - </floater.string> - <floater.string name="failed_file_read"> - 無法讀取動作檔。 - -[STATUS] - </floater.string> - <floater.string name="E_ST_OK"> - 確定 - </floater.string> - <floater.string name="E_ST_EOF"> - Premature end of file. - </floater.string> - <floater.string name="E_ST_NO_CONSTRAINT"> - Cannot read constraint definition. - </floater.string> - <floater.string name="E_ST_NO_FILE"> - 無法開啟 BVH 檔案。 - </floater.string> - <floater.string name="E_ST_NO_HIER"> - Invalid HIERARCHY header. - </floater.string> - <floater.string name="E_ST_NO_JOINT"> - Cannot find ROOT or JOINT. - </floater.string> - <floater.string name="E_ST_NO_NAME"> - Cannot get JOINT name. - </floater.string> - <floater.string name="E_ST_NO_OFFSET"> - 無法尋找位移。 - </floater.string> - <floater.string name="E_ST_NO_CHANNELS"> - Cannot find CHANNELS. - </floater.string> - <floater.string name="E_ST_NO_ROTATION"> - Cannot get rotation order. - </floater.string> - <floater.string name="E_ST_NO_AXIS"> - Cannot get rotation axis. - </floater.string> - <floater.string name="E_ST_NO_MOTION"> - Cannot find MOTION. - </floater.string> - <floater.string name="E_ST_NO_FRAMES"> - Cannot get number of frames. - </floater.string> - <floater.string name="E_ST_NO_FRAME_TIME"> - Cannot get frame time. - </floater.string> - <floater.string name="E_ST_NO_POS"> - Cannot get position values. - </floater.string> - <floater.string name="E_ST_NO_ROT"> - Cannot get rotation values. - </floater.string> - <floater.string name="E_ST_NO_XLT_FILE"> - Cannot open translation file. - </floater.string> - <floater.string name="E_ST_NO_XLT_HEADER"> - Cannot read translation header. - </floater.string> - <floater.string name="E_ST_NO_XLT_NAME"> - Cannot read translation names. - </floater.string> - <floater.string name="E_ST_NO_XLT_IGNORE"> - Cannot read translation ignore value. - </floater.string> - <floater.string name="E_ST_NO_XLT_RELATIVE"> - Cannot read translation relative value. - </floater.string> - <floater.string name="E_ST_NO_XLT_OUTNAME"> - Cannot read translation outname value. - </floater.string> - <floater.string name="E_ST_NO_XLT_MATRIX"> - Cannot read translation matrix. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGECHILD"> - Cannot get mergechild name. - </floater.string> - <floater.string name="E_ST_NO_XLT_MERGEPARENT"> - Cannot get mergeparent name. - </floater.string> - <floater.string name="E_ST_NO_XLT_PRIORITY"> - Cannot get priority value. - </floater.string> - <floater.string name="E_ST_NO_XLT_LOOP"> - Cannot get loop value. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEIN"> - Cannot get easeIn values. - </floater.string> - <floater.string name="E_ST_NO_XLT_EASEOUT"> - Cannot get easeOut values. - </floater.string> - <floater.string name="E_ST_NO_XLT_HAND"> - Cannot get hand morph value. - </floater.string> - <floater.string name="E_ST_NO_XLT_EMOTE"> - Cannot read emote name. - </floater.string> - <floater.string name="E_ST_BAD_ROOT"> - Incorrect root joint name, use "hip". - </floater.string> - <text name="name_label"> - 名稱: - </text> - <text name="description_label"> - 描述: - </text> - <spinner label="優先度" name="priority" tool_tip="Controls which other animations can be overridden by this animation"/> - <check_box label="Loop" name="loop_check" tool_tip="Makes this animation loop"/> - <spinner label="In(%)" name="loop_in_point" tool_tip="Sets point in animation that looping returns to"/> - <spinner label="Out(%)" name="loop_out_point" tool_tip="Sets point in animation that ends a loop"/> - <text name="hand_label"> - Hand Pose - </text> - <combo_box name="hand_pose_combo" tool_tip="Controls what hands do during animation"> - <combo_box.item label="Spread" name="Spread"/> - <combo_box.item label="Relaxed" name="Relaxed"/> - <combo_box.item label="Point Both" name="PointBoth"/> - <combo_box.item label="Fist" name="Fist"/> - <combo_box.item label="Relaxed Left" name="RelaxedLeft"/> - <combo_box.item label="Point Left" name="PointLeft"/> - <combo_box.item label="Fist Left" name="FistLeft"/> - <combo_box.item label="Relaxed Right" name="RelaxedRight"/> - <combo_box.item label="Point Right" name="PointRight"/> - <combo_box.item label="Fist Right" name="FistRight"/> - <combo_box.item label="Salute Right" name="SaluteRight"/> - <combo_box.item label="Typing" name="Typing"/> - <combo_box.item label="Peace Right" name="PeaceRight"/> - </combo_box> - <text name="emote_label"> - Expression - </text> - <combo_box name="emote_combo" tool_tip="Controls what face does during animation"> - <item label="(無)" name="[None]" value=""/> - <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> - <item label="Afraid" name="Afraid" value="Afraid"/> - <item label="Angry" name="Angry" value="Angry"/> - <item label="Big Smile" name="BigSmile" value="Big Smile"/> - <item label="Bored" name="Bored" value="Bored"/> - <item label="Cry" name="Cry" value="Cry"/> - <item label="Disdain" name="Disdain" value="Disdain"/> - <item label="Embarrassed" name="Embarrassed" value="Embarrassed"/> - <item label="Frown" name="Frown" value="Frown"/> - <item label="Kiss" name="Kiss" value="Kiss"/> - <item label="Laugh" name="Laugh" value="Laugh"/> - <item label="Plllppt" name="Plllppt" value="Plllppt"/> - <item label="Repulsed" name="Repulsed" value="Repulsed"/> - <item label="Sad" name="Sad" value="Sad"/> - <item label="Shrug" name="Shrug" value="Shrug"/> - <item label="Smile" name="Smile" value="Smile"/> - <item label="Surprise" name="Surprise" value="Surprise"/> - <item label="Wink" name="Wink" value="Wink"/> - <item label="Worry" name="Worry" value="Worry"/> - </combo_box> - <text name="preview_label"> - Preview while - </text> - <combo_box name="preview_base_anim" tool_tip="Use this to test your animation behavior while your avatar performs common actions."> - <item label="Standing" name="Standing" value="Standing"/> - <item label="Walking" name="Walking" value="Walking"/> - <item label="Sitting" name="Sitting" value="Sitting"/> - <item label="飛行" name="Flying" value="飛行"/> - </combo_box> - <spinner label="淡入(秒)" name="ease_in_time" tool_tip="Amount of time (in seconds) over which animations blends in"/> - <spinner label="淡出(秒)" name="ease_out_time" tool_tip="Amount of time (in seconds) over which animations blends out"/> - <button name="play_btn" tool_tip="播放你的動作"/> - <button name="pause_btn" tool_tip="暫停你的動做"/> - <button name="stop_btn" tool_tip="Stop animation playback"/> - <text name="bad_animation_text"> - Unable to read animation file. - -We recommend BVH files exported from Poser 4. - </text> - <button label="上傳(L$[AMOUNT])" name="ok_btn"/> - <button label="取消" name="cancel_btn"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_auction.xml b/indra/newview/skins/default/xui/zh/floater_auction.xml index b1862bc582..1b589a92cc 100644 --- a/indra/newview/skins/default/xui/zh/floater_auction.xml +++ b/indra/newview/skins/default/xui/zh/floater_auction.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_auction" title="START LINDEN LAND SALE"> +<floater name="floater_auction" title="開始 Linden 土地出售"> <floater.string name="already for sale"> - You cannot auction parcels which are already for sale. + 出售中的地段無法進行拍賣。 </floater.string> - <check_box initial_value="true" label="Include yellow selection fence" name="fence_check"/> - <button label="Snapshot" label_selected="Snapshot" name="snapshot_btn"/> - <button label="Sell to Anyone" label_selected="Sell to Anyone" name="sell_to_anyone_btn"/> + <check_box initial_value="true" label="包括黃色圍線" name="fence_check"/> + <button label="快照" label_selected="快照" name="snapshot_btn"/> + <button label="出售給任何人" label_selected="出售給任何人" name="sell_to_anyone_btn"/> <button label="清除設定" label_selected="清除設定" name="reset_parcel_btn"/> - <button label="Start Auction" label_selected="Start Auction" name="start_auction_btn"/> + <button label="開始拍賣" label_selected="開始拍賣" name="start_auction_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_autoreplace.xml b/indra/newview/skins/default/xui/zh/floater_autoreplace.xml new file mode 100644 index 0000000000..4ee07e6295 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_autoreplace.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="autoreplace_floater" title="自動取代設定"> + <check_box label="啟用自動取代" name="autoreplace_enable" tool_tip="在輸入聊天內容的同時,將輸入的關鍵字代換為相應的取代文字。"/> + <button label="匯入清單…" name="autoreplace_import_list" tool_tip="從檔案載入先前匯出過的清單。"/> + <button label="匯出清單…" name="autoreplace_export_list" tool_tip="將所選清單儲存到檔案以便和他人分享。"/> + <button label="新的清單…" name="autoreplace_new_list" tool_tip="新建一個清單。"/> + <button label="刪除清單" name="autoreplace_delete_list" tool_tip="刪除所選清單。"/> + <button name="autoreplace_list_up" tool_tip="提高此清單的優先次序。"/> + <button name="autoreplace_list_down" tool_tip="降低此清單的優先次序。"/> + <scroll_list name="autoreplace_list_replacements"> + <scroll_list.columns label="關鍵字" name="keyword"/> + <scroll_list.columns label="取代文字" name="replacement"/> + </scroll_list> + <button label="添加..." name="autoreplace_add_entry"/> + <button label="移除" name="autoreplace_delete_entry"/> + <button label="儲存項目" name="autoreplace_save_entry" tool_tip="儲存此項目。"/> + <button label="儲存變更" name="autoreplace_save_changes" tool_tip="儲存所有變更。"/> + <button label="取消" name="autoreplace_cancel" tool_tip="放棄所有變更。"/> +</floater> +<!-- + <text + top_pad="10" + left="10" + height="16" + width="260" + follows="left|top" + halign="center" + mouse_opaque="true" + name="autoreplace_text2"> + Entries + </text> +--> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar.xml b/indra/newview/skins/default/xui/zh/floater_avatar.xml new file mode 100644 index 0000000000..55b1a95a41 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_avatar.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Avatar" title="選擇一個化身"/> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml index 7e2d74c728..c19369c859 100644 --- a/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="avatarpicker" title="挑選居民"> <floater.string name="not_found"> - '[TEXT]' not found + 查無「[TEXT]」 </floater.string> <floater.string name="no_one_near"> - No one near + 附近無人 </floater.string> <floater.string name="no_results"> - No results + 沒有結果 </floater.string> <floater.string name="searching"> 搜尋中... @@ -21,9 +21,9 @@ <tab_container name="ResidentChooserTabs"> <panel label="搜尋" name="SearchPanel"> <text name="InstructSearchResidentName"> - Type part of a person's name: + 鍵入人名的一部分: </text> - <button label="Go" label_selected="Go" name="Find"/> + <button label="前往" label_selected="前往" name="Find"/> <scroll_list name="SearchResults"> <columns label="名稱" name="name"/> <columns label="使用者名稱" name="username"/> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml index 36dae7c798..69309c96de 100644 --- a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="avatar_texture_debug" title="化身材質"> <floater.string name="InvalidAvatar"> - INVALID AVATAR + 無效的化身 </floater.string> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> <text name="label"> - Baked -Textures + 確定產出的 +材質 </text> <text name="composite_label"> - Composite -Textures + 合成 +材質 </text> - <button label="Dump IDs to Console" label_selected="Dump" name="Dump"/> + <button label="傾印 ID 到控制臺" label_selected="傾印" name="Dump"/> <panel name="scroll_content_panel"> <texture_picker label="頭髮" name="hair-baked"/> <texture_picker label="頭髮" name="hair_grain"/> @@ -25,7 +25,7 @@ Textures <texture_picker label="眼睛" name="eyes-baked"/> <texture_picker label="眼睛" name="eyes_iris"/> <texture_picker label="眼睛半透明" name="eyes_alpha"/> - <texture_picker label="上半身半透明" name="upper-baked"/> + <texture_picker label="上半身" name="upper-baked"/> <texture_picker label="上半身身體部位" name="upper_bodypaint"/> <texture_picker label="內衣" name="upper_undershirt"/> <texture_picker label="手套" name="upper_gloves"/> diff --git a/indra/newview/skins/default/xui/zh/floater_beacons.xml b/indra/newview/skins/default/xui/zh/floater_beacons.xml index 1613b23e75..83e10804d6 100644 --- a/indra/newview/skins/default/xui/zh/floater_beacons.xml +++ b/indra/newview/skins/default/xui/zh/floater_beacons.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="beacons" title="BEACONS"> +<floater name="beacons" title="指標"> <panel name="beacons_panel"> <text name="label_show"> - Show : + 顯示: </text> - <check_box label="Beacons" name="beacons"/> - <check_box label="Highlights" name="highlights"/> - <text name="beacon_width_label" tool_tip="Beacon width"> - Width: + <check_box label="指標" name="beacons"/> + <check_box label="高亮顯示" name="highlights"/> + <text name="beacon_width_label" tool_tip="指標寬度"> + 寬: </text> <text name="label_objects"> - For these objects: + 對象物件: </text> - <check_box label="Physical" name="physical"/> - <check_box label="Scripted" name="scripted"/> - <check_box label="Touch only" name="touch_only"/> - <check_box label="Sound sources" name="sounds"/> - <check_box label="Particle sources" name="particles"/> - <check_box label="Media sources" name="moapbeacon"/> + <check_box label="物理性" name="physical"/> + <check_box label="有腳本" name="scripted"/> + <check_box label="僅可觸碰" name="touch_only"/> + <check_box label="聲音來源" name="sounds"/> + <check_box label="例子來源" name="particles"/> + <check_box label="媒體來源" name="moapbeacon"/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_build_options.xml b/indra/newview/skins/default/xui/zh/floater_build_options.xml index b9d3b6b849..29f36b461c 100644 --- a/indra/newview/skins/default/xui/zh/floater_build_options.xml +++ b/indra/newview/skins/default/xui/zh/floater_build_options.xml @@ -1,9 +1,32 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="build options floater" title="格線選項"> - <spinner label="格線單位(公尺)" name="GridResolution"/> - <spinner label="Grid Extents (meters)" name="GridDrawSize"/> + <floater.string name="grid_screen_text"> + 螢幕 + </floater.string> + <floater.string name="grid_local_text"> + 本地 + </floater.string> + <floater.string name="grid_world_text"> + 世界 + </floater.string> + <floater.string name="grid_reference_text"> + 參考 + </floater.string> + <floater.string name="grid_attachment_text"> + 附件 + </floater.string> + <text name="grid_mode_label" tool_tip="格線不透明度"> + 模式 + </text> + <combo_box name="combobox grid mode" tool_tip="選擇物件定位參考的格線尺度類型"> + <combo_box.item label="世界格線" name="World"/> + <combo_box.item label="地方格線" name="Local"/> + <combo_box.item label="參考格線" name="Reference"/> + </combo_box> + <spinner label="單位(公尺)" name="GridResolution"/> + <spinner label="範圍(公尺)" name="GridDrawSize"/> <check_box label="貼齊至子單位" name="GridSubUnit"/> - <check_box label="View cross-sections" name="GridCrossSection"/> + <check_box label="檢視橫剖面" name="GridCrossSection"/> <text name="grid_opacity_label" tool_tip="格線不透明度"> 不透明度: </text> diff --git a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml index 660710fb7b..59751a3a46 100644 --- a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml @@ -33,13 +33,13 @@ <text name="AnyoneLabel"> 任何人: </text> - <check_box label="覆製" name="everyone_copy"/> + <check_box label="恚庨" name="everyone_copy"/> <text name="NextOwnerLabel"> - 下一個擁有者: + 下一個所有人: </text> <check_box label="修改" name="next_owner_modify"/> - <check_box label="覆製" name="next_owner_copy"/> - <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="下一個擁有者能送出或轉售這個物件"/> + <check_box label="恚庨" name="next_owner_copy"/> + <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="下一個所有人可贈送或轉售這個物件"/> <button label="確定" name="apply"/> <button label="取消" name="close"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_contents.xml b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml index 44d3394a52..5e4153de66 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_contents.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_buy_contents" title="BUY CONTENTS"> +<floater name="floater_buy_contents" title="購買內容"> <floater.string name="no_copy_text"> - (no copy) + (禁止複製) </floater.string> <floater.string name="no_modify_text"> - (no modify) + (禁止修改) </floater.string> <floater.string name="no_transfer_text"> - (no transfer) + (禁止轉讓) </floater.string> <text name="contains_text"> - [NAME] contains: + <nolink>[NAME]</nolink> 內含: </text> <text name="buy_text"> - Buy for L$[AMOUNT] from [NAME]? + 是否花 L$[AMOUNT] 向 [NAME] 購買? </text> <check_box label="立即穿上服裝" name="wear_check"/> <button label="購買" label_selected="購買" name="buy_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml index 9f6591faf9..fcf2800728 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="buy currency" title="購買 L$"> <floater.string name="buy_currency"> - Buy L$ [LINDENS] for approx. [LOCALAMOUNT] + 購買 L$ [LINDENS],所需花費約為 [LOCALAMOUNT] </floater.string> <text name="info_need_more"> - 你需要更多 L$ + 你的 L$ 不足 </text> <text name="contacting"> 聯接到 LindeX 中... @@ -31,10 +31,10 @@ 以此價格 </text> <text name="currency_est"> - approx. [LOCALAMOUNT] + 約合 [LOCALAMOUNT] </text> <text name="getting_data"> - Estimating... + 估算中… </text> <text name="buy_action"> [ACTION] @@ -46,16 +46,16 @@ L$ [AMT] </text> <text name="currency_links"> - [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] + [http://www.secondlife.com/my/account/payment_method_management.php 付費方式] | [http://www.secondlife.com/my/account/currency.php 幣種] </text> <text name="exchange_rate_note"> - Re-enter amount to see the latest exchange rate. + 重新輸入金額即可察看最新的匯率。 </text> <text name="purchase_warning_repurchase"> - Confirming this purchase only buys L$, not the object. + 確認這次購買只是添購 L$,並非購買物件。 </text> <text name="purchase_warning_notenough"> - 你並未購買足夠的林登幣,請先添加一些數量。 + 你購買的林登幣不足, 請增加數額。 </text> <button label="立即購買" name="buy_btn"/> <button label="取消" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_land.xml b/indra/newview/skins/default/xui/zh/floater_buy_land.xml index 336d14747d..51bbd6a561 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_land.xml @@ -1,29 +1,29 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="buy land" title="購買土地"> <floater.string name="can_resell"> - May be resold. + 得以再出售。 </floater.string> <floater.string name="can_not_resell"> - May not be resold. + 不得再出售。 </floater.string> <floater.string name="can_change"> - May be joined or subdivided. + 得以合併或分割。 </floater.string> <floater.string name="can_not_change"> - May not be joined or subdivided. + 不得合併或分割。 </floater.string> <floater.string name="cant_buy_for_group"> - You do not have permission to buy land for your active group. + 你沒有權限為你當前的群組購買土地。 </floater.string> <floater.string name="no_land_selected"> 無土地被選擇。 </floater.string> <floater.string name="multiple_parcels_selected"> - Multiple different parcels selected. -Try selecting a smaller area. + 選取了多個不同地段。 +請嘗試選取較小區域。 </floater.string> <floater.string name="no_permission"> - You do not have permission to buy land for your active group. + 你沒有權限為你當前的群組購買土地。 </floater.string> <floater.string name="parcel_not_for_sale"> 所選擇的地段不出售。. @@ -35,37 +35,37 @@ Try selecting a smaller area. 你已經擁有這個地段。 </floater.string> <floater.string name="set_to_sell_to_other"> - The selected parcel is set to sell to another party. + 所選地段已設為待售給他人。 </floater.string> <floater.string name="no_public_land"> - The selected area has no public land. + 所選區域內無公共土地。 </floater.string> <floater.string name="not_owned_by_you"> - Land owned by another Resident is selected. -Try selecting a smaller area. + 選取了另一位居民所擁有土地。 +請嘗試選取較小區域。 </floater.string> <floater.string name="processing"> - Processing your purchase... + 正在處理你的購買… -(過程這將會花費一到兩分鐘) +(這過程將會花費一到兩分鐘。) </floater.string> <floater.string name="fetching_error"> - There has been an error while fetching land buying information. + 擷取購地訊息時發生錯誤。 </floater.string> <floater.string name="buying_will"> - Buying this land will: + 購買這塊土地後: </floater.string> <floater.string name="buying_for_group"> - Buying land for group will: + 為群組購買土地後: </floater.string> <floater.string name="cannot_buy_now"> - Cannot buy now: + 現在無法購買: </floater.string> <floater.string name="not_for_sale"> 不出售: </floater.string> <floater.string name="none_needed"> - none needed + 不需要 </floater.string> <floater.string name="must_upgrade"> 你的帳戶必須要升級才能擁有土地。 @@ -77,52 +77,52 @@ Try selecting a smaller area. 你持有 [BUYER] m² 土地。 </floater.string> <floater.string name="pay_to_for_land"> - Pay L$ [AMOUNT] to [SELLER] for this land + 支付 L$ [AMOUNT] 給 [SELLER] 購買這土地 </floater.string> <floater.string name="buy_for_US"> - Buy L$ [AMOUNT] for approx. [LOCAL_AMOUNT], + 購買 L$ [AMOUNT],所需花費約為 [LOCAL_AMOUNT], </floater.string> <floater.string name="parcel_meters"> - 這個地段為 [AMOUNT] m² + 這個地段有 [AMOUNT] 平方公尺 </floater.string> <floater.string name="premium_land"> - This land is premium, and will charge as [AMOUNT] m². + 這土地屬於高價地段,將計為 [AMOUNT] 平方公尺。 </floater.string> <floater.string name="discounted_land"> - This land is discounted, and will charge as [AMOUNT] m². + 這土地有折扣,將計為 [AMOUNT] 平方公尺。 </floater.string> <floater.string name="meters_supports_object"> - [AMOUNT] m² -supports [AMOUNT2] objects + [AMOUNT] 平方公尺 +支援 [AMOUNT2] 項物件 </floater.string> <floater.string name="sold_with_objects"> - sold with objects + 含物件出售 </floater.string> <floater.string name="sold_without_objects"> - objects not included + 不含物件 </floater.string> <floater.string name="info_price_string"> - L$ [PRICE] -(L$ [PRICE_PER_SQM]/m²) + L$[PRICE] +(L$ [PRICE_PER_SQM]/平方公尺) [SOLD_WITH_OBJECTS] </floater.string> <floater.string name="insufficient_land_credits"> - The group [GROUP] will need sufficient contributed land use credits to cover this parcel before the purchase will complete. + 群組 [GROUP] 需先有足夠的捐地使用額度來支應這個地段,才可完成購買。 </floater.string> <floater.string name="have_enough_lindens"> - You have L$ [AMOUNT], which is enough to buy this land. + 你有 L$ [AMOUNT],足以購買這土地。 </floater.string> <floater.string name="not_enough_lindens"> - You have only L$ [AMOUNT], and need L$ [AMOUNT2] more. + 你只有 L$ [AMOUNT],尚缺 L$ [AMOUNT2]。 </floater.string> <floater.string name="balance_left"> - After the purchase, you will have L$ [AMOUNT] left. + 購買後,你將剩餘 L$ [AMOUNT]。 </floater.string> <floater.string name="balance_needed"> - You need to buy at least L$ [AMOUNT] to afford this land. + 你至少必須購買 L$ [AMOUNT] 才能添購這土地。 </floater.string> <floater.string name="no_parcel_selected"> - (無地段被選擇) + (未選擇地段) </floater.string> <text name="region_name_label"> 地區: @@ -143,27 +143,27 @@ supports [AMOUNT2] objects (未知) </text> <text name="estate_owner_label"> - 領地擁有者: + 領地所有人: </text> <text name="estate_owner_text"> (未知) </text> <text name="resellable_changeable_label"> - Purchased land in this region: + 在本地區已購土地: </text> <text name="resellable_clause"> - May or may not be resold. + 是否可再售出。 </text> <text name="changeable_clause"> - May or may not be joined or subdivided. + 是否可合併或分割。 </text> <text name="covenant_text"> - You must agree to the Estate Covenant: + 你必須同意領地契約: </text> <text_editor name="covenant_editor"> 載入中... </text_editor> - <check_box label="I Agree to the Covenant Defined Above." name="agree_covenant"/> + <check_box label="我同意以上所訂契約。" name="agree_covenant"/> <text name="info_parcel_label"> 地段: </text> @@ -174,60 +174,60 @@ supports [AMOUNT2] objects 尺寸: </text> <text name="info_size"> - 1024 m² + 1024 平方公尺 </text> <text name="info_price_label"> 價格: </text> <text name="info_price"> L$ 1500 -(L$ 1.1/m²) -sold with objects +(L$ 1.1/平方公尺) +含物件出售 </text> <text name="info_action"> - Buying this land will: + 購買這塊土地後: </text> <text name="error_message"> - Something ain't right. + 恐怕出問題了。 </text> <button label="前往網站" name="error_web"/> <text name="account_action"> - Upgrade you to premium membership. + 將你升級為付費用戶 </text> <text name="account_reason"> - Only premimum members may own land. + 只有付費用戶才能擁有土地。 </text> <combo_box name="account_level"> - <combo_box.item label="US$9.95/month, billed monthly" name="US$9.95/month,billedmonthly"/> - <combo_box.item label="US$7.50/month, billed quarterly" name="US$7.50/month,billedquarterly"/> - <combo_box.item label="US$6.00/month, billed annually" name="US$6.00/month,billedannually"/> + <combo_box.item label="每月 US$9.95,按月支付" name="US$9.95/month,billedmonthly"/> + <combo_box.item label="每月 US$7.50,按季支付" name="US$7.50/month,billedquarterly"/> + <combo_box.item label="每月 US$6.00,一年支付一次" name="US$6.00/month,billedannually"/> </combo_box> <text name="land_use_action"> - Increase your monthly land use fees to US$ 40/month. + 將你的每月土地使用費增加為每月 US$ 40。 </text> <text name="land_use_reason"> - You hold 1309 m² of land. -This parcel is 512 m² of land. + 你持有 1309 平方公尺土地。 +這地段有 512 平方公尺的土地。 </text> <text name="purchase_action"> - Pay Joe Resident L$ 4000 for the land + 支付給居民 Joe L$ 4000 購買土地 </text> <text name="currency_reason"> - You have L$ 2,100. + 你有 L$ 2,100。 </text> <text name="currency_action"> - Buy additional L$ + 購買更多 L$ </text> <line_editor name="currency_amt"> 1000 </line_editor> <text name="currency_est"> - for approx. [LOCAL_AMOUNT] + 花費大約 [LOCAL_AMOUNT] </text> <text name="currency_balance"> - You have L$ 2,100. + 你有 L$ 2,100。 </text> - <check_box label="Remove [AMOUNT] m² of contribution from group." name="remove_contribution"/> - <button label="Purchase" name="buy_btn"/> + <check_box label="從群組移除 [AMOUNT] 平方公尺的捐出地。" name="remove_contribution"/> + <button label="購買" name="buy_btn"/> <button label="取消" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_object.xml b/indra/newview/skins/default/xui/zh/floater_buy_object.xml index 507e482766..ff4a1feedb 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_object.xml @@ -4,25 +4,25 @@ 購買 </floater.string> <floater.string name="title_buy_copy_text"> - Buy a copy of + 購買一個 </floater.string> <floater.string name="no_copy_text"> - (no copy) + (禁止複製) </floater.string> <floater.string name="no_modify_text"> - (no modify) + (禁止修改) </floater.string> <floater.string name="no_transfer_text"> - (no transfer) + (禁止轉讓) </floater.string> <text name="contents_text"> - Contains: + 內含: </text> <text name="buy_text"> - Buy for L$[AMOUNT] from: + 購買,支付 L$[AMOUNT] 給: </text> <text name="buy_name_text"> - [NAME]? + [NAME]? </text> <button label="購買" label_selected="購買" name="buy_btn"/> <button label="取消" label_selected="取消" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_camera.xml b/indra/newview/skins/default/xui/zh/floater_camera.xml index b75474340c..becb7b9546 100644 --- a/indra/newview/skins/default/xui/zh/floater_camera.xml +++ b/indra/newview/skins/default/xui/zh/floater_camera.xml @@ -1,13 +1,22 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="camera_floater"> +<floater name="camera_floater" title="攝影機控制"> <floater.string name="rotate_tooltip"> - Rotate Camera Around Focus + 繞著焦點轉動攝影機 </floater.string> <floater.string name="zoom_tooltip"> - Zoom Camera Towards Focus + 攝影機移近焦點 </floater.string> <floater.string name="move_tooltip"> - Move Camera Up and Down, Left and Right + 攝影機上下左右移動 + </floater.string> + <floater.string name="camera_modes_title"> + 攝影機模式 + </floater.string> + <floater.string name="pan_mode_title"> + 環繞縮放平移 + </floater.string> + <floater.string name="presets_mode_title"> + 預設視角 </floater.string> <floater.string name="free_mode_title"> 視角物件 @@ -43,14 +52,14 @@ </panel_camera_item> </panel> <panel name="zoom"> - <joystick_rotate name="cam_rotate_stick" tool_tip="Orbit camera around focus"/> - <slider_bar name="zoom_slider" tool_tip="Zoom camera toward focus"/> + <joystick_rotate name="cam_rotate_stick" tool_tip="攝影機繞焦點旋轉"/> + <slider_bar name="zoom_slider" tool_tip="攝影機移近焦點"/> <joystick_track name="cam_track_stick" tool_tip="移動攝影機上下左右"/> </panel> </panel> <panel name="buttons"> <button label="" name="presets_btn" tool_tip="預設視角"/> - <button label="" name="pan_btn" tool_tip="Orbit Zoom Pan"/> + <button label="" name="pan_btn" tool_tip="環繞縮放平移"/> <button label="" name="avatarview_btn" tool_tip="攝影機模式"/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_chat_bar.xml b/indra/newview/skins/default/xui/zh/floater_chat_bar.xml new file mode 100644 index 0000000000..f1a69a7688 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_chat_bar.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="chat_bar" title="附近的聊天"> + <panel name="bottom_panel"> + <line_editor label="點按此處開始聊天。" name="chat_box" tool_tip="按下 Enter 鍵來說或按下 Ctrl+Enter 來喊叫"/> + <button name="show_nearby_chat" tool_tip="顯示 / 隱藏 附近的聊天紀錄"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_color_picker.xml b/indra/newview/skins/default/xui/zh/floater_color_picker.xml index a7ac78e419..fa7b795d4f 100644 --- a/indra/newview/skins/default/xui/zh/floater_color_picker.xml +++ b/indra/newview/skins/default/xui/zh/floater_color_picker.xml @@ -10,13 +10,13 @@ 藍色: </text> <text name="h_val_text"> - Hue: + 色調: </text> <text name="s_val_text"> - Sat: + 飽和度: </text> <text name="l_val_text"> - Lum: + 亮度: </text> <check_box label="立即套用" name="apply_immediate"/> <button label="確定" label_selected="確定" name="select_btn"/> @@ -25,6 +25,6 @@ 目前顏色: </text> <text name="(Drag below to save.)"> - (Drag below to save) + (拖曳到下方即可儲存) </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml new file mode 100644 index 0000000000..4aafb31952 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<floater name="Delete Env Preset" title="刪除環境自訂配置"> + <string name="title_water"> + 刪除水的自訂配置 + </string> + <string name="title_sky"> + 刪除天空自訂配置 + </string> + <string name="title_day_cycle"> + 刪除日循環 + </string> + <string name="label_water"> + 自訂配置: + </string> + <string name="label_sky"> + 自訂配置: + </string> + <string name="label_day_cycle"> + 日循環: + </string> + <string name="msg_confirm_deletion"> + 確定要刪除所選自訂配置? + </string> + <string name="msg_sky_is_referenced"> + 無法刪除日循環有所指涉的自訂配置。 + </string> + <string name="combo_label"> + -選擇一個自訂配置- + </string> + <text name="label"> + 自訂配置: + </text> + <button label="刪除" name="delete"/> + <button label="取消" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_destinations.xml b/indra/newview/skins/default/xui/zh/floater_destinations.xml new file mode 100644 index 0000000000..f50a6a631a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_destinations.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Destinations" title="目的地"/> diff --git a/indra/newview/skins/default/xui/zh/floater_display_name.xml b/indra/newview/skins/default/xui/zh/floater_display_name.xml index 01b5088794..aa71bba769 100644 --- a/indra/newview/skins/default/xui/zh/floater_display_name.xml +++ b/indra/newview/skins/default/xui/zh/floater_display_name.xml @@ -1,18 +1,18 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Display Name" title="變更顯示名稱"> <text name="info_text"> - The name you give your avatar is called your Display Name. You can change it once a week. + 你為你的化身取的名字叫做「顯示名稱」。 一星期可以修改一次。 </text> <text name="lockout_text"> - You cannot change your Display Name until: [TIME]. + 你下次能再更改顯示名稱的時間為 [TIME]。 </text> <text name="set_name_label"> 新顯示名稱: </text> <text name="name_confirm_label"> - Type your new name again to confirm: + 再次輸入你的新名稱以便確認: </text> - <button label="儲存" name="save_btn" tool_tip="儲存你的新顯示名稱"/> - <button label="重設" name="reset_btn" tool_tip="Make Display Name the same as Username"/> + <button label="儲存" name="save_btn" tool_tip="儲存你的新的顯示名稱"/> + <button label="重設" name="reset_btn" tool_tip="將顯示名稱設成和使用者名稱相同"/> <button label="取消" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml new file mode 100644 index 0000000000..b84a4027ea --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Edit Day cycle" title="編輯日循環"> + <string name="title_new"> + 新建一個日循環 + </string> + <string name="title_edit"> + 編輯日循環 + </string> + <string name="hint_new"> + 為日循環定名,調整各項控制確定細節,再點按「儲存」。 + </string> + <string name="hint_edit"> + 若要編輯你的日循環,請調整下方各項控制,再點按「儲存」。 + </string> + <string name="combo_label"> + -選擇一個自訂配置- + </string> + <text name="label"> + 自訂配置名稱: + </text> + <text name="note"> + 注意:更改自訂配置的名稱將會新建一個自訂配置,不會改變原有的自訂配置。 + </text> + <text name="hint_item1"> + - 點按一個頁籤,編輯特定的天空設定和時間。 + </text> + <text name="hint_item2"> + - 點按並拖曳各個頁籤,即可設定過渡時間。 + </text> + <text name="hint_item3"> + - 使用 scrubber 預覽你的日循環。 + </text> + <panel name="day_cycle_slider_panel"> + <multi_slider initial_value="0" name="WLTimeSlider"/> + <multi_slider initial_value="0" name="WLDayCycleKeys"/> + <button label="新增鍵" label_selected="新增鍵" name="WLAddKey"/> + <button label="刪除鍵" label_selected="刪除鍵" name="WLDeleteKey"/> + <text name="WL12am"> + 午夜 12 點 + </text> + <text name="WL3am"> + 凌晨 3 點 + </text> + <text name="WL6am"> + 上午 6 點 + </text> + <text name="WL9amHash"> + 上午 9 點 + </text> + <text name="WL12pmHash"> + 中午 12 點 + </text> + <text name="WL3pm"> + 下午 3 點 + </text> + <text name="WL6pm"> + 下午 6 點 + </text> + <text name="WL9pm"> + 下午 9 點 + </text> + <text name="WL12am2"> + 午夜 12 點 + </text> + <text name="WL12amHash"> + | + </text> + <text name="WL3amHash"> + I + </text> + <text name="WL6amHash"> + | + </text> + <text name="WL9amHash2"> + I + </text> + <text name="WL12pmHash2"> + | + </text> + <text name="WL3pmHash"> + I + </text> + <text name="WL6pmHash"> + | + </text> + <text name="WL9pmHash"> + I + </text> + <text name="WL12amHash2"> + | + </text> + </panel> + <text name="WLCurKeyPresetText"> + 天空設定: + </text> + <combo_box label="預設值" name="WLSkyPresets"/> + <text name="WLCurKeyTimeText"> + 時間: + </text> + <time name="time" value="上午 6 點"/> + <check_box label="根據這設定變更我的日循環" name="make_default_cb"/> + <button label="儲存" name="save"/> + <button label="取消" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml new file mode 100644 index 0000000000..1ff832cdc4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Edit Sky Preset" title="編輯天空自訂配置"> + <string name="title_new"> + 建立新的天空自訂配置 + </string> + <string name="title_edit"> + 編輯天空自訂配置 + </string> + <string name="hint_new"> + 為自訂配置定名,調整各項控制確定配置細節,完成後點按「儲存」。 + </string> + <string name="hint_edit"> + 若要編輯你的天空自訂配置,請調整各項控制,再點按「儲存」。 + </string> + <string name="combo_label"> + -選擇一個自訂配置- + </string> + <text name="hint"> + 若要編輯你的自訂配置,請調整各項控制,再點按「儲存」。 + </text> + <text name="label"> + 自訂配置名稱: + </text> + <text name="note"> + 注意:更改自訂配置的名稱將會新建一個自訂配置,不會改變原有的自訂配置。 + </text> + <tab_container name="WindLight Tabs"> + <panel label="大氣" name="Atmosphere"> + <text name="BHText"> + 藍天水平線 + </text> + <text name="BDensText"> + 陰霾水平線 + </text> + <text name="BDensText2"> + 藍天密度 + </text> + <text name="HDText"> + 陰霾密度 + </text> + <text name="DensMultText"> + 密度倍增 + </text> + <text name="WLDistanceMultText"> + 距離倍增 + </text> + <text name="MaxAltText"> + 最大高度 + </text> + </panel> + <panel label="照明" name="Lighting"> + <text name="SLCText"> + 日/月 顏色 + </text> + <text name="WLAmbientText"> + 環境 + </text> + <text name="SunGlowText"> + 太陽光輝 + </text> + <slider label="聚焦" name="WLGlowB"/> + <slider label="尺寸" name="WLGlowR"/> + <text name="WLStarText"> + 星空亮度 + </text> + <text name="SceneGammaText"> + 場景 Gamma 值 + </text> + <text name="TODText"> + 日/月 位置 + </text> + <multi_slider initial_value="0" name="WLSunPos"/> + <text name="WL12amHash"> + | + </text> + <text name="WL6amHash"> + | + </text> + <text name="WL12pmHash2"> + | + </text> + <text name="WL6pmHash"> + | + </text> + <text name="WL12amHash2"> + | + </text> + <text name="WL12am"> + 午夜 12 點 + </text> + <text name="WL6am"> + 上午 6 點 + </text> + <text name="WL12pmHash"> + 中午 12 點 + </text> + <text name="WL6pm"> + 下午 6 點 + </text> + <text name="WL12am2"> + 午夜 12 點 + </text> + <time name="WLDayTime" value="上午 6 點"/> + <text name="WLEastAngleText"> + 東升角度 + </text> + </panel> + <panel label="雲彩" name="Clouds"> + <text name="WLCloudColorText"> + 雲彩顏色 + </text> + <text name="WLCloudColorText2"> + 雲彩 XY 軸 / 密度 + </text> + <slider label="X" name="WLCloudX"/> + <slider label="Y" name="WLCloudY"/> + <slider label="D" name="WLCloudDensity"/> + <text name="WLCloudCoverageText"> + 雲彩覆蓋 + </text> + <text name="WLCloudScaleText"> + 雲彩規模 + </text> + <text name="WLCloudDetailText"> + 雲彩細節(XY 軸 / 密度) + </text> + <slider label="X" name="WLCloudDetailX"/> + <slider label="Y" name="WLCloudDetailY"/> + <slider label="D" name="WLCloudDetailDensity"/> + <text name="WLCloudScrollXText"> + 雲彩 X 滾軸 + </text> + <check_box label="鎖定" name="WLCloudLockX"/> + <text name="WLCloudScrollYText"> + 雲彩 Y 滾軸 + </text> + <check_box label="鎖定" name="WLCloudLockY"/> + </panel> + </tab_container> + <check_box label="根據這自訂配置變更我的天空設定" name="make_default_cb"/> + <button label="儲存" name="save"/> + <button label="取消" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml new file mode 100644 index 0000000000..7943866e72 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Edit Water Preset" title="編輯水的自訂配置"> + <string name="title_new"> + 新建水的自訂配置 + </string> + <string name="title_edit"> + 編輯水的自訂配置 + </string> + <string name="hint_new"> + 為自訂配置定名,調整各項控制確定配置細節,完成後點按「儲存」。 + </string> + <string name="hint_edit"> + 若要編輯水的自訂配置,請調整各項控制,再點按「儲存」。 + </string> + <string name="combo_label"> + -選擇一個自訂配置- + </string> + <text name="hint"> + 若要編輯你的自訂配置,請調整各項控制,再點按「儲存」。 + </text> + <text name="label"> + 自訂配置名稱: + </text> + <text name="note"> + 注意:更改自訂配置的名稱將會新建一個自訂配置,不會改變原有的自訂配置。 + </text> + <panel name="panel_water_preset"> + <text name="water_color_label"> + 水霧顏色 + </text> + <text name="water_fog_density_label"> + 霧密度指數 + </text> + <text name="underwater_fog_modifier_label"> + 水底霧修飾元 + </text> + <text name="BHText"> + 大波浪方向 + </text> + <slider label="X" name="WaterWave1DirX"/> + <slider label="Y" name="WaterWave1DirY"/> + <text name="BDensText"> + 反射子波比例 + </text> + <text name="HDText"> + 菲涅耳比例 + </text> + <text name="FresnelOffsetText"> + 菲涅耳偏距 + </text> + <text name="BHText2"> + 小波浪方向 + </text> + <slider label="X" name="WaterWave2DirX"/> + <slider label="Y" name="WaterWave2DirY"/> + <text name="DensMultText"> + 上折射比例 + </text> + <text name="WaterScaleBelowText"> + 下折射比例 + </text> + <text name="MaxAltText"> + 模糊倍數 + </text> + <text name="BHText3"> + 正常地圖 + </text> + </panel> + <check_box label="根據這自訂配置變更我水的設定" name="make_default_cb"/> + <button label="儲存" name="save"/> + <button label="取消" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_env_settings.xml b/indra/newview/skins/default/xui/zh/floater_env_settings.xml deleted file mode 100644 index 534ee7f0d0..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_env_settings.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Environment Editor Floater" title="ENVIRONMENT EDITOR"> - <floater.string name="timeStr"> - [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc] - </floater.string> - <text name="EnvTimeText"> - Time of Day - </text> - <text name="EnvTimeText2"> - 12:00 PM - </text> - <text name="EnvCloudText"> - Cloud Cover - </text> - <text name="EnvWaterColorText"> - 水色 - </text> - <color_swatch name="EnvWaterColor" tool_tip="Click to open color picker"/> - <text name="EnvWaterFogText"> - 水霧 - </text> - <button label="Use Estate Time" name="EnvUseEstateTimeButton"/> - <button label="進階天空" name="EnvAdvancedSkyButton"/> - <button label="進階水文" name="EnvAdvancedWaterButton"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_environment_settings.xml b/indra/newview/skins/default/xui/zh/floater_environment_settings.xml new file mode 100644 index 0000000000..1c6f2f936d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_environment_settings.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Environment Editor Floater" title="環境設定"> + <text name="note"> + 使用以下的選項自訂你 Viewer 的環境設定。 + </text> + <radio_group name="region_settings_radio_group"> + <radio_item label="使用地區設定" name="use_region_settings"/> + <radio_item label="自訂我的環境" name="use_my_settings"/> + </radio_group> + <panel name="user_environment_settings"> + <text name="note"> + 注意:你的自訂設定不會被其他使用者看見。 + </text> + <text name="water_settings_title"> + 水的設定 + </text> + <combo_box name="water_settings_preset_combo"> + <combo_box.item label="-選擇一個自訂配置-" name="item0"/> + </combo_box> + <text name="sky_dayc_settings_title"> + 天空 / 日循環 + </text> + <radio_group name="sky_dayc_settings_radio_group"> + <radio_item label="固定天空" name="my_sky_settings"/> + <radio_item label="日循環" name="my_dayc_settings"/> + </radio_group> + <combo_box name="sky_settings_preset_combo"> + <combo_box.item label="-選擇一個自訂配置-" name="item0"/> + </combo_box> + <combo_box name="dayc_settings_preset_combo"> + <combo_box.item label="-選擇一個自訂配置-" name="item0"/> + </combo_box> + </panel> + <button label="確定" name="ok_btn"/> + <button label="取消" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_event.xml b/indra/newview/skins/default/xui/zh/floater_event.xml index 349b5717f2..7175731fef 100644 --- a/indra/newview/skins/default/xui/zh/floater_event.xml +++ b/indra/newview/skins/default/xui/zh/floater_event.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Event" name="Event" title="EVENT DETAILS"> +<floater label="活動" name="Event" title="活動細節"> <floater.string name="loading_text"> 載入中... </floater.string> <floater.string name="done_text"> - Done + 完成 </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_fast_timers.xml b/indra/newview/skins/default/xui/zh/floater_fast_timers.xml new file mode 100644 index 0000000000..871849305c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_fast_timers.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="fast_timers"> + <string name="pause"> + 暫停 + </string> + <string name="run"> + 跑步 + </string> + <button label="暫停" name="pause_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_gesture.xml b/indra/newview/skins/default/xui/zh/floater_gesture.xml index a809cf085c..e7b1ed1de3 100644 --- a/indra/newview/skins/default/xui/zh/floater_gesture.xml +++ b/indra/newview/skins/default/xui/zh/floater_gesture.xml @@ -7,17 +7,17 @@ (播放中) </floater.string> <floater.string name="copy_name"> - Copy of [COPY_NAME] + [COPY_NAME] 複本 </floater.string> <scroll_list name="gesture_list"> <scroll_list.columns label="名稱" name="name"/> <scroll_list.columns label="聊天" name="trigger"/> - <scroll_list.columns label="Key" name="shortcut"/> + <scroll_list.columns label="鍵" name="shortcut"/> </scroll_list> <panel label="bottom_panel" name="bottom_panel"> <menu_button name="gear_btn" tool_tip="更多選項"/> <button name="new_gesture_btn" tool_tip="製作新姿勢e"/> - <button name="activate_btn" tool_tip="Activate/Deactivate selected gesture"/> + <button name="activate_btn" tool_tip="啟動/停止所選姿勢"/> <button name="del_btn" tool_tip="刪除這個姿勢"/> </panel> <button label="編輯" name="edit_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_god_tools.xml b/indra/newview/skins/default/xui/zh/floater_god_tools.xml index 448113bf74..69a6eadc8c 100644 --- a/indra/newview/skins/default/xui/zh/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/zh/floater_god_tools.xml @@ -8,42 +8,42 @@ <text name="Region Name:"> 地區名稱: </text> - <check_box label="Prelude" name="check prelude" tool_tip="Set this to make the region a prelude"/> - <check_box label="固定太陽" name="check fixed sun" tool_tip="Fix the sun position (like in Region/Estate > Terrain"/> - <check_box label="Reset Home On Teleport" name="check reset home" tool_tip="When Resident teleports out, reset their home to the destination position."/> - <check_box label="Visible" name="check visible" tool_tip="Set this to make the region visible to non-gods"/> - <check_box label="傷害" name="check damage" tool_tip="Set this to enable damage in this region"/> - <check_box label="阻止流量追蹤" name="block dwell" tool_tip="Set this to make the region not compute traffic"/> - <check_box label="阻止變形" name="block terraform" tool_tip="Set this to disallow people terraforming their land"/> - <check_box label="沙盒" name="is sandbox" tool_tip="Toggle whether this is a sandbox region"/> - <button label="Bake Terrain" label_selected="Bake Terrain" name="Bake Terrain" tool_tip="儲存目前的地形為預設"/> - <button label="Revert Terrain" label_selected="Revert Terrain" name="Revert Terrain" tool_tip="Replace the current terrain with default"/> - <button label="Swap Terrain" label_selected="Swap Terrain" name="Swap Terrain" tool_tip="Swap current terrain with default"/> + <check_box label="導引區" name="check prelude" tool_tip="在此設定,將區域設為導引區"/> + <check_box label="固定太陽" name="check fixed sun" tool_tip="固定太陽位置(如同地區/領地 > 地形)"/> + <check_box label="瞬間傳送時重設家的位置" name="check reset home" tool_tip="居民瞬間傳送離開時,將他們的家重設為瞬間傳送的目的地。"/> + <check_box label="可看到" name="check visible" tool_tip="在此設定,將區域設為可讓非神者看到。"/> + <check_box label="傷害" name="check damage" tool_tip="在此設定,使本地區允許傷害。"/> + <check_box label="阻止流量追蹤" name="block dwell" tool_tip="在此設定,使本區域不計算流量。"/> + <check_box label="阻止土地變形" name="block terraform" tool_tip="設定禁止人們將其土地變形。"/> + <check_box label="沙盤" name="is sandbox" tool_tip="切換是否設為沙盤區域。"/> + <button label="確定地形" label_selected="確定地形" name="Bake Terrain" tool_tip="將目前的地形儲存為預設值"/> + <button label="回復原地形" label_selected="回復原地形" name="Revert Terrain" tool_tip="以預設值取代目前的地形"/> + <button label="交換地形" label_selected="交換地形" name="Swap Terrain" tool_tip="將目前的地形和預設值交換"/> <text name="estate id"> 領地 ID: </text> <text name="parent id"> - Parent ID: + 母領地 ID: </text> - <line_editor name="parentestate" tool_tip="This is the parent estate for this region"/> + <line_editor name="parentestate" tool_tip="這是本區域的母領地"/> <text name="Grid Pos: "> 網格位置: </text> - <line_editor name="gridposx" tool_tip="This is the grid x position for this region"/> - <line_editor name="gridposy" tool_tip="This is the grid y position for this region"/> + <line_editor name="gridposx" tool_tip="這是本區域的網格 X 位置"/> + <line_editor name="gridposy" tool_tip="這是本區域的網格 Y 位置"/> <text name="Redirect to Grid: "> - Redirect to Grid: + 重新導向至網格: </text> <text name="billable factor text"> - Billable Factor: + 收費率: </text> <text name="land cost text"> - L$ per m²: + 每平方公尺 L$: </text> - <button label="重新整理" label_selected="重新整理" name="Refresh" tool_tip="Click here to refresh the above information"/> - <button label="套用" label_selected="套用" name="Apply" tool_tip="點擊此處以接受套用上述變更"/> - <button label="選擇地區" label_selected="選擇地區" name="Select Region" tool_tip="Select the whole region with the land tool"/> - <button label="立即自動儲存" label_selected="立即自動儲存" name="Autosave now" tool_tip="Save gzipped state to autosave directory"/> + <button label="重新整理" label_selected="重新整理" name="Refresh" tool_tip="點按這裡刷新上列資料"/> + <button label="套用" label_selected="套用" name="Apply" tool_tip="點按此處以接受套用上述變更"/> + <button label="選擇地區" label_selected="選擇地區" name="Select Region" tool_tip="以土地工具選取整個區域"/> + <button label="立即自動儲存" label_selected="立即自動儲存" name="Autosave now" tool_tip="儲存 gzip 壓縮狀態至自動儲存目錄"/> </panel> <panel label="物件" name="objects"> <panel.string name="no_target"> @@ -53,44 +53,44 @@ 地區名稱: </text> <text name="region name"> - Welsh + 威爾斯 </text> <check_box label="關閉腳本" name="disable scripts" tool_tip="關閉這個地區現在的全部腳本"/> - <check_box label="Disable Collisions" name="disable collisions" tool_tip="Set this to disable non-agent collisions in this region"/> - <check_box label="Disable Physics" name="disable physics" tool_tip="Set this to disable all physics in this region"/> - <button label="套用" label_selected="套用" name="Apply" tool_tip="Click here to apply any changes from above"/> - <button label="Set Target" label_selected="Set Target" name="Set Target" tool_tip="Set the target avatar for object deletion"/> + <check_box label="禁止碰撞" name="disable collisions" tool_tip="設置關閉地區內除了人以外的碰撞"/> + <check_box label="關閉物理" name="disable physics" tool_tip="設置關閉本區域內所有物理"/> + <button label="套用" label_selected="套用" name="Apply" tool_tip="點按此處以接受套用上述變更"/> + <button label="設定目標" label_selected="設定目標" name="Set Target" tool_tip="將目標化身設為待刪除的物件"/> <text name="target_avatar_name"> (無目標) </text> - <button label="Delete Target's Scripted Objects On Others Land" label_selected="Delete Target's Scripted Objects On Others Land" name="Delete Target's Scripted Objects On Others Land" tool_tip="Delete all scripted objects owned by the target on land not owned by the target. (no copy) objects will be returned."/> - <button label="Delete Target's Scripted Objects On *Any* Land" label_selected="Delete Target's Scripted Objects On *Any* Land" name="Delete Target's Scripted Objects On *Any* Land" tool_tip="Delete all scripted objects owned by the target in this region. (no copy) objects will be returned."/> - <button label="Delete *ALL* Of Target's Objects" label_selected="Delete *ALL* Of Target's Objects" name="Delete *ALL* Of Target's Objects" tool_tip="Delete all objects owned by the target in this region. (no copy) objects will be returned."/> - <button label="Get Top Colliders" label_selected="Get Top Colliders" name="Get Top Colliders" tool_tip="Gets list of objects experiencing the most narrowphase callbacks"/> - <button label="Get Top Scripts" label_selected="Get Top Scripts" name="Get Top Scripts" tool_tip="Gets list of objects spending the most time running scripts"/> - <button label="Scripts digest" label_selected="Scripts digest" name="Scripts digest" tool_tip="Gets a list of all scripts and number of occurences of each"/> + <button label="刪除目標物在其他土地的帶腳本的物件" label_selected="刪除目標物在其他土地的帶腳本的物件" name="Delete Target's Scripted Objects On Others Land" tool_tip="在不是目標物所擁有的土地上,刪除屬於該目標物的所有帶腳本的物件。 「禁止複製」的物件將被送回。"/> + <button label="刪除目標物在任何土地的帶腳本的物件" label_selected="刪除目標物在任何土地的帶腳本的物件" name="Delete Target's Scripted Objects On *Any* Land" tool_tip="刪除本區域內屬於目標物的所有帶腳本的物件。 「禁止複製」的物件將被送回。"/> + <button label="刪除目標物所有的物件" label_selected="刪除目標物所有的物件" name="Delete *ALL* Of Target's Objects" tool_tip="刪除本區域內屬於目標物的所有物件。 「禁止複製」的物件將被送回。"/> + <button label="取得最常碰撞的物件" label_selected="取得最常碰撞的物件" name="Get Top Colliders" tool_tip="取得經歷最多次「窄相」回調的物件清單"/> + <button label="取得排名最高的腳本" label_selected="取得排名最高的腳本" name="Get Top Scripts" tool_tip="取得花最多時間執行腳本的物件清單"/> + <button label="腳本集" label_selected="腳本集" name="Scripts digest" tool_tip="取得所有腳本清單,並列出發生次數,針對每一"/> </panel> - <panel label="Request" name="request"> + <panel label="請求" name="request"> <text name="Destination:"> - Destination: + 目的地: </text> <combo_box name="destination"> - <combo_box.item label="Selection" name="item1"/> - <combo_box.item label="Agent Region" name="item2"/> + <combo_box.item label="選擇" name="item1"/> + <combo_box.item label="用戶地區" name="item2"/> </combo_box> <text name="Request:"> - Request: + 請求: </text> <combo_box name="request"> - <combo_box.item label="colliders <steps>" name="item1"/> - <combo_box.item label="scripts <count>,<optional pattern>" name="item2"/> - <combo_box.item label="objects <pattern>" name="item3"/> + <combo_box.item label="碰撞物 <步驟>" name="item1"/> + <combo_box.item label="腳本 <計數>,<非必要形態>" name="item2"/> + <combo_box.item label="物件 <形態>" name="item3"/> <combo_box.item label="rez <asset_id>" name="item4"/> </combo_box> <text name="Parameter:"> - Parameter: + 參數: </text> - <button label="Make Request" label_selected="Make Request" name="Make Request"/> + <button label="提出請求" label_selected="提出請求" name="Make Request"/> </panel> </tab_container> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml index 1465dcb256..9e3bb88ac0 100644 --- a/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Hardware Settings Floater" title="硬體設定"> <text name="Filtering:"> - Filtering: + 過濾: </text> - <check_box label="Anisotropic Filtering (slower when enabled)" name="ani"/> - <text name="Antialiasing:"> - Antialiasing: + <check_box label="各向異性過濾(若啟用會變慢)" name="ani"/> + <text name="antialiasing label"> + 消除鋸齒: </text> - <combo_box label="Antialiasing" name="fsaa"> - <combo_box.item label="Disabled" name="FSAADisabled"/> + <combo_box label="消除鋸齒" name="fsaa"> + <combo_box.item label="已停用" name="FSAADisabled"/> <combo_box.item label="2x" name="2x"/> <combo_box.item label="4x" name="4x"/> <combo_box.item label="8x" name="8x"/> @@ -17,15 +17,19 @@ <text name="antialiasing restart"> (須重新啟動瀏覽器) </text> - <spinner label="Gamma:" name="gamma"/> + <spinner label="伽瑪值:" name="gamma"/> <text name="(brightness, lower is brighter)"> - (0 = default brightness, lower = brighter) + (0 = 預設亮度;值越小 = 亮度越高) </text> <text name="Enable VBO:"> - Enable VBO: + 啟用頂點緩衝物件(VBO): </text> - <check_box initial_value="true" label="Enable OpenGL Vertex Buffer Objects" name="vbo" tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."/> - <slider label="材質記憶體(MB):" name="GraphicsCardTextureMemory" tool_tip="Amount of memory to allocate for textures. Defaults to video card memory. Reducing this may improve performance but may also make textures blurry."/> - <spinner label="Fog Distance Ratio:" name="fog"/> + <check_box initial_value="true" label="啟用 OpenGL 頂點緩衝物件(VBO)" name="vbo" tool_tip="在較新硬體上啟用,可提升效能。 但是,較舊硬體的 VBO 實作不佳,若啟用可能導致當機。"/> + <text name="tc label"> + 啟用 S3TC: + </text> + <check_box initial_value="true" label="啟用材質壓縮(須重新啟動)" name="texture compression" tool_tip="在影片記憶體中壓縮材質,讓高解析度材質可以載入,但色彩品質稍差。"/> + <slider label="材質記憶體(MB):" name="GraphicsCardTextureMemory" tool_tip="配置給材質使用的記憶體量。 預設為顯像卡記憶體。 降低此值可以提升效能,但材質也會變模糊。"/> + <spinner label="霧距離比率:" name="fog"/> <button label="確定" label_selected="確定" name="OK"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_how_to.xml b/indra/newview/skins/default/xui/zh/floater_how_to.xml new file mode 100644 index 0000000000..e033327165 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_how_to.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_how_to" title="簡易教學"/> diff --git a/indra/newview/skins/default/xui/zh/floater_im_session.xml b/indra/newview/skins/default/xui/zh/floater_im_session.xml index e8db97560e..808a0b6720 100644 --- a/indra/newview/skins/default/xui/zh/floater_im_session.xml +++ b/indra/newview/skins/default/xui/zh/floater_im_session.xml @@ -2,7 +2,7 @@ <floater name="panel_im"> <layout_stack name="im_panels"> <layout_panel> - <line_editor label="To" name="chat_editor"/> + <line_editor label="至" name="chat_editor"/> </layout_panel> </layout_stack> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_image_preview.xml b/indra/newview/skins/default/xui/zh/floater_image_preview.xml index 1260601f90..d2de37fa6a 100644 --- a/indra/newview/skins/default/xui/zh/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/zh/floater_image_preview.xml @@ -26,7 +26,7 @@ 請嘗試儲存圖像為 24 位元 Targa(.tga)格式。 </text> - <check_box label="Use lossless compression" name="lossless_check"/> + <check_box label="使用零失真壓縮" name="lossless_check"/> <button label="取消" name="cancel_btn"/> <button label="上傳(L$[AMOUNT])" name="ok_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_import_collada.xml b/indra/newview/skins/default/xui/zh/floater_import_collada.xml new file mode 100644 index 0000000000..8f6b476ccf --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_import_collada.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Import Collada" title="匯入場景"> + <text name="mesh count"> + 網面:[COUNT] + </text> + <text name="texture count"> + 材質: [COUNT] + </text> + <text name="status"> + 狀態:[STATUS] + </text> + <button label="取消" name="cancel"/> + <button label="確定" name="ok"/> + <string name="status_idle"> + 閒置中 + </string> + <string name="status_uploading"> + 正在上傳 [NAME] + </string> + <string name="status_creating"> + 正在建立 [NAME] 物件 + </string> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml index a0f31fa11f..45a003d3c8 100644 --- a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml @@ -4,28 +4,28 @@ 5 </floater.string> <floater.string name="localchat"> - 附近的音聊天 + 附近的語音聊天 </floater.string> <floater.string name="anonymous"> 匿名 </floater.string> <floater.string name="VoiceInviteP2P"> - 通話中。 + 來電中。 </floater.string> <floater.string name="VoiceInviteAdHoc"> - 已加訴入會議交談中的語音聊天。 + 已加入多方語音通話。 </floater.string> <floater.string name="VoiceInviteGroup"> 剛加入 '[GROUP]' 語音頻道。 </floater.string> <floater.string name="VoiceInviteQuestionGroup"> - Would you like to leave [CURRENT_CHAT] and join the call with '[GROUP]'? + 是否離開 [CURRENT_CHAT] 並加入和「[GROUP]」通話? </floater.string> <floater.string name="VoiceInviteQuestionDefault"> - Do you want to leave [CURRENT_CHAT] and join this voice chat? + 是否離開 [CURRENT_CHAT] 並加入這個語音聊天? </floater.string> <text name="question"> - Do you want to leave [CURRENT_CHAT] and join this voice chat? + 是否離開 [CURRENT_CHAT] 並加入這個語音聊天? </text> <button label="接受" label_selected="接受" name="Accept"/> <button label="拒絕" label_selected="拒絕" name="Reject"/> diff --git a/indra/newview/skins/default/xui/zh/floater_inspect.xml b/indra/newview/skins/default/xui/zh/floater_inspect.xml index ea3d9d0c3e..4e1f4b24fd 100644 --- a/indra/newview/skins/default/xui/zh/floater_inspect.xml +++ b/indra/newview/skins/default/xui/zh/floater_inspect.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="inspect" title="INSPECT OBJECTS"> +<floater name="inspect" title="檢視物件"> <floater.string name="timeStamp"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] </floater.string> - <scroll_list name="object_list" tool_tip="Select an object from this list to highlight it in-world"> + <scroll_list name="object_list" tool_tip="從清單中選取一物件,在虛擬世界中加以高亮顯示。"> <scroll_list.columns label="物件名稱" name="object_name"/> - <scroll_list.columns label="擁有者名稱" name="owner_name"/> + <scroll_list.columns label="所有人名稱" name="owner_name"/> <scroll_list.columns label="創造者名稱" name="creator_name"/> <scroll_list.columns label="創造日期" name="creation_date"/> </scroll_list> - <button label="察看擁有者檔案..." name="button owner" tool_tip="See profile of the highlighted object's owner"/> - <button label="察看創造者檔案..." name="button creator" tool_tip="See profile of the highlighted object's original creator"/> + <button label="察看所有人檔案..." name="button owner" tool_tip="察看高亮顯示的物件的物主個人檔案"/> + <button label="察看創造人檔案..." name="button creator" tool_tip="察看高亮顯示的物件的原創人個人檔案"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory.xml b/indra/newview/skins/default/xui/zh/floater_inventory.xml deleted file mode 100644 index da4619c964..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_inventory.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Inventory" title="我的收納區"> - <panel label="收納區面板" name="Inventory Panel"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml index a41be7ef9a..6998df75f3 100644 --- a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml @@ -10,7 +10,7 @@ 你可以: </floater.string> <floater.string name="owner_can"> - 擁有者可以: + 所有人可以: </floater.string> <floater.string name="acquiredDate"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -26,11 +26,11 @@ </text> <button label="檔案..." name="BtnCreator"/> <text name="LabelOwnerTitle"> - 擁有者: + 所有人: </text> <button label="檔案..." name="BtnOwner"/> <text name="LabelAcquiredTitle"> - Acquired: + 取得於: </text> <text name="LabelAcquiredDate"> Wed May 24 12:50:46 2006 @@ -39,25 +39,25 @@ 你: </text> <check_box label="編輯" name="CheckOwnerModify"/> - <check_box label="覆製" name="CheckOwnerCopy"/> + <check_box label="恚庨" name="CheckOwnerCopy"/> <check_box label="轉售" name="CheckOwnerTransfer"/> <text name="AnyoneLabel"> 任何人: </text> - <check_box label="覆製" name="CheckEveryoneCopy"/> + <check_box label="恚庨" name="CheckEveryoneCopy"/> <text name="GroupLabel"> 群組: </text> <check_box label="分享" name="CheckShareWithGroup"/> <text name="NextOwnerLabel"> - 下一個擁有者: + 下一個所有人: </text> <check_box label="編輯" name="CheckNextOwnerModify"/> - <check_box label="覆製" name="CheckNextOwnerCopy"/> + <check_box label="恚庨" name="CheckNextOwnerCopy"/> <check_box label="轉售" name="CheckNextOwnerTransfer"/> <check_box label="出售" name="CheckPurchase"/> <combo_box name="combobox sale copy"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="恚庨" name="Copy"/> <combo_box.item label="原件" name="Original"/> </combo_box> <spinner label="價格:" name="Edit Cost"/> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml index d698edf5e5..6d1d18b67c 100644 --- a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml @@ -5,16 +5,17 @@ <check_box label="服裝" name="check_clothing"/> <check_box label="姿勢" name="check_gesture"/> <check_box label="地標" name="check_landmark"/> + <check_box label="網面" name="check_mesh"/> <check_box label="記事卡" name="check_notecard"/> - <check_box label="Objects" name="check_object"/> + <check_box label="物件" name="check_object"/> <check_box label="腳本" name="check_script"/> - <check_box label="Sounds" name="check_sound"/> + <check_box label="聲音" name="check_sound"/> <check_box label="材質" name="check_texture"/> - <check_box label="Snapshots" name="check_snapshot"/> + <check_box label="快照" name="check_snapshot"/> <button label="全部" label_selected="全部" name="All"/> <button label="無" label_selected="無" name="None"/> - <check_box label="Always show folders" name="check_show_empty"/> - <check_box label="Since Logoff" name="check_since_logoff"/> + <check_box label="固定顯示資料夾" name="check_show_empty"/> + <check_box label="自上次登出" name="check_since_logoff"/> <text name="- OR -"> - 或 - </text> diff --git a/indra/newview/skins/default/xui/zh/floater_joystick.xml b/indra/newview/skins/default/xui/zh/floater_joystick.xml index 1721f7cd1e..e0b2cf5a1c 100644 --- a/indra/newview/skins/default/xui/zh/floater_joystick.xml +++ b/indra/newview/skins/default/xui/zh/floater_joystick.xml @@ -1,79 +1,79 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Joystick" title="JOYSTICK CONFIGURATION"> +<floater name="Joystick" title="搖桿設置"> <floater.string name="NoDevice"> 未偵測到設備 </floater.string> - <check_box label="Enable Joystick:" name="enable_joystick"/> - <spinner label="X Axis Mapping" name="JoystickAxis1"/> - <spinner label="Y Axis Mapping" name="JoystickAxis2"/> - <spinner label="Z Axis Mapping" name="JoystickAxis0"/> - <spinner label="Pitch Mapping" name="JoystickAxis4"/> - <spinner label="Yaw Mapping" name="JoystickAxis5"/> - <spinner label="Roll Mapping" name="JoystickAxis3"/> - <spinner label="Zoom Mapping" name="JoystickAxis6"/> - <check_box label="Direct Zoom" name="ZoomDirect"/> - <check_box label="3D Cursor" name="Cursor3D"/> - <check_box label="Auto Level" name="AutoLeveling"/> + <check_box label="啟用搖桿:" name="enable_joystick"/> + <spinner label="X 軸映射" name="JoystickAxis1"/> + <spinner label="Y 軸映射" name="JoystickAxis2"/> + <spinner label="Z 軸映射" name="JoystickAxis0"/> + <spinner label="俯仰映射" name="JoystickAxis4"/> + <spinner label="偏擺映射" name="JoystickAxis5"/> + <spinner label="翻滾映射" name="JoystickAxis3"/> + <spinner label="縮放映射" name="JoystickAxis6"/> + <check_box label="直接縮放" name="ZoomDirect"/> + <check_box label="三維游標" name="Cursor3D"/> + <check_box label="自動水平" name="AutoLeveling"/> <text name="Control Modes:"> - Control Modes: + 控制模式: </text> <check_box label="化身" name="JoystickAvatarEnabled"/> <check_box label="建造" name="JoystickBuildEnabled"/> - <check_box label="Flycam" name="JoystickFlycamEnabled"/> - <stat_view label="Joystick Monitor" name="axis_view"> - <stat_bar label="Axis 0" name="axis0"/> - <stat_bar label="Axis 1" name="axis1"/> - <stat_bar label="Axis 2" name="axis2"/> - <stat_bar label="Axis 3" name="axis3"/> - <stat_bar label="Axis 4" name="axis4"/> - <stat_bar label="Axis 5" name="axis5"/> + <check_box label="移動攝影機" name="JoystickFlycamEnabled"/> + <stat_view label="搖桿監控器" name="axis_view"> + <stat_bar label="軸 0" name="axis0"/> + <stat_bar label="軸 1" name="axis1"/> + <stat_bar label="軸 2" name="axis2"/> + <stat_bar label="軸 3" name="axis3"/> + <stat_bar label="軸 4" name="axis4"/> + <stat_bar label="軸 5" name="axis5"/> </stat_view> <text name="XScale"> - X Scale + X 比例 </text> <text name="YScale"> - Y Scale + Y 比例 </text> <text name="ZScale"> - Z Scale + Z 比例 </text> <text name="PitchScale"> - Pitch Scale + 俯仰比例 </text> <text name="YawScale"> - Yaw Scale + 偏擺比例 </text> <text name="RollScale"> - Roll Scale + 翻滾比例 </text> <text name="XDeadZone"> - X Dead Zone + X 死區 </text> <text name="YDeadZone"> - Y Dead Zone + Y 死區 </text> <text name="ZDeadZone"> - Z Dead Zone + Z 死區 </text> <text name="PitchDeadZone"> - Pitch Dead Zone + 俯仰死區 </text> <text name="YawDeadZone"> - Yaw Dead Zone + 偏擺死區 </text> <text name="RollDeadZone"> - Roll Dead Zone + 翻滾死區 </text> <text name="Feathering"> - Feathering + 重量反應 </text> <text name="ZoomScale2"> - Zoom Scale + 縮放比例 </text> <text name="ZoomDeadZone"> - Zoom Dead Zone + 縮放死區 </text> - <button label="SpaceNavigator Defaults" name="SpaceNavigatorDefaults"/> + <button label="SpaceNavigator 預設值" name="SpaceNavigatorDefaults"/> <button label="確定" label_selected="確定" name="ok_btn"/> <button label="取消" label_selected="取消" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml index 6e58e7332f..e9a082288a 100644 --- a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml +++ b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml @@ -7,7 +7,7 @@ 360 </floater.string> <floater.string name="min_title_msg"> - Lag + 延遲 </floater.string> <floater.string name="min_width_px"> 90 @@ -22,28 +22,28 @@ 15 </floater.string> <floater.string name="client_frame_time_window_bg_msg"> - Normal, window in background + 正常,視窗位於背景 </floater.string> <floater.string name="client_frame_time_critical_msg"> - Client frame rate below [CLIENT_FRAME_RATE_CRITICAL] + 客戶端幀率低於 [CLIENT_FRAME_RATE_CRITICAL] </floater.string> <floater.string name="client_frame_time_warning_msg"> - Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING] + 客戶端幀率介於 [CLIENT_FRAME_RATE_CRITICAL] 和 [CLIENT_FRAME_RATE_WARNING] 之間 </floater.string> <floater.string name="client_frame_time_normal_msg"> 正常 </floater.string> <floater.string name="client_draw_distance_cause_msg"> - Possible cause: Draw distance set too high + 可能原因:可視距離設得太遠 </floater.string> <floater.string name="client_texture_loading_cause_msg"> - Possible cause: Images loading + 可能原因:正在載入圖像 </floater.string> <floater.string name="client_texture_memory_cause_msg"> - Possible cause: Too many images in memory + 可能原因:記憶體裡圖像太多 </floater.string> <floater.string name="client_complex_objects_cause_msg"> - Possible cause: Too many complex objects in scene + 可能原因:場景內複雜物件太多 </floater.string> <floater.string name="network_text_msg"> 網路 @@ -55,10 +55,10 @@ 5 </floater.string> <floater.string name="network_packet_loss_critical_msg"> - Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets + 這次連通丟失了至少 [NETWORK_PACKET_LOSS_CRITICAL]% 的封包 </floater.string> <floater.string name="network_packet_loss_warning_msg"> - Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets + 這次連通丟失了 [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% 的封包 </floater.string> <floater.string name="network_performance_normal_msg"> 正常 @@ -70,16 +70,16 @@ 300 </floater.string> <floater.string name="network_ping_critical_msg"> - Connection ping time is over [NETWORK_PING_CRITICAL] ms + 探測連通回應時間超過 [NETWORK_PING_CRITICAL] 毫秒 </floater.string> <floater.string name="network_ping_warning_msg"> - Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms + 探測連通回應時間為 [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] 毫秒 </floater.string> <floater.string name="network_packet_loss_cause_msg"> - Possible bad connection or 'Bandwidth' pref too high. + 可能連通不良,或所設的偏好連通頻寬過高。 </floater.string> <floater.string name="network_ping_cause_msg"> - Possible bad connection or file-sharing app. + 可能連通不良,或使用檔案分享應用程式。 </floater.string> <floater.string name="server_text_msg"> 伺服器 diff --git a/indra/newview/skins/default/xui/zh/floater_land_holdings.xml b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml index 1d172f63e1..aae2cfb466 100644 --- a/indra/newview/skins/default/xui/zh/floater_land_holdings.xml +++ b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="land holdings floater" title="我的土地"> <floater.string name="area_string"> - [AREA] m² + [AREA] 平方公尺 </floater.string> <scroll_list name="parcel list"> <scroll_list.columns label="地段" name="name"/> @@ -12,28 +12,28 @@ <button label="瞬間傳送" label_selected="瞬間傳送" name="Teleport" tool_tip="瞬間傳送到這土地的中央。"/> <button label="地圖" label_selected="地圖" name="Show on Map" tool_tip="將這塊土地顯示在世界地圖上。"/> <text name="contrib_label"> - Contributions to your groups: + 對你的群組的貢獻: </text> <scroll_list name="grant list"> <scroll_list.columns label="群組" name="group"/> <scroll_list.columns label="區域" name="area"/> </scroll_list> <text name="allowed_label"> - Allowed land holdings at current payment plan: + 目前付費計劃所允許擁有的土地: </text> <text name="allowed_text"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="current_label"> - Current land holdings: + 目前擁有的土地: </text> <text name="current_text"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="available_label"> - Available for land purchases: + 可購土地: </text> <text name="available_text"> - [AREA] m² + [AREA] 平方公尺 </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml index fe61c312ed..f4a7ba5cca 100644 --- a/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml +++ b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="script ed float" title="腳本: 新腳本"> <floater.string name="not_allowed"> - You can not view or edit this script, since it has been set as "no copy". You need full permissions to view or edit a script inside an object. + 你無法察看或編輯這腳本,它被設為「禁止複製」。 你需要完整權限去察看或編輯物件內的腳本。 </floater.string> <floater.string name="script_running"> 執行中 diff --git a/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml index e5c3c47827..b10a480b06 100644 --- a/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml +++ b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="script ed float" title="LSL REFERENCE"> - <check_box label="Follow cursor" name="lock_check"/> - <combo_box label="Lock" name="history_combo"/> - <button label="Back" name="back_btn"/> - <button label="Forward" name="fwd_btn"/> +<floater name="script ed float" title="LSL 參考"> + <check_box label="跟隨游標" name="lock_check"/> + <combo_box label="鎖定" name="history_combo"/> + <button label="返回" name="back_btn"/> + <button label="向前" name="fwd_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_map.xml b/indra/newview/skins/default/xui/zh/floater_map.xml index b535ef0074..8a030b3b3f 100644 --- a/indra/newview/skins/default/xui/zh/floater_map.xml +++ b/indra/newview/skins/default/xui/zh/floater_map.xml @@ -1,36 +1,36 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Map" title=""> +<floater name="Map" title="迷你地圖"> <floater.string name="ToolTipMsg"> - [REGION](Double-click to open Map, shift-drag to pan) + [REGION](雙擊以開啟地圖,按下 shift 鍵拖曳來平移) </floater.string> <floater.string name="AltToolTipMsg"> - [REGION](Double-click to teleport, shift-drag to pan) + [REGION](雙擊以瞬間傳送,按下 shift 鍵拖曳來平移) </floater.string> <floater.string name="mini_map_caption"> - MINIMAP + 迷你地圖 </floater.string> - <text label="N" name="floater_map_north"> - N + <text label="北" name="floater_map_north"> + 北 </text> <text label="E" name="floater_map_east"> E </text> - <text label="W" name="floater_map_west"> - W + <text label="西" name="floater_map_west"> + 西 </text> - <text label="S" name="floater_map_south"> - S + <text label="南" name="floater_map_south"> + 南 </text> - <text label="SE" name="floater_map_southeast"> - SE + <text label="東南" name="floater_map_southeast"> + 東南 </text> - <text label="NE" name="floater_map_northeast"> - NE + <text label="東北" name="floater_map_northeast"> + 東北 </text> - <text label="SW" name="floater_map_southwest"> - SW + <text label="西南" name="floater_map_southwest"> + 西南 </text> - <text label="NW" name="floater_map_northwest"> - NW + <text label="西北" name="floater_map_northwest"> + 西北 </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_media_browser.xml b/indra/newview/skins/default/xui/zh/floater_media_browser.xml index 6e75016fad..7f030924e1 100644 --- a/indra/newview/skins/default/xui/zh/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/zh/floater_media_browser.xml @@ -8,13 +8,13 @@ </floater.string> <layout_stack name="stack1"> <layout_panel name="nav_controls"> - <button label="向後" name="back"/> + <button label="返回" name="back"/> <button label="向前" name="forward"/> - <button label="重載" name="reload"/> - <button label="Go" name="go"/> + <button label="重新載入" name="reload"/> + <button label="前往" name="go"/> </layout_panel> <layout_panel name="time_controls"> - <button label="rewind" name="rewind"/> + <button label="倒轉" name="rewind"/> <button label="停止" name="stop"/> <button label="向前" name="seek"/> </layout_panel> @@ -22,8 +22,8 @@ <button label="送出目前頁面到地段" name="assign"/> </layout_panel> <layout_panel name="external_controls"> - <button label="在我的網頁瀏覽器中開啟" name="open_browser"/> - <check_box label="總是在我的網頁瀏覽器中開啟" name="open_always"/> + <button label="用我的瀏覽器開啟" name="open_browser"/> + <check_box label="固定用我的瀏覽器開啟" name="open_always"/> <button label="關閉" name="close"/> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/zh/floater_media_settings.xml b/indra/newview/skins/default/xui/zh/floater_media_settings.xml index f42c0af3d9..3984095a65 100644 --- a/indra/newview/skins/default/xui/zh/floater_media_settings.xml +++ b/indra/newview/skins/default/xui/zh/floater_media_settings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="media_settings" title="MEDIA SETTINGS"> +<floater name="media_settings" title="媒體設定"> <button label="確定" label_selected="確定" name="OK"/> <button label="取消" label_selected="取消" name="Cancel"/> <button label="套用" label_selected="套用" name="Apply"/> diff --git a/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml index 93c1b58df6..350254e385 100644 --- a/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml +++ b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="MemLeak" title="SIMULATE A MEMORY LEAK"> - <spinner label="Leaking Speed (bytes per frame):" name="leak_speed"/> - <spinner label="Max Leaked Memory (MB):" name="max_leak"/> +<floater name="MemLeak" title="模擬記憶體漏耗"> + <spinner label="漏耗速度(位元組/幀):" name="leak_speed"/> + <spinner label="最大記憶體漏耗(MB):" name="max_leak"/> <text name="total_leaked_label"> - Current leaked memory: [SIZE] KB + 目前已漏耗記憶體:[SIZE] KB </text> <text name="note_label_1"> [NOTE1] @@ -11,8 +11,8 @@ <text name="note_label_2"> [NOTE2] </text> - <button label="Start" name="start_btn"/> + <button label="開始" name="start_btn"/> <button label="停止" name="stop_btn"/> - <button label="Release" name="release_btn"/> + <button label="釋放" name="release_btn"/> <button label="關閉" name="close_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml new file mode 100644 index 0000000000..6b6126c8e0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_merchant_outbox" title="商家發件匣"> + <string name="OutboxFolderCount1"> + 1 個資料夾 + </string> + <string name="OutboxFolderCountN"> + [NUM] 個資料夾 + </string> + <string name="OutboxImporting"> + 正在傳送資料夾… + </string> + <string name="OutboxInitializing"> + 正在初始化… + </string> + <panel label=""> + <panel> + <panel name="outbox_inventory_placeholder_panel"> + <text name="outbox_inventory_placeholder_title"> + 載入中... + </text> + </panel> + </panel> + <panel> + <button label="送往第二人生購物市集" name="outbox_import_btn" tool_tip="推到我第二人生購物市集的店面"/> + </panel> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_model_preview.xml b/indra/newview/skins/default/xui/zh/floater_model_preview.xml new file mode 100644 index 0000000000..22b3d3b065 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_model_preview.xml @@ -0,0 +1,312 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Model Preview" title="上傳模型"> + <string name="status_idle"/> + <string name="status_parse_error"> + 錯誤:剖析 dae 時出錯,詳見記錄檔。 + </string> + <string name="status_material_mismatch"> + 錯誤:模型材料並非參考模型的子集合。 + </string> + <string name="status_reading_file"> + 載入中... + </string> + <string name="status_generating_meshes"> + 正在生成網面… + </string> + <string name="status_vertex_number_overflow"> + 錯誤:頂點數目超過 65534,程序已中止! + </string> + <string name="bad_element"> + 錯誤:無效的元件 + </string> + <string name="high"> + 高 + </string> + <string name="medium"> + 中 + </string> + <string name="low"> + 低 + </string> + <string name="lowest"> + 最低 + </string> + <string name="mesh_status_good"> + 確定產生! + </string> + <string name="mesh_status_na"> + 不適用 + </string> + <string name="mesh_status_none"> + 無 + </string> + <string name="mesh_status_submesh_mismatch"> + 細節層次裡,可使用材質的臉部數目不同。 + </string> + <string name="mesh_status_mesh_mismatch"> + 細節層次裡,網面實例的數目不同。 + </string> + <string name="mesh_status_too_many_vertices"> + 細節層次裡,頂點數目太多。 + </string> + <string name="mesh_status_missing_lod"> + 缺乏需要的細節層次。 + </string> + <string name="mesh_status_invalid_material_list"> + 細節層次材料並非參考模型的子集合。 + </string> + <string name="layer_all"> + 全部 + </string> + <string name="decomposing"> + 分析中… + </string> + <string name="simplifying"> + 簡化中… + </string> + <string name="tbd"> + (未定) + </string> + <panel name="left_panel"> + <panel name="model_name_representation_panel"> + <text name="name_label"> + 模型名稱: + </text> + <text name="model_category_label"> + 這模型代表… + </text> + <combo_box name="model_category_combo"> + <combo_item label="選擇一項…" name="Choose one"/> + <combo_item label="化身形狀" name="Avatar shape"/> + <combo_item label="化身附件" name="Avatar attachment"/> + <combo_item label="會移動的物件(車輛、動物)" name="Moving object (vehicle, animal)"/> + <combo_item label="建製元件" name="Building Component"/> + <combo_item label="大型、不會移動等類型" name="Large, non moving etc"/> + <combo_item label="較小型、不會移動等類型" name="Smaller, non-moving etc"/> + <combo_item label="並非其中任何一個" name="Not really any of these"/> + </combo_box> + </panel> + <tab_container name="import_tab"> + <panel label="細節層次" name="lod_panel" title="細節層次"> + <text initial_value="來源" name="source" value="來源"/> + <text initial_value="三角形" name="triangles" value="三角形"/> + <text initial_value="頂點" name="vertices" value="頂點"/> + <text initial_value="高" name="high_label" value="高"/> + <combo_box name="lod_source_high"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + </combo_box> + <button label="瀏覽…" name="lod_browse_high"/> + <combo_box name="lod_mode_high"> + <item name="Triangle Limit" value="三角形上限"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="high_triangles" value="0"/> + <text initial_value="0" name="high_vertices" value="0"/> + <text initial_value="中" name="medium_label" value="中"/> + <combo_box name="lod_source_medium"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + <item name="Use LoD above" value="以上使用低階細節"/> + </combo_box> + <button label="瀏覽…" name="lod_browse_medium"/> + <combo_box name="lod_mode_medium"> + <item name="Triangle Limit" value="三角形上限"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="medium_triangles" value="0"/> + <text initial_value="0" name="medium_vertices" value="0"/> + <text initial_value="低" name="low_label" value="低"/> + <combo_box name="lod_source_low"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + <item name="Use LoD above" value="以上使用低階細節"/> + </combo_box> + <button label="瀏覽…" name="lod_browse_low"/> + <combo_box name="lod_mode_low"> + <item name="Triangle Limit" value="三角形上限"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="low_triangles" value="0"/> + <text initial_value="0" name="low_vertices" value="0"/> + <text initial_value="最低" name="lowest_label" value="最低"/> + <combo_box name="lod_source_lowest"> + <item name="Load from file" value="從檔案載入"/> + <item name="Generate" value="產生"/> + <item name="Use LoD above" value="以上使用低階細節"/> + </combo_box> + <button label="瀏覽…" name="lod_browse_lowest"/> + <combo_box name="lod_mode_lowest"> + <item name="Triangle Limit" value="三角形上限"/> + <item name="Error Threshold" value="錯誤門檻"/> + </combo_box> + <text initial_value="0" name="lowest_triangles" value="0"/> + <text initial_value="0" name="lowest_vertices" value="0"/> + <check_box label="產生法線" name="gen_normals"/> + <text initial_value="皺褶角度:" name="crease_label" value="皺褶角度:"/> + <spinner name="crease_angle" value="75"/> + </panel> + <panel label="物理" name="physics_panel"> + <panel name="physics geometry"> + <text name="first_step_name"> + 步驟 1:細節層次 + </text> + <combo_box name="physics_lod_combo" tool_tip="物理形狀所採用的細節層次"> + <combo_item name="choose_one"> + 選擇一項… + </combo_item> + <combo_item name="physics_high"> + 高 + </combo_item> + <combo_item name="physics_medium"> + 中 + </combo_item> + <combo_item name="physics_low"> + 低 + </combo_item> + <combo_item name="physics_lowest"> + 最低 + </combo_item> + <combo_item name="load_from_file"> + 來自檔案 + </combo_item> + </combo_box> + <button label="瀏覽…" name="physics_browse"/> + </panel> + <panel name="physics analysis"> + <text name="method_label"> + 步驟 2:分析 + </text> + <text name="analysis_method_label"> + 方法: + </text> + <text name="quality_label"> + 品質: + </text> + <text name="smooth_method_label"> + 平滑: + </text> + <check_box label="關閉洞口" name="Close Holes (Slow)"/> + <button label="分析" name="Decompose"/> + <button label="取消" name="decompose_cancel"/> + </panel> + <panel name="physics simplification"> + <text name="second_step_label"> + 步驟 3:簡化 + </text> + <text name="simp_method_header"> + 方法: + </text> + <text name="pass_method_header"> + 階段數: + </text> + <text name="Detail Scale label"> + 細節比例: + </text> + <text name="Retain%_label"> + 保留: + </text> + <combo_box name="Combine Quality" value="1"/> + <button label="簡化" name="Simplify"/> + <button label="取消" name="simplify_cancel"/> + </panel> + <panel name="physics info"> + <text name="results_text"> + 結果: + </text> + <text name="physics_triangles"> + 三角形:[TRIANGLES], + </text> + <text name="physics_points"> + 頂點:[POINTS], + </text> + <text name="physics_hulls"> + 殼面:[HULLS] + </text> + </panel> + </panel> + <panel label="上傳選項" name="modifiers_panel"> + <text name="scale_label"> + 比例(1 = 原比例): + </text> + <spinner name="import_scale" value="1.0"/> + <text name="dimensions_label"> + 規格: + </text> + <text name="import_dimensions"> + [X] X [Y] X [Z] + </text> + <check_box label="包含材質" name="upload_textures"/> + <text name="include_label"> + 僅限化身模型: + </text> + <check_box label="包含表皮重量" name="upload_skin"/> + <check_box label="包含接點位置" name="upload_joints"/> + <text name="pelvis_offset_label"> + Z 偏距(升高或降低化身): + </text> + <spinner name="pelvis_offset" value="0.0"/> + </panel> + </tab_container> + <panel name="weights_and_warning_panel"> + <button label="計算重量和費用" name="calculate_btn" tool_tip="計算重量和費用"/> + <button label="取消" name="cancel_btn"/> + <button label="上傳" name="ok_btn" tool_tip="上傳至模擬器"/> + <button label="清除設定並重設形式" name="reset_btn"/> + <text name="upload_fee"> + 上傳費用:L$ [FEE] + </text> + <text name="prim_weight"> + 土地衝擊量:[EQ] + </text> + <text name="download_weight"> + 下載:[ST] + </text> + <text name="physics_weight"> + 物理:[PH] + </text> + <text name="server_weight"> + 伺服器:[SIM] + </text> + <text name="warning_title"> + 附註: + </text> + <text name="warning_message"> + 你無權上傳網面模型。 [[VURL] 瞭解如何]通過認證。 + </text> + <text name="status"> + [STATUS] + </text> + </panel> + </panel> + <text name="lod_label"> + 預覽: + </text> + <panel name="right_panel"> + <combo_box name="preview_lod_combo" tool_tip="要在呈像預覽中察看的細節層次"> + <combo_item name="high"> + 高 + </combo_item> + <combo_item name="medium"> + 中 + </combo_item> + <combo_item name="low"> + 低 + </combo_item> + <combo_item name="lowest"> + 最低 + </combo_item> + </combo_box> + <text name="label_display"> + 顯示… + </text> + <check_box label="邊" name="show_edges"/> + <check_box label="物理" name="show_physics"/> + <check_box label="材質" name="show_textures"/> + <check_box label="表皮重量" name="show_skin_weight"/> + <check_box label="接點" name="show_joint_positions"/> + <text name="physics_explode_label"> + 預覽伸展: + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_moveview.xml b/indra/newview/skins/default/xui/zh/floater_moveview.xml index e1155bdf34..0b267e8fae 100644 --- a/indra/newview/skins/default/xui/zh/floater_moveview.xml +++ b/indra/newview/skins/default/xui/zh/floater_moveview.xml @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="move_floater"> +<floater name="move_floater" title="行走 / 跑步 / 飛行"> <string name="walk_forward_tooltip"> - Walk Forward (press Up Arrow or W) + 向前走(按下向上箭頭或 W 鍵) </string> <string name="walk_back_tooltip"> - Walk Backwards (press Down Arrow or S) + 倒退行走(按下向下箭頭或 S 鍵) </string> <string name="walk_left_tooltip"> - Walk left (press Shift + Left Arrow or A) + 向左走(按下 Shift 加左方向鍵或按 A 鍵) </string> <string name="walk_right_tooltip"> - Walk right (press Shift + Right Arrow or D) + 向右走(按下 Shift 加右方向鍵或按 D 鍵) </string> <string name="run_forward_tooltip"> - Run Forward (press Up Arrow or W) + 向前跑(按下向上箭頭或 W 鍵) </string> <string name="run_back_tooltip"> - Run Backwards (press Down Arrow or S) + 倒退跑步(按下向下箭頭或 S 鍵) </string> <string name="run_left_tooltip"> - Run left (press Shift + Left Arrow or A) + 向左跑(按下 Shift + 左方向鍵或按 A 鍵) </string> <string name="run_right_tooltip"> - Run right (press Shift + Right Arrow or D) + 向右跑(按下 Shift + 右方向鍵或按 D 鍵) </string> <string name="fly_forward_tooltip"> 向前飛(按下向上箭頭或 W 鍵) @@ -65,7 +65,7 @@ <joystick_turn name="forward btn" tool_tip="向前走(按向上方向鍵或按 W 鍵)"/> <joystick_turn name="backward btn" tool_tip="向後退(按向下方向鍵或按 S 鍵)"/> <button name="move up btn" tool_tip="向上飛(按下 E 鍵)"/> - <button name="move down btn" tool_tip="向下飛(按下 C 建)"/> + <button name="move down btn" tool_tip="向下飛(按下 C 鍵)"/> </panel> <panel name="panel_modes"> <button label="" name="mode_walk_btn" tool_tip="行走模式"/> diff --git a/indra/newview/skins/default/xui/zh/floater_mute_object.xml b/indra/newview/skins/default/xui/zh/floater_mute_object.xml index 606e061395..64998d3e28 100644 --- a/indra/newview/skins/default/xui/zh/floater_mute_object.xml +++ b/indra/newview/skins/default/xui/zh/floater_mute_object.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="block by name" title="依名稱封鎖物件"> <text name="message"> - Block an object: + 封鎖一個物件: </text> <line_editor name="object_name"> 物件名稱 </line_editor> <text name="note"> - * Only blocks object text, not sounds + * 只封鎖物件文字,不封鎖聲音 </text> <button label="確定" name="OK"/> <button label="取消" name="Cancel"/> diff --git a/indra/newview/skins/default/xui/zh/floater_my_appearance.xml b/indra/newview/skins/default/xui/zh/floater_my_appearance.xml new file mode 100644 index 0000000000..217ea5d1f9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_my_appearance.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_my_appearance" title="外觀"> + <panel label="編輯外觀" name="main_panel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_my_inventory.xml b/indra/newview/skins/default/xui/zh/floater_my_inventory.xml new file mode 100644 index 0000000000..187597f4eb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_my_inventory.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_my_inventory" title="收納區"/> diff --git a/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml b/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml deleted file mode 100644 index 38a5dab523..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="附近的聊天"> - <check_box label="Translate chat" name="translate_chat_checkbox"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_object_weights.xml b/indra/newview/skins/default/xui/zh/floater_object_weights.xml new file mode 100644 index 0000000000..d2875b24b4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_object_weights.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="object_weights" title="進階"> + <floater.string name="nothing_selected" value="--"/> + <text name="selected_text" value="已選"/> + <text name="objects" value="--"/> + <text name="objects_label" value="物件"/> + <text name="prims" value="--"/> + <text name="prims_label" value="幾何元件"/> + <text name="weights_of_selected_text" value="所選物重量"/> + <text name="download" value="--"/> + <text name="download_label" value="下載"/> + <text name="physics" value="--"/> + <text name="physics_label" value="物理"/> + <text name="server" value="--"/> + <text name="server_label" value="伺服器"/> + <text name="display" value="--"/> + <text name="display_label" value="顯示"/> + <text name="land_impacts_text" value="土地衝擊量"/> + <text name="selected" value="--"/> + <text name="selected_label" value="選擇"/> + <text name="rezzed_on_land" value="--"/> + <text name="rezzed_on_land_label" value="已產生到土地上"/> + <text name="remaining_capacity" value="--"/> + <text name="remaining_capacity_label" value="剩餘容納量"/> + <text name="total_capacity" value="--"/> + <text name="total_capacity_label" value="總容納量"/> + <text name="help_SLURL" value="[secondlife:///app/help/object_weights 這是什麼?]"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_openobject.xml b/indra/newview/skins/default/xui/zh/floater_openobject.xml index 61ac3cb1fc..ce6869487a 100644 --- a/indra/newview/skins/default/xui/zh/floater_openobject.xml +++ b/indra/newview/skins/default/xui/zh/floater_openobject.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="objectcontents" title="物件內容"> <text name="object_name"> - [DESC]: + [DESC]: </text> <button label="覆製到收納區" label_selected="覆製到收納區" name="copy_to_inventory_button"/> <button label="覆製且穿上" label_selected="覆製且穿上" name="copy_and_wear_button"/> diff --git a/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml index a557e1c2e3..9e786edcdd 100644 --- a/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml +++ b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml @@ -3,9 +3,9 @@ <button label="儲存" label_selected="儲存" name="Save"/> <button label="取消" label_selected="取消" name="Cancel"/> <text name="Save item as:"> - 儲存我正在穿的為新裝扮: + 儲存我現在的穿著為新裝扮: </text> <line_editor name="name ed"> - [DESC] (新) + [DESC](新) </line_editor> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml index 63da47f4de..e57374f4d7 100644 --- a/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml +++ b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="outgoing call" title="CALLING"> +<floater name="outgoing call" title="打電話"> <floater.string name="lifetime"> 5 </floater.string> @@ -10,31 +10,31 @@ 匿名 </floater.string> <floater.string name="VoiceInviteP2P"> - 通話中。 + 來電中。 </floater.string> <floater.string name="VoiceInviteAdHoc"> - has joined a Voice Chat call with a conference chat. + 已加入多方語音通話。 </floater.string> <text name="connecting"> - Connecting to [CALLEE_NAME] + 正在連通 [CALLEE_NAME] </text> <text name="calling"> - Calling [CALLEE_NAME] + 正在打給 [CALLEE_NAME] </text> <text name="noanswer"> - 無應答,請稍候再試。 + 無人接聽。 請稍候再試一次。 </text> <text name="nearby"> - You have been disconnected from [VOICE_CHANNEL_NAME]. [RECONNECT_NEARBY] + 你的 [VOICE_CHANNEL_NAME] 通話已經中斷。 [RECONNECT_NEARBY] </text> <text name="nearby_P2P_by_other"> - Your call has ended. [RECONNECT_NEARBY] + 你的通話已經結束。 [RECONNECT_NEARBY] </text> <text name="nearby_P2P_by_agent"> - You have ended the call. [RECONNECT_NEARBY] + 你已經結束通話。 [RECONNECT_NEARBY] </text> <text name="leaving"> - Leaving [CURRENT_CHAT]. + 離開 [CURRENT_CHAT]。 </text> <button label="取消" label_selected="取消" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml new file mode 100644 index 0000000000..e6971d111f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_characters" title="尋徑角色"> + <floater.string name="messaging_get_inprogress"> + 尋徑角色查詢中… + </floater.string> + <floater.string name="messaging_get_error"> + 查詢尋徑角色時出錯。 + </floater.string> + <floater.string name="messaging_complete_none_found"> + 沒有尋徑角色。 + </floater.string> + <floater.string name="messaging_complete_available"> + 從 [NUM_TOTAL] 個角色中選取了 [NUM_SELECTED] 個。 + </floater.string> + <floater.string name="messaging_not_enabled"> + 這地區並未啟用尋徑。 + </floater.string> + <floater.string name="character_cpu_time"> + [CPU_TIME] 微秒 + </floater.string> + <floater.string name="character_owner_loading"> + [Loading] + </floater.string> + <floater.string name="character_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="character_owner_group"> + [group] + </floater.string> + <panel> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="名稱" name="name"/> + <scroll_list.columns label="描述" name="description"/> + <scroll_list.columns label="所有人" name="owner"/> + <scroll_list.columns label="中央處理器" name="cpu_time"/> + <scroll_list.columns label="高度" name="altitude"/> + </scroll_list> + <text name="messaging_status"> + 角色: + </text> + <button label="刷新清單" name="refresh_objects_list"/> + <button label="全選" name="select_all_objects"/> + <button label="全都不選" name="select_none_objects"/> + </panel> + <panel> + <text name="actions_label"> + 所選角色所採動作: + </text> + <check_box label="顯示指標" name="show_beacon"/> + <check_box label="顯示物理囊" name="show_physics_capsule"/> + <button label="取得" name="take_objects"/> + <button label="拿取副本" name="take_copy_objects"/> + <button label="瞬間傳送我到那裡" name="teleport_me_to_object" tool_tip="只在選取了一個角色時啟用。"/> + <button label="退回" name="return_objects"/> + <button label="刪除" name="delete_objects"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml new file mode 100644 index 0000000000..be009b54d8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_console" title="尋徑察看 / 測試"> + <floater.string name="navmesh_viewer_status_library_not_implemented"> + 找不到尋徑函式庫實作。 + </floater.string> + <floater.string name="navmesh_viewer_status_region_not_enabled"> + 這地區並未啟用尋徑。 + </floater.string> + <floater.string name="navmesh_viewer_status_region_loading"> + 等待地區完成載入。 + </floater.string> + <floater.string name="navmesh_viewer_status_checking_version"> + 正在檢查導航網面狀態。 + </floater.string> + <floater.string name="navmesh_viewer_status_downloading"> + 正在下載導航網面。 + </floater.string> + <floater.string name="navmesh_viewer_status_updating"> + 伺服器上的導航網面已變更。 正在下載最新的導航網面。 + </floater.string> + <floater.string name="navmesh_viewer_status_has_navmesh"> + 最新的導航網面下載完成。 + </floater.string> + <floater.string name="navmesh_viewer_status_error"> + 無法完成導航網面下載。 + </floater.string> + <floater.string name="navmesh_simulator_status_pending"> + 導航網面有變更待存。 + </floater.string> + <floater.string name="navmesh_simulator_status_building"> + 正在建構導航網面。 + </floater.string> + <floater.string name="navmesh_simulator_status_some_pending"> + 某些導航網面地區有變更待存。 + </floater.string> + <floater.string name="navmesh_simulator_status_some_building"> + 正在建構某些導航網面地區。 + </floater.string> + <floater.string name="navmesh_simulator_status_pending_and_building"> + 某些導航網面地區有變更待存,其他的正在建構中。 + </floater.string> + <floater.string name="navmesh_simulator_status_complete"> + 導航網面已全面更新。 + </floater.string> + <floater.string name="pathing_library_not_implemented"> + 找不到尋徑函式庫實作。 + </floater.string> + <floater.string name="pathing_region_not_enabled"> + 這地區並未啟用尋徑。 + </floater.string> + <floater.string name="pathing_choose_start_and_end_points"> + 請選擇起點和終點。 + </floater.string> + <floater.string name="pathing_choose_start_point"> + 請選擇起點。 + </floater.string> + <floater.string name="pathing_choose_end_point"> + 請選擇終點。 + </floater.string> + <floater.string name="pathing_path_valid"> + 路徑以橘色顯示。 + </floater.string> + <floater.string name="pathing_path_invalid"> + 在所選的點之間找不到路徑。 + </floater.string> + <floater.string name="pathing_error"> + 產生路徑時出錯。 + </floater.string> + <tab_container name="view_test_tab_container"> + <panel label="視角" name="view_panel"> + <text name="show_label"> + 顯示: + </text> + <check_box label="世界" name="show_world"/> + <check_box label="僅限可移動的" name="show_world_movables_only"/> + <check_box label="導航網面" name="show_navmesh"/> + <text name="show_walkability_label"> + 顯示可行走地圖: + </text> + <combo_box name="show_heatmap_mode"> + <combo_box.item label="不顯示" name="show_heatmap_mode_none"/> + <combo_box.item label="類型 A 角色" name="show_heatmap_mode_a"/> + <combo_box.item label="類型 B 角色" name="show_heatmap_mode_b"/> + <combo_box.item label="類型 C 角色" name="show_heatmap_mode_c"/> + <combo_box.item label="類型 D 角色" name="show_heatmap_mode_d"/> + </combo_box> + <check_box label="可行走的" name="show_walkables"/> + <check_box label="實質體積" name="show_material_volumes"/> + <check_box label="靜態障礙" name="show_static_obstacles"/> + <check_box label="排除體積" name="show_exclusion_volumes"/> + <check_box label="水平面" name="show_water_plane"/> + <check_box label="具 X 光透視力" name="show_xray"/> + </panel> + <panel label="測試路徑" name="test_panel"> + <text name="ctrl_click_label"> + 按住 Ctrl 並點按即可選擇起點。 + </text> + <text name="shift_click_label"> + 按住 Shift 並點按即可選擇終點。 + </text> + <text name="character_width_label"> + 角色寬度 + </text> + <slider name="character_width" value="1"/> + <text name="character_width_unit_label"> + 公尺 + </text> + <text name="character_type_label"> + 角色類型 + </text> + <combo_box name="path_character_type"> + <combo_box.item label="無" name="path_character_type_none"/> + <combo_box.item label="A" name="path_character_type_a"/> + <combo_box.item label="B" name="path_character_type_b"/> + <combo_box.item label="C" name="path_character_type_c"/> + <combo_box.item label="D" name="path_character_type_d"/> + </combo_box> + <button label="清除路徑" name="clear_path"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml new file mode 100644 index 0000000000..22e5d2e846 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_pathfinding_linksets" title="尋徑聯結集"> + <floater.string name="messaging_get_inprogress"> + 尋徑聯結集查詢中… + </floater.string> + <floater.string name="messaging_get_error"> + 查詢尋徑聯結集時出錯。 + </floater.string> + <floater.string name="messaging_set_inprogress"> + 正在修改所選尋徑聯結集… + </floater.string> + <floater.string name="messaging_set_error"> + 修改所選尋徑聯結集時出錯。 + </floater.string> + <floater.string name="messaging_complete_none_found"> + 沒有尋徑聯結集。 + </floater.string> + <floater.string name="messaging_complete_available"> + 從 [NUM_TOTAL] 個聯結集中選取了 [NUM_SELECTED] 個。 + </floater.string> + <floater.string name="messaging_not_enabled"> + 這地區並未啟用尋徑。 + </floater.string> + <floater.string name="linkset_terrain_name"> + [Terrain] + </floater.string> + <floater.string name="linkset_terrain_description"> + -- + </floater.string> + <floater.string name="linkset_terrain_owner"> + -- + </floater.string> + <floater.string name="linkset_terrain_scripted"> + -- + </floater.string> + <floater.string name="linkset_terrain_land_impact"> + -- + </floater.string> + <floater.string name="linkset_terrain_dist_from_you"> + -- + </floater.string> + <floater.string name="linkset_owner_loading"> + [Loading] + </floater.string> + <floater.string name="linkset_owner_unknown"> + [Unknown] + </floater.string> + <floater.string name="linkset_owner_group"> + [group] + </floater.string> + <floater.string name="linkset_is_scripted"> + 是 + </floater.string> + <floater.string name="linkset_is_not_scripted"> + 否 + </floater.string> + <floater.string name="linkset_is_unknown_scripted"> + 未知 + </floater.string> + <floater.string name="linkset_use_walkable"> + 可行走的 + </floater.string> + <floater.string name="linkset_use_static_obstacle"> + 靜態障礙 + </floater.string> + <floater.string name="linkset_use_dynamic_obstacle"> + 可移動障礙 + </floater.string> + <floater.string name="linkset_use_material_volume"> + 實質體積 + </floater.string> + <floater.string name="linkset_use_exclusion_volume"> + 排除體積 + </floater.string> + <floater.string name="linkset_use_dynamic_phantom"> + 可移動幻影 + </floater.string> + <floater.string name="linkset_is_terrain"> + [unmodifiable] + </floater.string> + <floater.string name="linkset_is_restricted_state"> + [restricted] + </floater.string> + <floater.string name="linkset_is_non_volume_state"> + [concave] + </floater.string> + <floater.string name="linkset_is_restricted_non_volume_state"> + [restricted,concave] + </floater.string> + <floater.string name="linkset_choose_use"> + 選擇聯結集的使用… + </floater.string> + <panel> + <combo_box name="filter_by_linkset_use"> + <combo_box.item label="按聯結集的使用來過濾…" name="filter_by_linkset_use_none"/> + <combo_box.item label="可行走的" name="filter_by_linkset_use_walkable"/> + <combo_box.item label="靜態障礙" name="filter_by_linkset_use_static_obstacle"/> + <combo_box.item label="可移動障礙" name="filter_by_linkset_use_dynamic_obstacle"/> + <combo_box.item label="實質體積" name="filter_by_linkset_use_material_volume"/> + <combo_box.item label="排除體積" name="filter_by_linkset_use_exclusion_volume"/> + <combo_box.item label="可移動幻影" name="filter_by_linkset_use_dynamic_phantom"/> + </combo_box> + <button label="套用" name="apply_filters"/> + <button label="清除" name="clear_filters"/> + <scroll_list name="objects_scroll_list"> + <scroll_list.columns label="名稱(根幾何元件)" name="name"/> + <scroll_list.columns label="描述(根幾何元件)" name="description"/> + <scroll_list.columns label="所有人" name="owner"/> + <scroll_list.columns label="有腳本" name="scripted"/> + <scroll_list.columns label="衝擊" name="land_impact"/> + <scroll_list.columns label="距離" name="dist_from_you"/> + <scroll_list.columns label="聯結集的使用" name="linkset_use"/> + <scroll_list.columns label="A %" name="a_percent"/> + <scroll_list.columns label="B %" name="b_percent"/> + <scroll_list.columns label="C %" name="c_percent"/> + <scroll_list.columns label="D %" name="d_percent"/> + </scroll_list> + <text name="messaging_status"> + 聯結集: + </text> + <button label="刷新清單" name="refresh_objects_list"/> + <button label="全選" name="select_all_objects"/> + <button label="全都不選" name="select_none_objects"/> + </panel> + <panel> + <check_box label="顯示指標" name="show_beacon"/> + <button label="取得" name="take_objects"/> + <button label="拿取副本" name="take_copy_objects"/> + <button label="瞬間傳送我到那裡" name="teleport_me_to_object"/> + <button label="退回" name="return_objects"/> + <button label="刪除" name="delete_objects"/> + </panel> + <panel> + <text name="walkability_coefficients_label"> + 可行走性: + </text> + <text name="edit_a_label"> + A + </text> + <line_editor name="edit_a_value" tool_tip="A 類型角色的可行走性。以類人類為範例角色類型。"/> + <text name="edit_b_label"> + B + </text> + <line_editor name="edit_b_value" tool_tip="B 類型角色的可行走性。以獸類為範例角色類型。"/> + <text name="edit_c_label"> + C + </text> + <line_editor name="edit_c_value" tool_tip="C 類型角色的可行走性。以機械類為範例角色類型。"/> + <text name="edit_d_label"> + D + </text> + <line_editor name="edit_d_value" tool_tip="D 類型角色的可行走性。以其他種類為範例角色類型。"/> + <button label="套用變更" name="apply_edit_values"/> + <text name="suggested_use_a_label"> + (類人類) + </text> + <text name="suggested_use_b_label"> + (獸類) + </text> + <text name="suggested_use_c_label"> + (機械類) + </text> + <text name="suggested_use_d_label"> + (其他) + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pay.xml b/indra/newview/skins/default/xui/zh/floater_pay.xml index 0a823cd82e..69427605a4 100644 --- a/indra/newview/skins/default/xui/zh/floater_pay.xml +++ b/indra/newview/skins/default/xui/zh/floater_pay.xml @@ -7,14 +7,14 @@ 支付居民 </string> <text name="payee_name"> - Test Name That Is Extremely Long To Check Clipping + 測試一個長度非常非常非常長的名稱,檢查是否被切斷 </text> <button label="L$1" label_selected="L$1" name="fastpay 1"/> <button label="L$5" label_selected="L$5" name="fastpay 5"/> <button label="L$10" label_selected="L$10" name="fastpay 10"/> <button label="L$20" label_selected="L$20" name="fastpay 20"/> <text name="amount text"> - 或,選擇一個金額: + 或選擇一個金額: </text> <button label="支付" label_selected="支付" name="pay btn"/> <button label="取消" label_selected="取消" name="cancel btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_pay_object.xml b/indra/newview/skins/default/xui/zh/floater_pay_object.xml index 39259524d7..7d20b44bc6 100644 --- a/indra/newview/skins/default/xui/zh/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/zh/floater_pay_object.xml @@ -14,14 +14,14 @@ </text> <icon name="icon_object" tool_tip="物件"/> <text name="object_name_text"> - My awesome object with a really damn long name + 這是我名稱很長很長很長很長的一個很棒的物件 </text> <button label="L$1" label_selected="L$1" name="fastpay 1"/> <button label="L$5" label_selected="L$5" name="fastpay 5"/> <button label="L$10" label_selected="L$10" name="fastpay 10"/> <button label="L$20" label_selected="L$20" name="fastpay 20"/> <text name="amount text"> - 或者,選擇一個金額: + 或選擇一個金額: </text> <button label="支付" label_selected="支付" name="pay btn"/> <button label="取消" label_selected="取消" name="cancel btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_people.xml b/indra/newview/skins/default/xui/zh/floater_people.xml new file mode 100644 index 0000000000..f629f2f184 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_people.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_people" title="人群"> + <panel_container name="main_panel"> + <panel label="群組檔案" name="panel_group_info_sidetray"/> + <panel label="被封鎖的居民與物件" name="panel_block_list_sidetray"/> + </panel_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml index 498848ee56..b38db59ff3 100644 --- a/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml +++ b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml @@ -4,10 +4,10 @@ <check_box label="與群組分享" name="share_with_group"/> <check_box label="允許任何人覆製" name="everyone_copy"/> <text name="NextOwnerLabel"> - 下一個擁有者可以: + 下一個所有人可以: </text> <check_box label="修改" name="next_owner_modify"/> - <check_box label="覆製" name="next_owner_copy"/> + <check_box label="恚庨" name="next_owner_copy"/> <check_box initial_value="true" label="轉售 / 送人" name="next_owner_transfer"/> </panel> <button label="確定" label_selected="確定" name="ok"/> diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml new file mode 100644 index 0000000000..a8bfcd99e3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_picks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_picks" title="精選地點"/> diff --git a/indra/newview/skins/default/xui/zh/floater_places.xml b/indra/newview/skins/default/xui/zh/floater_places.xml new file mode 100644 index 0000000000..f6ef1e2141 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_places.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_places" title="地點"> + <panel label="地點" name="main_panel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_post_process.xml b/indra/newview/skins/default/xui/zh/floater_post_process.xml index 0972c6dfa6..2908f7c1d0 100644 --- a/indra/newview/skins/default/xui/zh/floater_post_process.xml +++ b/indra/newview/skins/default/xui/zh/floater_post_process.xml @@ -1,50 +1,50 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Post-Process Floater" title="POST-PROCESS SETTINGS"> +<floater name="Post-Process Floater" title="後處理設定:"> <tab_container name="Post-Process Tabs"> - <panel label="Color Filter" name="wmiColorFilterPanel"> - <check_box label="Enable" name="wmiColorFilterToggle"/> + <panel label="顏色過濾" name="wmiColorFilterPanel"> + <check_box label="啟用" name="wmiColorFilterToggle"/> <text name="wmiColorFilterBrightnessText"> - Brightness + 亮度 </text> <text name="wmiColorFilterSaturationText"> - Saturation + 飽和度 </text> <text name="wmiColorFilterContrastText"> - Contrast + 對比 </text> <text name="wmiColorFilterBaseText"> - Contrast Base Color + 對比基本色 </text> <slider label="R" name="wmiColorFilterBaseR"/> <slider label="G" name="wmiColorFilterBaseG"/> <slider label="B" name="wmiColorFilterBaseB"/> <slider label="I" name="wmiColorFilterBaseI"/> </panel> - <panel label="Night Vision" name="wmiNightVisionPanel"> - <check_box label="Enable" name="wmiNightVisionToggle"/> + <panel label="夜視" name="wmiNightVisionPanel"> + <check_box label="啟用" name="wmiNightVisionToggle"/> <text name="wmiNightVisionBrightMultText"> - Light Amplification Multiple + 光放大倍數 </text> <text name="wmiNightVisionNoiseSizeText"> - Noise Size + 噪音規模 </text> <text name="wmiNightVisionNoiseStrengthText"> - Noise Strength + 噪音強度 </text> </panel> - <panel label="Bloom" name="wmiBloomPanel"> - <check_box label="Enable" name="wmiBloomToggle"/> + <panel label="開花" name="wmiBloomPanel"> + <check_box label="啟用" name="wmiBloomToggle"/> <text name="wmiBloomExtractText"> - Luminosity Extraction + 光度萃取 </text> <text name="wmiBloomSizeText"> - Bloom Size + 開花大小 </text> <text name="wmiBloomStrengthText"> - Bloom Strength + 開花強度 </text> </panel> - <panel label="Extras" name="Extras"> + <panel label="其他" name="Extras"> <button label="LoadEffect" label_selected="LoadEffect" name="PPLoadEffect"/> <button label="SaveEffect" label_selected="SaveEffect" name="PPSaveEffect"/> <line_editor label="效果名稱" name="PPEffectNameEditor"/> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences.xml b/indra/newview/skins/default/xui/zh/floater_preferences.xml index 396a4893e0..b0a27e8c1f 100644 --- a/indra/newview/skins/default/xui/zh/floater_preferences.xml +++ b/indra/newview/skins/default/xui/zh/floater_preferences.xml @@ -3,11 +3,11 @@ <button label="確定" label_selected="確定" name="OK"/> <button label="取消" label_selected="取消" name="Cancel"/> <tab_container name="pref core"> - <panel label="一般" name="general"/> - <panel label="圖形" name="display"/> + <panel label="基本設定" name="general"/> + <panel label="顯像" name="display"/> <panel label="聲音與媒體" name="audio"/> <panel label="聊天" name="chat"/> - <panel label="移動與視角" name="move"/> + <panel label="移動/視野" name="move"/> <panel label="通知" name="msgs"/> <panel label="顏色" name="colors"/> <panel label="隱私" name="im"/> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml new file mode 100644 index 0000000000..f91d5c5cdb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Proxy Settings Floater" title="代理伺服器設定"> + <check_box initial_value="false" label="使用 HTTP 代理伺服器瀏覽網頁" name="web_proxy_enabled"/> + <text name="http_proxy_label"> + HTTP 代理伺服器: + </text> + <line_editor name="web_proxy_editor" tool_tip="你希望使用的 HTTP 代理伺服器的 DNS 名稱或 IP 位址。"/> + <spinner label="埠號:" name="web_proxy_port" tool_tip="你希望使用的 HTTP 代理伺服器的埠號。"/> + <check_box label="使用 SOCKS 5 代理伺服器處理 UDP 資料流" name="socks_proxy_enabled"/> + <text name="socks5_proxy_label"> + SOCKS 5 代理伺服器: + </text> + <line_editor name="socks_proxy_editor" tool_tip="你希望使用的 SOCKS 5 代理伺服器的 DNS 名稱或 IP 位址。"/> + <spinner label="埠號:" name="socks_proxy_port" tool_tip="你希望使用的 SOCKS 5 代理伺服器的埠號。"/> + <text name="socks_auth_label"> + SOCKS 鑒認: + </text> + <radio_group name="socks5_auth_type"> + <radio_item label="無鑒認" name="Socks5NoAuth" tool_tip="Socks5 代理伺服器無需鑒認。" value="無"/> + <radio_item label="使用者名稱 / 密碼" name="Socks5UserPass" tool_tip="Socks5 代理伺服器需要透過使用者名稱 / 密碼鑒認。" value="UserPass"/> + </radio_group> + <text name="socks5_username_label"> + 使用者名稱: + </text> + <text name="socks5_password_label"> + 密碼: + </text> + <line_editor name="socks5_username" tool_tip="你的 SOCKS 5 伺服器鑒認所用的使用者名稱"/> + <line_editor name="socks5_password" tool_tip="你的 SOCKS 5 伺服器鑒認所用的密碼"/> + <text name="other_proxy_label"> + 其他 HTTP 資料流代理伺服器: + </text> + <radio_group name="other_http_proxy_type"> + <radio_item label="不使用代理伺服器" name="OtherNoProxy" tool_tip="非網頁的 HTTP 資料流不會被導向任何代理伺服器。" value="無"/> + <radio_item label="使用 HTTP 代理伺服器" name="OtherHTTPProxy" tool_tip="非網頁的 HTTP 資料流將導向所設的網頁代理伺服器。" value="網頁"/> + <radio_item label="使用 SOCKS 5 代理伺服器" name="OtherSocksProxy" tool_tip="非網頁的 HTTP 資料流將導向所設的 Socks 5 代理伺服器。" value="網路套接"/> + </radio_group> + <button label="確定" label_selected="確定" name="OK"/> + <button label="取消" label_selected="取消" name="Cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_animation.xml b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml index c435ddc0bd..b94d67b7ef 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="preview_anim"> <floater.string name="Title"> - 動作: [NAME] + 動作:[NAME] </floater.string> <text name="desc txt"> 描述: </text> - <button label="播放於虛擬世界" label_selected="停止" name="Anim play btn" tool_tip="Play this animation so that others can see it"/> - <button label="播放於本地" label_selected="停止" name="Anim audition btn" tool_tip="Play this animation so that only you can see it"/> + <button label="在虛擬世界播放" label_selected="停止" name="Inworld" tool_tip="播放此動作讓他人看見"/> + <button label="在本地播放" label_selected="停止" name="Locally" tool_tip="播放此動作,只給自己看"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml index ad49370423..be75038a09 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="gesture_preview"> <floater.string name="step_anim"> - Animation to play: + 要播放的動作: </floater.string> <floater.string name="step_sound"> - Sound to play: + 要播放的聲音: </floater.string> <floater.string name="step_chat"> - Chat to say: + 要說出的聊天文字: </floater.string> <floater.string name="step_wait"> - Wait: + 等待: </floater.string> <floater.string name="stop_txt"> 停止 @@ -22,20 +22,20 @@ -- 無 -- </floater.string> <floater.string name="Title"> - Gesture: [NAME] + 姿勢:[NAME] </floater.string> <text name="desc_label"> 描述: </text> <text name="trigger_label"> - Trigger: + 觸發: </text> - <text name="replace_text" tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture!"> - Replace with: + <text name="replace_text" tool_tip="用這些字眼取代觸發字眼。 例如,觸發 'hello' 取代為 'howdy' 後,將使得聊天文字「我想說 hello」變成「我想說 howdy」,同時還會播放該姿勢!"> + 取代成: </text> - <line_editor name="replace_editor" tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture"/> + <line_editor name="replace_editor" tool_tip="用這些字眼取代觸發字眼。 例如,觸發 'hello' 取代為 'howdy' 後,將使得聊天文字「我想說 hello」變成「我想說 howdy」,同時還會播放該姿勢。"/> <text name="key_label"> - Shortcut Key: + 快捷鍵: </text> <combo_box label="無" name="modifier_combo"/> <combo_box label="無" name="key_combo"/> @@ -50,10 +50,10 @@ </scroll_list> <button label="添加 >>" name="add_btn"/> <text name="steps_label"> - Steps: + 步驟: </text> - <button label="Up" name="up_btn"/> - <button label="Down" name="down_btn"/> + <button label="上移鍵" name="up_btn"/> + <button label="下移鍵" name="down_btn"/> <button label="移除" name="delete_btn"/> <text name="options_text"> (選項) @@ -63,11 +63,11 @@ <radio_item label="停止" name="stop"/> </radio_group> <check_box label="直到動作結束。" name="wait_anim_check"/> - <check_box label="time in seconds:" name="wait_time_check"/> + <check_box label="時間(秒):" name="wait_time_check"/> <text name="help_label"> - All steps happen simultaneously, unless you add wait steps. + 所有步驟都會同時進行,除非你加入「等待」步驟。 </text> - <check_box label="Active" name="active_check" tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict."/> + <check_box label="可用" name="active_check" tool_tip="你可以在聊天中鍵入「觸發字眼」,或按某姿勢的熱鍵來啟動可用的姿勢。 熱鍵的綁定若有衝突,通常會使姿勢變成不可用。"/> <button label="預覽" name="preview_btn"/> <button label="儲存" name="save_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_sound.xml b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml index 46844349de..d04428a36d 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_sound.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml @@ -6,6 +6,6 @@ <text name="desc txt"> 描述: </text> - <button label="播放於虛擬世界" label_selected="播放於虛擬世界" name="Sound play btn" tool_tip="Play this sound so that others can hear it"/> - <button label="播放於本地" label_selected="播放於本地" name="Sound audition btn" tool_tip="Play this sound so that only you can hear it"/> + <button label="在虛擬世界播放" label_selected="在虛擬世界播放" name="Sound play btn" tool_tip="播放此聲音讓他人聽見"/> + <button label="在本地播放" label_selected="在本地播放" name="Sound audition btn" tool_tip="播放此聲音,只讓自己聽見"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml index 02e26cea24..c56b1c2987 100644 --- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml @@ -10,31 +10,31 @@ 描述: </text> <text name="dimensions"> - [WIDTH]px x [HEIGHT]px + [WIDTH] 像素 X [HEIGHT] 像素 </text> <text name="aspect_ratio"> - Preview aspect ratio + 預覽長寬比 </text> - <combo_box name="combo_aspect_ratio" tool_tip="Preview at a fixed aspect ratio"> + <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽"> <combo_item name="Unconstrained"> - Unconstrained + 不受限 </combo_item> - <combo_item name="1:1" tool_tip="Group insignia or Real World profile"> + <combo_item name="1:1" tool_tip="群組徽章或現實世界小檔案"> 1:1 </combo_item> <combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案"> 4:3 </combo_item> - <combo_item name="10:7" tool_tip="Classifieds and search listings, landmarks"> + <combo_item name="10:7" tool_tip="個人廣告和搜索刊登廣告、地標"> 10:7 </combo_item> - <combo_item name="3:2" tool_tip="關於土地"> + <combo_item name="3:2" tool_tip="土地資料"> 3:2 </combo_item> <combo_item name="16:10"> 16:10 </combo_item> - <combo_item name="16:9" tool_tip="Profile picks"> + <combo_item name="16:9" tool_tip="個人檔案精選"> 16:9 </combo_item> <combo_item name="2:1"> @@ -42,6 +42,6 @@ </combo_item> </combo_box> <button label="確定" name="Keep"/> - <button label="Discard" name="Discard"/> - <button label="另存" name="save_tex_btn"/> + <button label="丟棄" name="Discard"/> + <button label="另存為" name="save_tex_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml b/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml new file mode 100644 index 0000000000..078b490655 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="price_for_listing" title="刊登個人廣告"> + <text name="explanation_text"> + 你的個人廣告將從刊登日起連續刊載一星期。 + +你的廣告在個人廣告欄出現的位置,取決於你決定付費的多寡。 + +付費越多的個人廣告會出現在接近最上方位置,並顯示於搜尋結果的前面。 + </text> + <text name="price_text"> + 刊登費: + </text> + <text name="price_symbol"> + L$ + </text> + <button label="確定" name="set_price_btn"/> + <button label="取消" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_publish_classified.xml b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml index 5f0ffea182..b810af0145 100644 --- a/indra/newview/skins/default/xui/zh/floater_publish_classified.xml +++ b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="publish_classified" title="Publishing Classified"> +<floater name="publish_classified" title="刊登個人廣告"> <text name="explanation_text"> - Your classified ad will run for one week from the date it is published. + 你的個人廣告將從刊登日起連續刊載一星期。 -Remember, Classified fees are non-refundable. +請注意,個人廣告刊登費恕不退還。 </text> - <spinner label="價格: L$" name="price_for_listing" tool_tip="刊登費用。" value="50"/> + <spinner label="價格: L$" name="price_for_listing" tool_tip="刊登費。" value="50"/> <button label="發布" name="publish_btn"/> <button label="取消" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_report_abuse.xml b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml index 436f5cdcc5..8dbc216ab5 100644 --- a/indra/newview/skins/default/xui/zh/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml @@ -14,66 +14,66 @@ 地區名稱 </text> <text name="pos_title"> - Position: + 位置: </text> <text name="pos_field"> {128.1, 128.1, 15.4} </text> <text name="select_object_label"> - Click the button, then the abusive object: + 點按按鈕,再點按違紀的物件: </text> - <button name="pick_btn" tool_tip="Object Picker - Identify an object as the subject of this report"/> + <button name="pick_btn" tool_tip="物件選取器 - 指明本舉報的對象物件"/> <text name="object_name_label"> 物件: </text> <text name="owner_name_label"> - 擁有者: + 所有人: </text> - <combo_box name="category_combo" tool_tip="Category -- select the category that best describes this report"> + <combo_box name="category_combo" tool_tip="類別 -- 選擇最符合此次舉報內容的類別"> <combo_box.item label="選擇類別" name="Select_category"/> - <combo_box.item label="Age > Age play" name="Age__Age_play"/> - <combo_box.item label="Age > Adult Resident on Teen Second Life" name="Age__Adult_resident_on_Teen_Second_Life"/> - <combo_box.item label="Age > Underage Resident outside of Teen Second Life" name="Age__Underage_resident_outside_of_Teen_Second_Life"/> - <combo_box.item label="Assault > Combat sandbox / unsafe area" name="Assault__Combat_sandbox___unsafe_area"/> - <combo_box.item label="Assault > Safe area" name="Assault__Safe_area"/> - <combo_box.item label="Assault > Weapons testing sandbox" name="Assault__Weapons_testing_sandbox"/> - <combo_box.item label="Commerce > Failure to deliver product or service" name="Commerce__Failure_to_deliver_product_or_service"/> - <combo_box.item label="Disclosure > Real world information" name="Disclosure__Real_world_information"/> - <combo_box.item label="Disclosure > Remotely monitoring chat" name="Disclosure__Remotely_monitoring chat"/> - <combo_box.item label="Disclosure > Second Life information/chat/IMs" name="Disclosure__Second_Life_information_chat_IMs"/> - <combo_box.item label="Disturbing the peace > Unfair use of region resources" name="Disturbing_the_peace__Unfair_use_of_region_resources"/> - <combo_box.item label="Disturbing the peace > Excessive scripted objects" name="Disturbing_the_peace__Excessive_scripted_objects"/> - <combo_box.item label="Disturbing the peace > Object littering" name="Disturbing_the_peace__Object_littering"/> - <combo_box.item label="Disturbing the peace > Repetitive spam" name="Disturbing_the_peace__Repetitive_spam"/> - <combo_box.item label="Disturbing the peace > Unwanted advert spam" name="Disturbing_the_peace__Unwanted_advert_spam"/> - <combo_box.item label="Fraud > L$" name="Fraud__L$"/> - <combo_box.item label="Fraud > Land" name="Fraud__Land"/> - <combo_box.item label="Fraud > Pyramid scheme or chain letter" name="Fraud__Pyramid_scheme_or_chain_letter"/> - <combo_box.item label="Fraud > US$" name="Fraud__US$"/> - <combo_box.item label="Harassment > Advert farms / visual spam" name="Harassment__Advert_farms___visual_spam"/> - <combo_box.item label="Harassment > Defaming individuals or groups" name="Harassment__Defaming_individuals_or_groups"/> - <combo_box.item label="Harassment > Impeding movement" name="Harassment__Impeding_movement"/> - <combo_box.item label="Harassment > Sexual harassment" name="Harassment__Sexual_harassment"/> - <combo_box.item label="Harassment > Solicting/inciting others to violate ToS" name="Harassment__Solicting_inciting_others_to_violate_ToS"/> - <combo_box.item label="Harassment > Verbal abuse" name="Harassment__Verbal_abuse"/> - <combo_box.item label="Indecency > Broadly offensive content or conduct" name="Indecency__Broadly_offensive_content_or_conduct"/> - <combo_box.item label="Indecency > Inappropriate avatar name" name="Indecency__Inappropriate_avatar_name"/> - <combo_box.item label="Indecency > Inappropriate content or conduct in a PG region" name="Indecency__Mature_content_in_PG_region"/> - <combo_box.item label="Indecency > Inappropriate content or conduct in a Moderate region" name="Indecency__Inappropriate_content_in_Mature_region"/> - <combo_box.item label="Intellectual property infringement > Content Removal" name="Intellectual_property_infringement_Content_Removal"/> - <combo_box.item label="Intellectual property infringement > CopyBot or Permissions Exploit" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/> - <combo_box.item label="Intolerance" name="Intolerance"/> - <combo_box.item label="Land > Abuse of sandbox resources" name="Land__Abuse_of_sandbox_resources"/> - <combo_box.item label="Land > Encroachment > Objects/textures" name="Land__Encroachment__Objects_textures"/> - <combo_box.item label="Land > Encroachment > Particles" name="Land__Encroachment__Particles"/> - <combo_box.item label="Land > Encroachment > Trees/plants" name="Land__Encroachment__Trees_plants"/> - <combo_box.item label="Wagering/gambling" name="Wagering_gambling"/> + <combo_box.item label="年齡 > 年齡 play" name="Age__Age_play"/> + <combo_box.item label="年齡 > 成人居民出現在青少年專用第二人生" name="Age__Adult_resident_on_Teen_Second_Life"/> + <combo_box.item label="年齡 > 未成年居民出現在青少年專用第二人生以外場所" name="Age__Underage_resident_outside_of_Teen_Second_Life"/> + <combo_box.item label="攻擊 > 戰鬥沙盤 / 不安全區域" name="Assault__Combat_sandbox___unsafe_area"/> + <combo_box.item label="攻擊 > 安全區域" name="Assault__Safe_area"/> + <combo_box.item label="攻擊 > 測試武器的沙盤" name="Assault__Weapons_testing_sandbox"/> + <combo_box.item label="商業 > 未送交產品或履行服務" name="Commerce__Failure_to_deliver_product_or_service"/> + <combo_box.item label="揭露 > 真實世界資訊" name="Disclosure__Real_world_information"/> + <combo_box.item label="揭露 > 遠端監控聊天內容" name="Disclosure__Remotely_monitoring chat"/> + <combo_box.item label="揭露 > 第二人生資訊 / 聊天內容 / 即時訊息" name="Disclosure__Second_Life_information_chat_IMs"/> + <combo_box.item label="擾亂 > 不公平使用地區資源" name="Disturbing_the_peace__Unfair_use_of_region_resources"/> + <combo_box.item label="擾亂 > 過度使用帶腳本的物件" name="Disturbing_the_peace__Excessive_scripted_objects"/> + <combo_box.item label="擾亂 > 任意棄置物件" name="Disturbing_the_peace__Object_littering"/> + <combo_box.item label="擾亂 > 一再發出垃圾訊息" name="Disturbing_the_peace__Repetitive_spam"/> + <combo_box.item label="擾亂 > 不受歡迎的垃圾廣告" name="Disturbing_the_peace__Unwanted_advert_spam"/> + <combo_box.item label="詐欺 > L$" name="Fraud__L$"/> + <combo_box.item label="詐欺 > 土地" name="Fraud__Land"/> + <combo_box.item label="詐欺 > 層壓式推銷或連環信" name="Fraud__Pyramid_scheme_or_chain_letter"/> + <combo_box.item label="詐欺 > 美金" name="Fraud__US$"/> + <combo_box.item label="騷擾 > 廣告農場 / 視覺轟炸" name="Harassment__Advert_farms___visual_spam"/> + <combo_box.item label="騷擾 > 詆譭個人或群組" name="Harassment__Defaming_individuals_or_groups"/> + <combo_box.item label="騷擾 > 阻撓移動" name="Harassment__Impeding_movement"/> + <combo_box.item label="騷擾 > 性騷擾" name="Harassment__Sexual_harassment"/> + <combo_box.item label="騷擾 > 鼓吹 / 教唆他人違反服務條款" name="Harassment__Solicting_inciting_others_to_violate_ToS"/> + <combo_box.item label="騷擾 > 言語暴力" name="Harassment__Verbal_abuse"/> + <combo_box.item label="不雅 > 令大多人不快的內容或行為" name="Indecency__Broadly_offensive_content_or_conduct"/> + <combo_box.item label="不雅 > 冒犯人的化身名稱" name="Indecency__Inappropriate_avatar_name"/> + <combo_box.item label="不雅 > 在一般普級地區出現冒犯人的內容或行為" name="Indecency__Mature_content_in_PG_region"/> + <combo_box.item label="不雅 > 在適度成人地區出現冒犯人的內容或行為" name="Indecency__Inappropriate_content_in_Mature_region"/> + <combo_box.item label="侵犯智產權 > 移除內容" name="Intellectual_property_infringement_Content_Removal"/> + <combo_box.item label="侵犯智產權 > 複製機器程式碼 CopyBot 或濫用權限" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/> + <combo_box.item label="不容異己" name="Intolerance"/> + <combo_box.item label="土地 > 不當使用沙盤資源" name="Land__Abuse_of_sandbox_resources"/> + <combo_box.item label="土地 > 侵佔 > 物件 / 材質" name="Land__Encroachment__Objects_textures"/> + <combo_box.item label="土地 > 侵佔 > 粒子" name="Land__Encroachment__Particles"/> + <combo_box.item label="土地 > 侵佔 > 樹種 / 植物" name="Land__Encroachment__Trees_plants"/> + <combo_box.item label="下注 / 賭博" name="Wagering_gambling"/> <combo_box.item label="其他" name="Other"/> </combo_box> <text name="abuser_name_title"> 濫用者名稱: </text> - <button label="選擇" name="select_abuser" tool_tip="Select the name of the abuser from a list"/> + <button label="選擇" name="select_abuser" tool_tip="從清單中選擇違紀者姓名"/> <text name="abuser_name_title2"> 濫用位置: </text> @@ -84,11 +84,11 @@ 細節: </text> <text name="bug_aviso"> - Please be as specific as possible + 請盡可能提供具體細節 </text> <text name="incomplete_title"> - * Incomplete reports won't be investigated + * 不完整的舉報內容概不受理調查 </text> - <button label="舉報濫用" label_selected="舉報濫用" name="send_btn"/> + <button label="違規舉報" label_selected="違規舉報" name="send_btn"/> <button label="取消" label_selected="取消" name="cancel_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_script_preview.xml b/indra/newview/skins/default/xui/zh/floater_script_preview.xml index c3d05402c0..a6c6c76181 100644 --- a/indra/newview/skins/default/xui/zh/floater_script_preview.xml +++ b/indra/newview/skins/default/xui/zh/floater_script_preview.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="preview lsl text" title="SCRIPT: ROTATION SCRIPT"> +<floater name="preview lsl text" title="腳本:旋轉腳本"> <floater.string name="Title"> 腳本:[NAME] </floater.string> diff --git a/indra/newview/skins/default/xui/zh/floater_script_queue.xml b/indra/newview/skins/default/xui/zh/floater_script_queue.xml index ff02946d86..7c253aa74c 100644 --- a/indra/newview/skins/default/xui/zh/floater_script_queue.xml +++ b/indra/newview/skins/default/xui/zh/floater_script_queue.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="queue" title="RESET PROGRESS"> +<floater name="queue" title="重設進度"> <floater.string name="Starting"> - Starting [START] of [COUNT] items. + 正在啟動 [START] 項,共 [COUNT] 項。 </floater.string> <floater.string name="Done"> - Done. + 完成。 </floater.string> <floater.string name="Resetting"> 重設中 diff --git a/indra/newview/skins/default/xui/zh/floater_script_search.xml b/indra/newview/skins/default/xui/zh/floater_script_search.xml index 400ef4be81..11c23d933f 100644 --- a/indra/newview/skins/default/xui/zh/floater_script_search.xml +++ b/indra/newview/skins/default/xui/zh/floater_script_search.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="script search" title="腳本搜尋"> - <check_box label="Case Insensitive" name="case_text"/> + <check_box label="大小寫視為相同" name="case_text"/> <button label="搜尋" label_selected="搜尋" name="search_btn"/> <button label="取代" label_selected="取代" name="replace_btn"/> <button label="全部取代" label_selected="全部取代" name="replace_all_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_search.xml b/indra/newview/skins/default/xui/zh/floater_search.xml index bb693b7a70..3e85a529ae 100644 --- a/indra/newview/skins/default/xui/zh/floater_search.xml +++ b/indra/newview/skins/default/xui/zh/floater_search.xml @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_search" title="尋找"> +<floater name="floater_search" title=""> <floater.string name="loading_text"> 載入中... </floater.string> <floater.string name="done_text"> - Done + 完成 </floater.string> <layout_stack name="stack1"> <layout_panel name="browser_layout"> <text name="refresh_search"> - Redo search to reflect current God level + 以目前具備的神階級再搜尋一次 </text> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/zh/floater_select_key.xml b/indra/newview/skins/default/xui/zh/floater_select_key.xml index c1661635f1..231eb48b04 100644 --- a/indra/newview/skins/default/xui/zh/floater_select_key.xml +++ b/indra/newview/skins/default/xui/zh/floater_select_key.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="modal container"> <text name="Save item as:"> - Press a key to set your Speak button trigger. + 按任一鍵設定「說話」按鈕的觸發。 </text> <button label="取消" label_selected="取消" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_sell_land.xml b/indra/newview/skins/default/xui/zh/floater_sell_land.xml index 19580c99a1..9030f7eb63 100644 --- a/indra/newview/skins/default/xui/zh/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/zh/floater_sell_land.xml @@ -12,16 +12,16 @@ 尺寸: </text> <text name="info_size"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="info_action"> - To sell this parcel: + 出售地段: </text> <text name="price_label"> - 1. Set a price: + 1. 訂定價格: </text> <text name="price_text"> - Choose an appropriate price. + 選擇適合的價格。 </text> <text name="price_ld"> L$ @@ -30,13 +30,13 @@ 0 </line_editor> <text name="price_per_m"> - (L$[PER_METER] per m²) + (每平方公尺 L$[PER_METER]) </text> <text name="sell_to_label"> - 2. Sell the land to: + 2. 出售土地給: </text> <text name="sell_to_text"> - Choose whether to sell to anyone or a particular buyer. + 選擇要賣給任何人或賣給特定買主。 </text> <combo_box name="sell_to"> <combo_box.item label="- 選擇一個 -" name="--selectone--"/> @@ -45,20 +45,20 @@ </combo_box> <button label="選擇" name="sell_to_select_agent"/> <text name="sell_objects_label"> - 3. Sell the objects with the land? + 3. 物件連同土地一起售出? </text> <text name="sell_objects_text"> - Land owner's transferable objects on parcel will change ownership. + 地段上地主的可轉讓物件將過繼所有權。 </text> <radio_group name="sell_objects"> - <radio_item label="No, keep ownership of objects" name="no"/> - <radio_item label="Yes, sell objects with land" name="yes"/> + <radio_item label="不,我要保留物件所有權" name="no"/> + <radio_item label="好,物件連同土地一起售出" name="yes"/> </radio_group> <button label="顯示物件" name="show_objects"/> <text name="nag_message_label"> - REMEMBER: All sales are final. + 請記住:售後一概不退。 </text> - <button label="Set Land For Sale" name="sell_btn"/> + <button label="設定土地待售" name="sell_btn"/> <button label="取消" name="cancel_btn"/> </panel> </scroll_container> diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml index 9edc19969f..e86e20829f 100644 --- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml @@ -1,74 +1,65 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Snapshot" title="SNAPSHOT PREVIEW"> +<floater name="Snapshot" title="快照預覽"> <floater.string name="unknown"> 未知 </floater.string> - <radio_group label="Snapshot type" name="snapshot_type_radio"> - <radio_item label="Email" name="postcard"/> - <radio_item label="我的收納區(L$[AMOUNT])" name="texture"/> - <radio_item label="Save to my computer" name="local"/> - </radio_group> + <string name="postcard_progress_str"> + 正在發送電郵 + </string> + <string name="profile_progress_str"> + 發佈 + </string> + <string name="inventory_progress_str"> + 儲存到收納區 + </string> + <string name="local_progress_str"> + 正在存到電腦 + </string> + <string name="profile_succeeded_str"> + 圖像已上傳 + </string> + <string name="postcard_succeeded_str"> + 電郵發送成功! + </string> + <string name="inventory_succeeded_str"> + 成功存入收納區! + </string> + <string name="local_succeeded_str"> + 成功存入電腦! + </string> + <string name="profile_failed_str"> + 上傳圖像到你的檔案訊息發佈時出錯。 + </string> + <string name="postcard_failed_str"> + 電郵傳送失敗。 + </string> + <string name="inventory_failed_str"> + 無法存入收納區。 + </string> + <string name="local_failed_str"> + 無法儲入電腦。 + </string> + <button name="advanced_options_btn" tool_tip="進階選項"/> + <text name="image_res_text"> + [WIDTH] x [HEIGHT] 像素 + </text> <text name="file_size_label"> [SIZE] KB </text> - <button label="送出" name="send_btn"/> - <button label="儲存(L$[AMOUNT])" name="upload_btn"/> - <flyout_button label="儲存" name="save_btn" tool_tip="儲存圖像到檔案"> - <flyout_button.item label="儲存" name="save_item"/> - <flyout_button.item label="另存..." name="saveas_item"/> - </flyout_button> - <button label="更多" name="more_btn" tool_tip="進階選項"/> - <button label="更少" name="less_btn" tool_tip="進階選項"/> - <button label="取消" name="discard_btn"/> - <text name="type_label2"> - 尺寸 - </text> - <text name="format_label"> - Format - </text> - <combo_box label="Resolution" name="postcard_size_combo"> - <combo_box.item label="目前視窗" name="CurrentWindow"/> - <combo_box.item label="640x480" name="640x480"/> - <combo_box.item label="800x600" name="800x600"/> - <combo_box.item label="1024x768" name="1024x768"/> - <combo_box.item label="自訂" name="Custom"/> - </combo_box> - <combo_box label="Resolution" name="texture_size_combo"> - <combo_box.item label="目前視窗" name="CurrentWindow"/> - <combo_box.item label="Small (128x128)" name="Small(128x128)"/> - <combo_box.item label="Medium (256x256)" name="Medium(256x256)"/> - <combo_box.item label="Large (512x512)" name="Large(512x512)"/> - <combo_box.item label="自訂" name="Custom"/> - </combo_box> - <combo_box label="Resolution" name="local_size_combo"> - <combo_box.item label="目前視窗" name="CurrentWindow"/> - <combo_box.item label="320x240" name="320x240"/> - <combo_box.item label="640x480" name="640x480"/> - <combo_box.item label="800x600" name="800x600"/> - <combo_box.item label="1024x768" name="1024x768"/> - <combo_box.item label="1280x1024" name="1280x1024"/> - <combo_box.item label="1600x1200" name="1600x1200"/> - <combo_box.item label="Custom" name="Custom"/> - </combo_box> - <combo_box label="Format" name="local_format_combo"> - <combo_box.item label="PNG" name="PNG"/> - <combo_box.item label="JPEG" name="JPEG"/> - <combo_box.item label="BMP" name="BMP"/> - </combo_box> - <spinner label="Width" name="snapshot_width"/> - <spinner label="Height" name="snapshot_height"/> - <check_box label="Constrain proportions" name="keep_aspect_check"/> - <slider label="圖像品質" name="image_quality_slider"/> - <text name="layer_type_label"> - Capture: - </text> - <combo_box label="圖層" name="layer_types"> - <combo_box.item label="Colors" name="Colors"/> - <combo_box.item label="Depth" name="Depth"/> - </combo_box> - <check_box label="Interface" name="ui_check"/> - <check_box label="HUDs" name="hud_check"/> - <check_box label="Keep open after saving" name="keep_open_check"/> - <check_box label="凍結框架(全螢幕)" name="freeze_frame_check"/> - <check_box label="Auto-refresh" name="auto_snapshot_check"/> + <panel name="advanced_options_panel"> + <text name="advanced_options_label"> + 進階選項 + </text> + <text name="layer_type_label"> + 擷取快照: + </text> + <combo_box label="圖層" name="layer_types"> + <combo_box.item label="顏色" name="Colors"/> + <combo_box.item label="深度" name="Depth"/> + </combo_box> + <check_box label="介面" name="ui_check"/> + <check_box label="擡頭顯示" name="hud_check"/> + <check_box label="將幀凍結(全螢幕)" name="freeze_frame_check"/> + <check_box label="自動刷新" name="auto_snapshot_check"/> + </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_sound_devices.xml b/indra/newview/skins/default/xui/zh/floater_sound_devices.xml new file mode 100644 index 0000000000..0374c74f8f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_sound_devices.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_sound_devices" title="聲音裝置"> + <text name="voice_label"> + 語音聊天 + </text> + <check_box label="已啟用" name="enable_voice"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_spellcheck.xml b/indra/newview/skins/default/xui/zh/floater_spellcheck.xml new file mode 100644 index 0000000000..f5a6665844 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_spellcheck.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_floater" title="拼字檢查設定"> + <check_box label="啟用拼字檢查" name="spellcheck_enable"/> + <text name="spellcheck_main"> + 主要字典: + </text> + <text label="記錄:" name="spellcheck_additional"> + 附加字典: + </text> + <text name="spellcheck_available"> + 可用的 + </text> + <text name="spellcheck_active"> + 可用 + </text> + <button label="移除" name="spellcheck_remove_btn"/> + <button label="匯入…" name="spellcheck_import_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml new file mode 100644 index 0000000000..6094a3bbce --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="spellcheck_import" title="匯入字典"> + <button label="瀏覽" label_selected="瀏覽" name="dictionary_path_browse"/> + <button label="匯入" name="ok_btn"/> + <button label="取消" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_stats.xml b/indra/newview/skins/default/xui/zh/floater_stats.xml index 582572d0e2..4af5684ec1 100644 --- a/indra/newview/skins/default/xui/zh/floater_stats.xml +++ b/indra/newview/skins/default/xui/zh/floater_stats.xml @@ -3,67 +3,84 @@ <scroll_container name="statistics_scroll"> <container_view name="statistics_view"> <stat_view label="基本" name="basic"> - <stat_bar label="FPS" name="fps"/> + <stat_bar label="每秒幀數" name="fps"/> <stat_bar label="頻寬" name="bandwidth"/> <stat_bar label="封包損失" name="packet_loss"/> - <stat_bar label="Ping Sim" name="ping"/> + <stat_bar label="探詢模擬器有無反應" name="ping"/> </stat_view> <stat_view label="進階" name="advanced"> - <stat_view label="Render" name="render"> - <stat_bar label="KTris Drawn" name="ktrisframe"/> - <stat_bar label="KTris Drawn" name="ktrissec"/> + <stat_view label="呈像" name="render"> + <stat_bar label="繪出的 KTris(每幀)" name="ktrisframe"/> + <stat_bar label="繪出的 KTris(每秒)" name="ktrissec"/> <stat_bar label="物件總計" name="objs"/> <stat_bar label="新物件" name="newobjs"/> + <stat_bar label="物件快取讀取率" name="object_cache_hits"/> </stat_view> <stat_view label="材質" name="texture"> + <stat_bar label="快取讀取率" name="texture_cache_hits"/> + <stat_bar label="快取讀取延遲" name="texture_cache_read_latency"/> <stat_bar label="計數" name="numimagesstat"/> - <stat_bar label="Raw Count" name="numrawimagesstat"/> - <stat_bar label="GL Mem" name="gltexmemstat"/> - <stat_bar label="Formatted Mem" name="formattedmemstat"/> - <stat_bar label="Raw Mem" name="rawmemstat"/> - <stat_bar label="Bound Mem" name="glboundmemstat"/> + <stat_bar label="原始計數" name="numrawimagesstat"/> + <stat_bar label="GL 記憶" name="gltexmemstat"/> + <stat_bar label="格式化記憶" name="formattedmemstat"/> + <stat_bar label="原始記憶" name="rawmemstat"/> + <stat_bar label="界限記憶" name="glboundmemstat"/> </stat_view> <stat_view label="網路" name="network"> - <stat_bar label="Packets In" name="packetsinstat"/> - <stat_bar label="Packets Out" name="packetsoutstat"/> + <stat_bar label="進入封包" name="packetsinstat"/> + <stat_bar label="出去封包" name="packetsoutstat"/> <stat_bar label="物件" name="objectkbitstat"/> <stat_bar label="材質" name="texturekbitstat"/> <stat_bar label="資產" name="assetkbitstat"/> - <stat_bar label="Layers" name="layerskbitstat"/> - <stat_bar label="Actual In" name="actualinkbitstat"/> - <stat_bar label="Actual Out" name="actualoutkbitstat"/> - <stat_bar label="VFS Pending Ops" name="vfspendingoperations"/> + <stat_bar label="層次" name="layerskbitstat"/> + <stat_bar label="實入" name="actualinkbitstat"/> + <stat_bar label="實出" name="actualoutkbitstat"/> + <stat_bar label="VFS 待行作業" name="vfspendingoperations"/> </stat_view> </stat_view> <stat_view label="模擬器" name="sim"> - <stat_bar label="Time Dilation" name="simtimedilation"/> - <stat_bar label="Sim FPS" name="simfps"/> - <stat_bar label="Physics FPS" name="simphysicsfps"/> - <stat_view label="Physics Details" name="physicsdetail"> - <stat_bar label="Pinned Objects" name="physicspinnedtasks"/> - <stat_bar label="Low LOD Objects" name="physicslodtasks"/> + <stat_bar label="時間膨脹" name="simtimedilation"/> + <stat_bar label="模擬器每秒幀數" name="simfps"/> + <stat_bar label="物理引擎每秒幀數" name="simphysicsfps"/> + <stat_view label="物理細節" name="physicsdetail"> + <stat_bar label="固位物件" name="physicspinnedtasks"/> + <stat_bar label="低細節層次物件" name="physicslodtasks"/> <stat_bar label="記憶體配置" name="physicsmemoryallocated"/> </stat_view> - <stat_bar label="Agent Updates/Sec" name="simagentups"/> - <stat_bar label="Main Agents" name="simmainagents"/> - <stat_bar label="Child Agents" name="simchildagents"/> + <stat_bar label="用戶更新 / 秒" name="simagentups"/> + <stat_bar label="主要用戶" name="simmainagents"/> + <stat_bar label="兒童用戶" name="simchildagents"/> <stat_bar label="物件" name="simobjects"/> - <stat_bar label="Active Objects" name="simactiveobjects"/> - <stat_bar label="Active Scripts" name="simactivescripts"/> + <stat_bar label="使用中物件" name="simactiveobjects"/> + <stat_bar label="使用中腳本" name="simactivescripts"/> + <stat_bar label="腳本執行" name="simpctscriptsrun"/> <stat_bar label="腳本事件" name="simscripteps"/> + <stat_view label="尋徑" name="simpathfinding"> + <stat_bar label="人工智慧步驟時間" name="simsimaistepmsec"/> + <stat_bar label="已略過輪廓步驟" name="simsimskippedsilhouettesteps"/> + <stat_bar label="角色已更新" name="simsimpctsteppedcharacters"/> + </stat_view> <stat_bar label="進入封包" name="siminpps"/> <stat_bar label="出去封包" name="simoutpps"/> <stat_bar label="擱置下載" name="simpendingdownloads"/> <stat_bar label="擱置上傳" name="simpendinguploads"/> - <stat_bar label="Total Unacked Bytes" name="simtotalunackedbytes"/> - <stat_view label="Time (ms)" name="simperf"> - <stat_bar label="Total Frame Time" name="simframemsec"/> - <stat_bar label="Net Time" name="simnetmsec"/> - <stat_bar label="Physics Time" name="simsimphysicsmsec"/> - <stat_bar label="Simulation Time" name="simsimothermsec"/> - <stat_bar label="Agent Time" name="simagentmsec"/> - <stat_bar label="Images Time" name="simimagesmsec"/> + <stat_bar label="未承認的總位元組數" name="simtotalunackedbytes"/> + <stat_view label="時間(毫秒)" name="simperf"> + <stat_bar label="總禎時間" name="simframemsec"/> + <stat_bar label="淨時間" name="simnetmsec"/> + <stat_bar label="物理時間" name="simsimphysicsmsec"/> + <stat_bar label="模擬時間" name="simsimothermsec"/> + <stat_bar label="用戶時間" name="simagentmsec"/> + <stat_bar label="圖像時間" name="simimagesmsec"/> <stat_bar label="腳本時間" name="simscriptmsec"/> + <stat_bar label="閒置時間" name="simsparemsec"/> + <stat_view label="時間細節(毫秒)" name="timedetails"> + <stat_bar label="物理步驟" name="simsimphysicsstepmsec"/> + <stat_bar label="更新物理形狀" name="simsimphysicsshapeupdatemsec"/> + <stat_bar label="物理(其他)" name="simsimphysicsothermsec"/> + <stat_bar label="睡眠時間" name="simsleepmsec"/> + <stat_bar label="Pump IO" name="simpumpiomsec"/> + </stat_view> </stat_view> </stat_view> </container_view> diff --git a/indra/newview/skins/default/xui/zh/floater_sys_well.xml b/indra/newview/skins/default/xui/zh/floater_sys_well.xml index fd27e944ac..ca0b7f146d 100644 --- a/indra/newview/skins/default/xui/zh/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/zh/floater_sys_well.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="sys_well_window" title="通知"> <string name="title_im_well_window"> - CONVERSATIONS + 交談 </string> <string name="title_notification_well_window"> 通知 diff --git a/indra/newview/skins/default/xui/zh/floater_telehub.xml b/indra/newview/skins/default/xui/zh/floater_telehub.xml index b4c9f3ab29..ee21a78e90 100644 --- a/indra/newview/skins/default/xui/zh/floater_telehub.xml +++ b/indra/newview/skins/default/xui/zh/floater_telehub.xml @@ -1,29 +1,29 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Explicit left edge to avoid overlapping build tools --> -<floater name="telehub" title="TELEHUB"> +<floater name="telehub" title="瞬間傳送中心"> <text name="status_text_connected"> - Telehub connected to object [OBJECT] + 瞬間傳送中心已連通物件 [OBJECT] </text> <text name="status_text_not_connected"> - No telehub connected. + 無連通的瞬間傳送中心。 </text> <text name="help_text_connected"> - To remove, click Disconnect. + 點按「中斷」即可移除。 </text> <text name="help_text_not_connected"> - Select object and click Connect Telehub. + 選擇物件,並點按「連通瞬間傳送中心」。 </text> - <button label="Connect Telehub" name="connect_btn"/> - <button label="Disconnect" name="disconnect_btn"/> + <button label="連通瞬間傳送中心" name="connect_btn"/> + <button label="中斷" name="disconnect_btn"/> <text name="spawn_points_text"> - Spawn Points (positions, not objects): + 產生點(位置而非物件): </text> - <button label="Add Spawn" name="add_spawn_point_btn"/> - <button label="Remove Spawn" name="remove_spawn_point_btn"/> + <button label="新增產生" name="add_spawn_point_btn"/> + <button label="移除產生" name="remove_spawn_point_btn"/> <text name="spawn_point_help"> - Select object and click "Add Spawn" to specify position. -You can then move or delete the object. -Positions are relative to the telehub center. -Select an item in list to highlight it inworld. + 選擇物件,並點按「新增產生」來指定位置。 +你可以接著移動或刪除該物件。 +位置是與瞬間傳送中心相對。 +從清單中選取一項,在虛擬世界中以高亮顯示。 </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml new file mode 100644 index 0000000000..68fcf3f7f7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="LAYOUTSTACK 測試"/> diff --git a/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml new file mode 100644 index 0000000000..83b6df6fe5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="測試浮動視窗"/> diff --git a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml index 01586ac153..e909a67e2c 100644 --- a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml @@ -1,23 +1,35 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="texture picker" title="PICK: TEXTURE"> +<floater name="texture picker" title="精選:材質"> <floater.string name="choose_picture"> - 點擊以挑選圖像 + 點按以挑選圖片 </floater.string> <floater.string name="pick title"> - Pick: + 精選地點: </floater.string> <text name="Multiple"> - Multiple textures + 多重材質 </text> + <radio_group name="mode_selection"> + <radio_item label="收納區" name="inventory" value="0"/> + <radio_item label="本地" name="local" value="1"/> + </radio_group> <text name="unknown"> 尺寸:[DIMENSIONS] </text> <button label="預設" label_selected="預設" name="Default"/> + <button label="空白" label_selected="空白" name="Blank"/> <button label="無" label_selected="無" name="None"/> - <button label="Blank" label_selected="Blank" name="Blank"/> - <check_box initial_value="true" label="立即套用" name="apply_immediate_check"/> + <check_box initial_value="true" label="實時預覽" name="apply_immediate_check"/> + <text name="preview_disabled" value="已停用預覽"/> <filter_editor label="材質過濾器" name="inventory search editor"/> <check_box initial_value="false" label="顯示資料夾" name="show_folders_check"/> + <button label="添加" label_selected="添加" name="l_add_btn"/> + <button label="移除" label_selected="移除" name="l_rem_btn"/> + <button label="上傳" label_selected="上傳" name="l_upl_btn"/> + <scroll_list name="l_name_list"> + <column label="名稱" name="unit_name"/> + <column label="ID" name="unit_id_HIDDEN"/> + </scroll_list> <button label="確定" label_selected="確定" name="Select"/> <button label="取消" label_selected="取消" name="Cancel"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml new file mode 100644 index 0000000000..0dcac17a75 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="TexFetchDebugger" title="材質擷取除錯器"> + <text name="total_num_fetched_label"> + 1. 已擷取材質總數:[NUM] + </text> + <text name="total_num_fetching_requests_label"> + 2. 總擷取請求數:[NUM] + </text> + <text name="total_num_cache_hits_label"> + 3. 快取總讀取數:[NUM] + </text> + <text name="total_num_visible_tex_label"> + 4. 可見材質總數:[NUM] + </text> + <text name="total_num_visible_tex_fetch_req_label"> + 5. 可見材質擷取總請求數:[NUM] + </text> + <text name="total_fetched_data_label"> + 6. 總擷取資料量:[SIZE1] KB,解碼資料量:[SIZE2] KB,[PIXEL] 百萬像素 + </text> + <text name="total_fetched_vis_data_label"> + 7. 可見資料總量:[SIZE1] KB,解碼資料量:[SIZE2] KB + </text> + <text name="total_fetched_rendered_data_label"> + 8. 總呈像資料量:[SIZE1] KB,解碼資料量:[SIZE2] KB,[PIXEL] 百萬像素 + </text> + <text name="total_time_cache_read_label"> + 9. 快取讀取總時間:[TIME] 秒 + </text> + <text name="total_time_cache_write_label"> + 10. 快取寫入總時間:[TIME] 秒 + </text> + <text name="total_time_decode_label"> + 11. 解碼總時間:[TIME] 秒 + </text> + <text name="total_time_gl_label"> + 12. 建立 gl 材質總時間:[TIME] 秒 + </text> + <text name="total_time_http_label"> + 13. HTTP 擷取總時間:[TIME] 秒 + </text> + <text name="total_time_fetch_label"> + 14. 所有擷取動作總時間:[TIME] 秒 + </text> + <text name="total_time_refetch_vis_cache_label"> + 15. 自快取重新擷取可見材質,時間:[TIME] 秒,擷取量:[SIZE] KB,[PIXEL] 百萬像素 + </text> + <text name="total_time_refetch_all_cache_label"> + 16. 從快取重新擷取所有材質,時間:[TIME] 秒,擷取量:[SIZE] KB,[PIXEL] 百萬像素 + </text> + <text name="total_time_refetch_vis_http_label"> + 17. 自 HTTP 重新擷取可見材質,時間:[TIME] 秒,擷取量:[SIZE] KB,[PIXEL] 百萬像素 + </text> + <text name="total_time_refetch_all_http_label"> + 18. 自 HTTP 重新擷取所有材質,時間:[TIME] 秒,擷取量:[SIZE] KB,[PIXEL] 百萬像素 + </text> + <spinner label="19. 材質/像素比率:" name="texel_pixel_ratio"/> + <text name="texture_source_label"> + 20. 材質來源: + </text> + <radio_group name="texture_source"> + <radio_item label="快取 + HTTP" name="0"/> + <radio_item label="僅限 HTTP" name="1"/> + </radio_group> + <button label="開始" name="start_btn"/> + <button label="重設" name="clear_btn"/> + <button label="關閉" name="close_btn"/> + <button label="快取讀取" name="cacheread_btn"/> + <button label="快取寫入" name="cachewrite_btn"/> + <button label="HTTP" name="http_btn"/> + <button label="解碼" name="decode_btn"/> + <button label="GL 材質" name="gl_btn"/> + <button label="快取重取可見材質" name="refetchviscache_btn"/> + <button label="重新擷取所有快取" name="refetchallcache_btn"/> + <button label="HTTP 重取可見材質" name="refetchvishttp_btn"/> + <button label="重新擷取所有 HTTP" name="refetchallhttp_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml index 2db98eb3d7..33c9ebeaf0 100644 --- a/indra/newview/skins/default/xui/zh/floater_tools.xml +++ b/indra/newview/skins/default/xui/zh/floater_tools.xml @@ -1,43 +1,49 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="toolbox floater" short_title="建造工具"> + <floater.string name="grid_screen_text"> + 螢幕 + </floater.string> + <floater.string name="grid_local_text"> + 本地 + </floater.string> + <floater.string name="grid_world_text"> + 世界 + </floater.string> + <floater.string name="grid_reference_text"> + 參考 + </floater.string> + <floater.string name="grid_attachment_text"> + 附件 + </floater.string> <floater.string name="status_rotate"> - Drag colored bands to rotate object + 拖曳色條可以旋轉物件 </floater.string> <floater.string name="status_scale"> - Click and drag to stretch selected side + 按住並拖曳,可以拉伸所選的一面 </floater.string> <floater.string name="status_move"> - Drag to move, shift-drag to copy + 拖曳就會移動,按下 Shift 再拖曳則可複製 </floater.string> <floater.string name="status_modifyland"> - Click and hold to modify land + 按住不放開,可以修改土地 </floater.string> <floater.string name="status_camera"> - Click and drag to move camera + 按住並拖曳,可以移動攝影機 </floater.string> <floater.string name="status_grab"> - Drag to move, Ctrl to lift, Ctrl+Shift to rotate + 拖曳就可移動,按下 Ctrl 可以拿起,按下 Ctrl+Shift 可以旋轉 </floater.string> <floater.string name="status_place"> - Click inworld to build + 在虛擬世界裡點按一下,可以建製物件 </floater.string> <floater.string name="status_selectland"> - Click and drag to select land + 按住並拖曳,可以選取土地 </floater.string> - <floater.string name="grid_screen_text"> - Screen + <floater.string name="status_selectcount"> + 選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT] </floater.string> - <floater.string name="grid_local_text"> - Local - </floater.string> - <floater.string name="grid_world_text"> - World - </floater.string> - <floater.string name="grid_reference_text"> - Reference - </floater.string> - <floater.string name="grid_attachment_text"> - Attachment + <floater.string name="status_remaining_capacity"> + 剩餘容納量 [LAND_CAPACITY]。 </floater.string> <button name="button focus" tool_tip="聚焦"/> <button name="button move" tool_tip="移動"/> @@ -45,7 +51,7 @@ <button name="button create" tool_tip="創造"/> <button name="button land" tool_tip="土地"/> <text name="text status"> - Drag to move, shift-drag to copy + 拖曳就會移動,按下 Shift 再拖曳則可複製 </text> <radio_group name="focus_radio_group"> <radio_item label="縮放" name="radio zoom"/> @@ -56,7 +62,7 @@ <radio_group name="move_radio_group"> <radio_item label="移動" name="radio move"/> <radio_item label="舉起(Ctrl)" name="radio lift"/> - <radio_item label="Spin (Ctrl+Shift)" name="radio spin"/> + <radio_item label="旋轉(Ctrl+Shift)" name="radio spin"/> </radio_group> <radio_group name="edit_radio_group"> <radio_item label="移動" name="radio position"/> @@ -67,39 +73,36 @@ <check_box label="編輯聯結部分" name="checkbox edit linked parts"/> <button label="聯結" name="link_btn"/> <button label="取消聯結" name="unlink_btn"/> - <text name="RenderingCost" tool_tip="Shows the rendering cost calculated for this object"> - þ: [COUNT] - </text> <text label="同時伸展兩側" name="checkbox uniform label"> 同時伸展兩側 </text> <check_box initial_value="true" label="伸展材質" name="checkbox stretch textures"/> - <check_box initial_value="true" label="貼齊格線" name="checkbox snap to grid"/> + <check_box initial_value="true" label="Snap" name="checkbox snap to grid"/> <combo_box name="combobox grid mode" tool_tip="選擇物件定位參考的格線尺度類型"> - <combo_box.item label="世界格線" name="World"/> - <combo_box.item label="地方格線" name="Local"/> - <combo_box.item label="參考格線" name="Reference"/> + <combo_box.item label="世界" name="World"/> + <combo_box.item label="本地" name="Local"/> + <combo_box.item label="參考" name="Reference"/> </combo_box> - <button name="Options..." tool_tip="察看更多格線選項"/> - <button name="ToolCube" tool_tip="Cube"/> - <button name="ToolPrism" tool_tip="Prism"/> - <button name="ToolPyramid" tool_tip="Pyramid"/> - <button name="ToolTetrahedron" tool_tip="Tetrahedron"/> - <button name="ToolCylinder" tool_tip="Cylinder"/> - <button name="ToolHemiCylinder" tool_tip="Hemicylinder"/> - <button name="ToolCone" tool_tip="Cone"/> - <button name="ToolHemiCone" tool_tip="Hemicone"/> - <button name="ToolSphere" tool_tip="Sphere"/> - <button name="ToolHemiSphere" tool_tip="Hemisphere"/> - <button name="ToolTorus" tool_tip="Torus"/> - <button name="ToolTube" tool_tip="Tube"/> - <button name="ToolRing" tool_tip="Ring"/> - <button name="ToolTree" tool_tip="Tree"/> - <button name="ToolGrass" tool_tip="Grass"/> + <button label="" name="Options..." tool_tip="察看更多格線選項"/> + <button name="ToolCube" tool_tip="立方體"/> + <button name="ToolPrism" tool_tip="稜鏡體"/> + <button name="ToolPyramid" tool_tip="金字塔"/> + <button name="ToolTetrahedron" tool_tip="正四面體"/> + <button name="ToolCylinder" tool_tip="圓柱體"/> + <button name="ToolHemiCylinder" tool_tip="半圓柱體"/> + <button name="ToolCone" tool_tip="圓錐"/> + <button name="ToolHemiCone" tool_tip="半圓錐"/> + <button name="ToolSphere" tool_tip="球體"/> + <button name="ToolHemiSphere" tool_tip="半球體"/> + <button name="ToolTorus" tool_tip="環面"/> + <button name="ToolTube" tool_tip="圓管"/> + <button name="ToolRing" tool_tip="圓環"/> + <button name="ToolTree" tool_tip="樹木"/> + <button name="ToolGrass" tool_tip="草地"/> <check_box label="保持已選擇的工具" name="checkbox sticky"/> - <check_box label="覆製選擇" name="checkbox copy selection"/> - <check_box initial_value="true" label="Center Copy" name="checkbox copy centers"/> - <check_box label="Rotate Copy" name="checkbox copy rotates"/> + <check_box label="複製選擇" name="checkbox copy selection"/> + <check_box initial_value="true" label="複製物置中" name="checkbox copy centers"/> + <check_box label="旋轉複製物" name="checkbox copy rotates"/> <radio_group name="land_radio_group"> <radio_item label="選擇土地" name="radio select land"/> <radio_item label="攤平" name="radio flatten"/> @@ -121,11 +124,11 @@ </text> <slider_bar initial_value="0.00" name="slider force"/> <button label="套用" label_selected="套用" name="button apply to selection" tool_tip="修改所選擇的土地"/> - <text name="obj_count"> - 物件: [COUNT] + <text name="selection_empty"> + 未做任何選擇。 </text> - <text name="prim_count"> - 幾何元件: [COUNT] + <text name="remaining_capacity"> + [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights 詳情] </text> <tab_container name="Object Info Tabs"> <panel label="一般" name="General"> @@ -147,6 +150,12 @@ <panel.string name="text modify info 4"> 你不能修改這些物件 </panel.string> + <panel.string name="text modify info 5"> + 無法跨地區修改這個物件 + </panel.string> + <panel.string name="text modify info 6"> + 無法跨地區修改這些物件 + </panel.string> <panel.string name="text modify warning"> 你必須選取整個物件以設定權限 </panel.string> @@ -154,16 +163,16 @@ 價格: L$ </panel.string> <panel.string name="Cost Total"> - 總價: L$ + 總價:L$ </panel.string> <panel.string name="Cost Per Unit"> - 單價每個: L$ + 單價:L$ </panel.string> <panel.string name="Cost Mixed"> - Mixed Price + 混合價格 </panel.string> <panel.string name="Sale Mixed"> - Mixed Sale + 混合銷售 </panel.string> <text name="Name:"> 名稱: @@ -175,49 +184,49 @@ 創造者: </text> <text name="Owner:"> - 擁有者: + 所有人: </text> <text name="Group:"> 群組: </text> <name_box initial_value="載入中..." name="Group Name Proxy"/> - <button name="button set group" tool_tip="選擇一個群組以分享這物件權限"/> - <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> - <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/> + <button name="button set group" tool_tip="選擇一個群組以分享這物件的權限"/> + <check_box label="分享" name="checkbox share with group" tool_tip="允許此群組所有成員共享你修改此物件的權限。 你必須讓渡才能啟動角色限制。"/> + <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="「讓渡」會把這物件贈送出去並賦予「下一個所有人」權限。 群組所分享的物件可由群組職員加以讓渡。"/> <text name="label click action"> - 點擊以: + 點按以: </text> <combo_box name="clickaction"> <combo_box.item label="觸碰(預設)" name="Touch/grab(default)"/> <combo_box.item label="坐在物件上" name="Sitonobject"/> <combo_box.item label="購買物件" name="Buyobject"/> <combo_box.item label="支付物件" name="Payobject"/> - <combo_box.item label="開啟" name="Open"/> + <combo_box.item label="打開" name="Open"/> <combo_box.item label="縮放" name="Zoom"/> </combo_box> - <check_box label="出售:" name="checkbox for sale"/> + <check_box label="出售中:" name="checkbox for sale"/> + <spinner label="L$" name="Edit Cost"/> <combo_box name="sale type"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="恚庨" name="Copy"/> <combo_box.item label="內容" name="Contents"/> <combo_box.item label="原件" name="Original"/> </combo_box> - <spinner label="價格: L$" name="Edit Cost"/> - <check_box label="顯示在搜尋中" name="search_check" tool_tip="讓其他人可以在搜尋結果中看到這物件"/> + <check_box label="顯示在搜尋中" name="search_check" tool_tip="讓其他人可以在搜尋結果中察看到此物件"/> <panel name="perms_build"> <text name="perm_modify"> - 你可以修改這個物件 + 你能修改這個物件 </text> <text name="Anyone can:"> 任何人: </text> <check_box label="移動" name="checkbox allow everyone move"/> - <check_box label="覆製" name="checkbox allow everyone copy"/> + <check_box label="恚庨" name="checkbox allow everyone copy"/> <text name="Next owner can:"> - 下一個擁有者: + 下一個所有人: </text> <check_box label="修改" name="checkbox next owner can modify"/> - <check_box label="覆製" name="checkbox next owner can copy"/> - <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個擁有者可以送人或轉售這個物件"/> + <check_box label="恚庨" name="checkbox next owner can copy"/> + <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個所有人可贈送或轉售這個物件"/> <text name="B:"> B: </text> @@ -237,9 +246,14 @@ F: </text> </panel> + <panel name="pathfinding_attrs_panel"> + <text name="pathfinding_attributes_label"> + 尋徑屬性: + </text> + </panel> </panel> <panel label="物件" name="Object"> - <check_box label="鎖定" name="checkbox locked" tool_tip="預防物件被移動或刪除,最常使用的狀況是在建造過程中避免被意外的編輯。"/> + <check_box label="已鎖住" name="checkbox locked" tool_tip="避免物件被移動或刪除。 這在建製過程中非常有用,可避免意外的編輯更動。"/> <check_box label="物理性" name="Physical Checkbox Ctrl" tool_tip="允許物件被推撞與受重力影響"/> <check_box label="暫時性" name="Temporary Checkbox Ctrl" tool_tip="使物件在建造後的一分鐘自動刪除"/> <check_box label="幻影性" name="Phantom Checkbox Ctrl" tool_tip="使物件不會與其他物件或化身產生碰撞"/> @@ -262,26 +276,17 @@ <spinner label="Y" name="Rot Y"/> <spinner label="Z" name="Rot Z"/> <combo_box name="comboBaseType"> - <combo_box.item label="Box" name="Box"/> - <combo_box.item label="Cylinder" name="Cylinder"/> - <combo_box.item label="Prism" name="Prism"/> - <combo_box.item label="Sphere" name="Sphere"/> - <combo_box.item label="Torus" name="Torus"/> - <combo_box.item label="Tube" name="Tube"/> - <combo_box.item label="Ring" name="Ring"/> - <combo_box.item label="Sculpted" name="Sculpted"/> - </combo_box> - <combo_box name="material"> - <combo_box.item label="石頭" name="Stone"/> - <combo_box.item label="金屬" name="Metal"/> - <combo_box.item label="玻璃" name="Glass"/> - <combo_box.item label="木頭" name="Wood"/> - <combo_box.item label="肌肉" name="Flesh"/> - <combo_box.item label="塑膠" name="Plastic"/> - <combo_box.item label="橡膠" name="Rubber"/> + <combo_box.item label="箱子" name="Box"/> + <combo_box.item label="圓柱體" name="Cylinder"/> + <combo_box.item label="稜鏡體" name="Prism"/> + <combo_box.item label="球體" name="Sphere"/> + <combo_box.item label="環面" name="Torus"/> + <combo_box.item label="圓管" name="Tube"/> + <combo_box.item label="圓環" name="Ring"/> + <combo_box.item label="雕刻的" name="Sculpted"/> </combo_box> <text name="text cut"> - Path Cut (begin/end) + 路徑切斷(開始 / 結束) </text> <spinner label="B" name="cut begin"/> <spinner label="E" name="cut end"/> @@ -289,24 +294,24 @@ 中空 </text> <text name="text skew"> - Skew + 偏斜 </text> <text name="Hollow Shape"> 中空形狀 </text> <combo_box name="hole"> <combo_box.item label="預設" name="Default"/> - <combo_box.item label="Circle" name="Circle"/> - <combo_box.item label="Square" name="Square"/> - <combo_box.item label="Triangle" name="Triangle"/> + <combo_box.item label="圓圈" name="Circle"/> + <combo_box.item label="方形" name="Square"/> + <combo_box.item label="三角形" name="Triangle"/> </combo_box> <text name="text twist"> - Twist (begin/end) + 扭曲(開始 / 結束) </text> <spinner label="B" name="Twist Begin"/> <spinner label="E" name="Twist End"/> <text name="scale_taper"> - Taper + 錐化 </text> <text name="scale_hole"> 洞尺寸 @@ -314,54 +319,62 @@ <spinner label="X" name="Taper Scale X"/> <spinner label="Y" name="Taper Scale Y"/> <text name="text topshear"> - Top Shear + 頂部斜變 </text> <spinner label="X" name="Shear X"/> <spinner label="Y" name="Shear Y"/> <text name="advanced_cut"> - Profile Cut (begin/end) + 側面切斷(開始 / 結束) </text> <text name="advanced_dimple"> - Dimple (begin/end) + 凹陷(開始 / 結束) </text> <text name="advanced_slice"> - Slice (begin/end) + Slice(開始 / 結束) </text> <spinner label="B" name="Path Limit Begin"/> <spinner label="E" name="Path Limit End"/> <text name="text taper2"> - Taper + 錐化 </text> <spinner label="X" name="Taper X"/> <spinner label="Y" name="Taper Y"/> <text name="text radius delta"> - Radius + 半徑 </text> <text name="text revolutions"> - Revolutions + 旋轉 </text> - <texture_picker label="Sculpt Texture" name="sculpt texture control" tool_tip="點擊以挑選圖像"/> - <check_box label="Mirror" name="sculpt mirror control" tool_tip="Flips sculpted prim along the X axis"/> - <check_box label="Inside-out" name="sculpt invert control" tool_tip="Inverts the sculpted prims normals, making it appear inside-out"/> + <texture_picker label="雕刻材質" name="sculpt texture control" tool_tip="點按以挑選圖片"/> + <check_box label="鏡像" name="sculpt mirror control" tool_tip="沿X軸翻轉雕刻幾何元件"/> + <check_box label="內外倒翻" name="sculpt invert control" tool_tip="將雕刻幾何元件的正常值顛倒,使其看來有如內外倒翻"/> <text name="label sculpt type"> - Stitching type + 縫合類型 </text> <combo_box name="sculpt type control"> - <combo_box.item label="(無)" name="None"/> - <combo_box.item label="Sphere" name="Sphere"/> - <combo_box.item label="Torus" name="Torus"/> - <combo_box.item label="Plane" name="Plane"/> - <combo_box.item label="Cylinder" name="Cylinder"/> + <combo_box.item label="球體" name="Sphere"/> + <combo_box.item label="環面" name="Torus"/> + <combo_box.item label="平面" name="Plane"/> + <combo_box.item label="圓柱體" name="Cylinder"/> </combo_box> </panel> <panel label="特性" name="Features"> + <panel.string name="None"> + 無 + </panel.string> + <panel.string name="Prim"> + 幾何元件 + </panel.string> + <panel.string name="Convex Hull"> + 凸包 + </panel.string> <text name="select_single"> 只能選擇一個幾何元件去編輯細節。 </text> <text name="edit_object"> 編輯物件特性: </text> - <check_box label="彈性路徑" name="Flexible1D Checkbox Ctrl" tool_tip="Allows object to flex about the Z axis (Client-side only)"/> + <check_box label="彈性路徑" name="Flexible1D Checkbox Ctrl" tool_tip="允許物件繞 Z 軸伸展(僅限客戶端)"/> <spinner label="柔軟" name="FlexNumSections"/> <spinner label="重力" name="FlexGravity"/> <spinner label="拖曳" name="FlexFriction"/> @@ -371,14 +384,31 @@ <spinner label="強制 Y 軸" name="FlexForceY"/> <spinner label="強制 Z 軸" name="FlexForceZ"/> <check_box label="光源" name="Light Checkbox Ctrl" tool_tip="導致物件發光"/> - <color_swatch name="colorswatch" tool_tip="點擊以開啟顏色挑選器"/> - <texture_picker label="" name="light texture control" tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)"/> + <color_swatch name="colorswatch" tool_tip="點按以開啟顏色挑選器"/> + <texture_picker label="" name="light texture control" tool_tip="點選投影圖像(只在啟用延遲呈像時生效)"/> <spinner label="強度" name="Light Intensity"/> - <spinner label="FOV" name="Light FOV"/> + <spinner label="視角" name="Light FOV"/> <spinner label="半徑" name="Light Radius"/> - <spinner label="Focus" name="Light Focus"/> + <spinner label="焦點" name="Light Focus"/> <spinner label="衰減" name="Light Falloff"/> - <spinner label="Ambiance" name="Light Ambiance"/> + <spinner label="環境" name="Light Ambiance"/> + <text name="label physicsshapetype"> + 物理形狀類型: + </text> + <combo_box name="Physics Shape Type Combo Ctrl" tool_tip="選擇物理形狀類型"/> + <combo_box name="material"> + <combo_box.item label="石頭" name="Stone"/> + <combo_box.item label="金屬" name="Metal"/> + <combo_box.item label="玻璃" name="Glass"/> + <combo_box.item label="木頭" name="Wood"/> + <combo_box.item label="肌肉" name="Flesh"/> + <combo_box.item label="塑膠" name="Plastic"/> + <combo_box.item label="橡膠" name="Rubber"/> + </combo_box> + <spinner label="重力" name="Physics Gravity"/> + <spinner label="摩擦" name="Physics Friction"/> + <spinner label="密度(100 公斤 / 立方公尺)" name="Physics Density"/> + <spinner label="恢復" name="Physics Restitution"/> </panel> <panel label="材質" name="Texture"> <panel.string name="string repeats per meter"> @@ -387,8 +417,8 @@ <panel.string name="string repeats per face"> 每一面重覆次數 </panel.string> - <texture_picker label="材質" name="texture control" tool_tip="點擊以挑選圖像"/> - <color_swatch label="顏色" name="colorswatch" tool_tip="點擊以開啟顏色挑選器"/> + <texture_picker label="材質" name="texture control" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色" name="colorswatch" tool_tip="點按以開啟顏色挑選器"/> <text name="color trans"> 透明度 % </text> @@ -417,25 +447,25 @@ </text> <combo_box name="combobox bumpiness"> <combo_box.item label="無" name="None"/> - <combo_box.item label="Brightness" name="Brightness"/> - <combo_box.item label="Darkness" name="Darkness"/> - <combo_box.item label="woodgrain" name="woodgrain"/> - <combo_box.item label="bark" name="bark"/> - <combo_box.item label="bricks" name="bricks"/> - <combo_box.item label="checker" name="checker"/> - <combo_box.item label="concrete" name="concrete"/> - <combo_box.item label="crustytile" name="crustytile"/> - <combo_box.item label="cutstone" name="cutstone"/> - <combo_box.item label="discs" name="discs"/> - <combo_box.item label="gravel" name="gravel"/> - <combo_box.item label="petridish" name="petridish"/> - <combo_box.item label="siding" name="siding"/> - <combo_box.item label="stonetile" name="stonetile"/> - <combo_box.item label="stucco" name="stucco"/> - <combo_box.item label="suction" name="suction"/> - <combo_box.item label="weave" name="weave"/> + <combo_box.item label="亮度" name="Brightness"/> + <combo_box.item label="暗度" name="Darkness"/> + <combo_box.item label="木紋" name="woodgrain"/> + <combo_box.item label="樹皮" name="bark"/> + <combo_box.item label="磚" name="bricks"/> + <combo_box.item label="格子" name="checker"/> + <combo_box.item label="混凝土" name="concrete"/> + <combo_box.item label="粗花磚" name="crustytile"/> + <combo_box.item label="石磚" name="cutstone"/> + <combo_box.item label="圓盤" name="discs"/> + <combo_box.item label="碎石" name="gravel"/> + <combo_box.item label="培養皿" name="petridish"/> + <combo_box.item label="側邊片" name="siding"/> + <combo_box.item label="石磚格" name="stonetile"/> + <combo_box.item label="彩色沙岩" name="stucco"/> + <combo_box.item label="吸附" name="suction"/> + <combo_box.item label="編織" name="weave"/> </combo_box> - <check_box initial_value="false" label="對齊平面" name="checkbox planar align" tool_tip="以最後所選擇的面為基準,對齊全部所選擇的面上的材質。這必須使用平面材質映射方式。"/> + <check_box initial_value="false" label="對齊平面" name="checkbox planar align" tool_tip="以最後所選擇的面為基準,對齊全部所選擇的面上的材質。 這必須使用平面材質映射方式。"/> <text name="rpt"> 重覆次數 / 面 </text> @@ -476,15 +506,8 @@ <text name="label_area"> 面積: [AREA] m² </text> - <button label="關於土地" label_selected="關於土地" name="button about land"/> - <check_box label="顯示擁有者" name="checkbox show owners" tool_tip="Colorize the parcels according to the type of owner: - -綠色 = 你的土地 -水藍 = 你群組的土地 -紅色 = 其他人所有 -黃色 = 出售 -紫色 = 拍賣 -灰色 = 公有地"/> + <button label="土地資料" label_selected="土地資料" name="button about land"/> + <check_box label="顯示所有人" name="checkbox show owners" tool_tip="根據所有人將地段分類上色: 綠色 = 你的土地 水藍 = 你群組的土地 紅色 = 其他人所有 黃色 = 出售 紫色 = 拍賣 灰色 = 公有地"/> <text name="label_parcel_modify"> 修改地段 </text> diff --git a/indra/newview/skins/default/xui/zh/floater_top_objects.xml b/indra/newview/skins/default/xui/zh/floater_top_objects.xml index 0e7e0c5b1a..6f50be0855 100644 --- a/indra/newview/skins/default/xui/zh/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/zh/floater_top_objects.xml @@ -1,28 +1,25 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="top_objects" title="Top Objects"> +<floater name="top_objects" title="排行最高的物件"> <floater.string name="top_scripts_title"> - Top Scripts + 排行最高的腳本 </floater.string> <floater.string name="top_scripts_text"> - [COUNT] scripts taking a total of [TIME] ms + [COUNT] 個腳本共需時 [TIME] 毫秒 </floater.string> <floater.string name="scripts_score_label"> - Time - </floater.string> - <floater.string name="scripts_mono_time_label"> - Mono Time + 時間 </floater.string> <floater.string name="top_colliders_title"> - Top Colliders + 最常碰撞物項 </floater.string> <floater.string name="top_colliders_text"> - Top [COUNT] objects experiencing many potential collisions + 排行最高的 [COUNT] 個物件可能發生多次碰撞 </floater.string> <floater.string name="colliders_score_label"> 積分 </floater.string> <floater.string name="none_descriptor"> - 未發現。 + 查無結果。 </floater.string> <text name="title_text"> 載入中... @@ -30,11 +27,12 @@ <scroll_list name="objects_list"> <scroll_list.columns label="積分" name="score"/> <scroll_list.columns label="名稱" name="name"/> - <scroll_list.columns label="擁有者" name="owner"/> + <scroll_list.columns label="所有人" name="owner"/> <scroll_list.columns label="位置" name="location"/> - <scroll_list.columns label="Time" name="time"/> - <scroll_list.columns label="Mono Time" name="mono_time"/> - <scroll_list.columns label="URLs" name="URLs"/> + <scroll_list.columns label="地段" name="parcel"/> + <scroll_list.columns label="時間" name="time"/> + <scroll_list.columns label="URL" name="URLs"/> + <scroll_list.columns label="記憶體 (KB)" name="memory"/> </scroll_list> <text name="id_text"> 物件 ID: @@ -45,11 +43,15 @@ </text> <button label="過濾器" name="filter_object_btn"/> <text name="owner_name_text"> - 擁有者: + 所有人: </text> <button label="過濾器" name="filter_owner_btn"/> + <text name="parcel_name_text"> + 地段: + </text> + <button label="過濾器" name="filter_parcel_btn"/> <button label="退回所選擇的" name="return_selected_btn"/> <button label="全部退回" name="return_all_btn"/> - <button label="關閉所選擇的" name="disable_selected_btn"/> - <button label="全部關閉" name="disable_all_btn"/> + <button label="停用所選的" name="disable_selected_btn"/> + <button label="全部停用" name="disable_all_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml index 5f9e16afe1..3da9445a55 100644 --- a/indra/newview/skins/default/xui/zh/floater_tos.xml +++ b/indra/newview/skins/default/xui/zh/floater_tos.xml @@ -4,12 +4,12 @@ http://secondlife.com/app/tos/ </floater.string> <floater.string name="loading_url"> - data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E Loading %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E + data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E 正在載入 %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E </floater.string> <button label="繼續" label_selected="繼續" name="Continue"/> <button label="取消" label_selected="取消" name="Cancel"/> <check_box label="我同意接受服務條款及隱私政策" name="agree_chk"/> <text name="tos_heading"> - 請謹慎閱讀以下的服務條款及隱私政策。要繼續登入到 [SECOND_LIFE],你必須接受這些協議。 + 請仔細閱讀以下服務條款及隱私政策。 繼續登入 [SECOND_LIFE] 前,你必須同意條款。 </text> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_toybox.xml b/indra/newview/skins/default/xui/zh/floater_toybox.xml new file mode 100644 index 0000000000..fc6b6ea611 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_toybox.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Toybox" title="工具列按鈕"> + <text name="toybox label 1"> + 將按鈕拖入或拖離工具列,即可新增或移除該按鈕。 + </text> + <text name="toybox label 2"> + 按鈕將根據每一個工具列的設定,僅顯示圖示或一併顯示文字標籤。 + </text> + <button label="清除所有工具列" label_selected="清除所有工具列" name="btn_clear_all"/> + <button label="還原預設值" label_selected="還原預設值" name="btn_restore_defaults"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_translation_settings.xml b/indra/newview/skins/default/xui/zh/floater_translation_settings.xml new file mode 100644 index 0000000000..fe84872557 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_translation_settings.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_translation_settings" title="聊天內容翻譯設定"> + <string name="bing_api_key_not_verified"> + Bing AppID 未通過驗證。 請再試一次。 + </string> + <string name="google_api_key_not_verified"> + Google API 鍵值未通過驗證。 請再試一次。 + </string> + <string name="bing_api_key_verified"> + Bing AppID 驗證成功。 + </string> + <string name="google_api_key_verified"> + Google API 鍵值驗證成功。 + </string> + <check_box label="聊天時啟用機器翻譯" name="translate_chat_checkbox"/> + <text name="translate_language_label"> + 將聊天內容翻譯成: + </text> + <combo_box name="translate_language_combo"> + <combo_box.item label="系統預設" name="System Default Language"/> + <combo_box.item label="英語" name="English"/> + <combo_box.item label="Dansk(丹麥語)" name="Danish"/> + <combo_box.item label="Deutsch(德語)" name="German"/> + <combo_box.item label="Español(西班牙語)" name="Spanish"/> + <combo_box.item label="Français(法語)" name="French"/> + <combo_box.item label="Italiano(義大利語)" name="Italian"/> + <combo_box.item label="Magyar(匈牙利語)" name="Hungarian"/> + <combo_box.item label="Nederlands(荷蘭語)" name="Dutch"/> + <combo_box.item label="Polski(波蘭語)" name="Polish"/> + <combo_box.item label="Português(葡萄牙語)" name="Portugese"/> + <combo_box.item label="Русский(俄羅斯語)" name="Russian"/> + <combo_box.item label="Türkçe(土耳其語)" name="Turkish"/> + <combo_box.item label="Українська(烏克蘭語)" name="Ukrainian"/> + <combo_box.item label="中文(正體)" name="Chinese"/> + <combo_box.item label="日本語(日語)" name="Japanese"/> + <combo_box.item label="한국어(漢語)" name="Korean"/> + </combo_box> + <text name="tip"> + 選擇翻譯服務: + </text> + <radio_group name="translation_service_rg"> + <radio_item initial_value="bing" label="Bing 翻譯器" name="bing"/> + <radio_item initial_value="google" label="Google 翻譯" name="google"/> + </radio_group> + <text name="bing_api_key_label"> + Bing [http://www.bing.com/developers/createapp.aspx AppID]: + </text> + <button label="驗證" name="verify_bing_api_key_btn"/> + <text name="google_api_key_label"> + Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API 鍵值]: + </text> + <button label="驗證" name="verify_google_api_key_btn"/> + <text name="google_links_text"> + [http://code.google.com/apis/language/translate/v2/pricing.html 價格表] | [https://code.google.com/apis/console 統計] + </text> + <button label="確定" name="ok_btn"/> + <button label="取消" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_voice_controls.xml b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml index 24b7efea4f..a3a7679957 100644 --- a/indra/newview/skins/default/xui/zh/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="floater_voice_controls" title="語音控制"> <string name="title_nearby"> - 附近的語音 + 語音設定 </string> <string name="title_group"> 與 [GROUP] 進行群組通話 </string> <string name="title_adhoc"> - 會議通話 + 多方通話 </string> <string name="title_peer_2_peer"> - 與 [NAME] 進行通話 + 和 [NAME] 通話 </string> <string name="no_one_near"> 附近沒有一人開啟語音 @@ -22,7 +22,7 @@ <layout_panel name="leave_call_panel"> <layout_stack name="voice_effect_and_leave_call_stack"> <layout_panel name="leave_call_btn_panel"> - <button label="結束通話" name="leave_call_btn"/> + <button label="離開通話" name="leave_call_btn"/> </layout_panel> </layout_stack> </layout_panel> diff --git a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml index 36efe20b65..81e0204262 100644 --- a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml @@ -1,29 +1,158 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater label="地點" name="voice_effects" title="語音變聲"> <string name="no_voice_effect"> - (No Voice Morph) + (無變聲效果) </string> <string name="active_voice_effect"> - (Active) + (使用中) </string> <string name="unsubscribed_voice_effect"> - (Unsubscribed) + (已停止訂用) </string> <string name="new_voice_effect"> - (New!) + (新的!) + </string> + <string name="effect_Arena"> + 競技場 + </string> + <string name="effect_Beast"> + 野獸 + </string> + <string name="effect_Buff"> + Buff + </string> + <string name="effect_Buzz"> + Buzz + </string> + <string name="effect_Camille"> + 卡蜜兒 + </string> + <string name="effect_Creepy"> + 怪異 + </string> + <string name="effect_CreepyBot"> + 怪異機器人 + </string> + <string name="effect_Cyber"> + 科幻 + </string> + <string name="effect_DeepBot"> + 深沉機器人 + </string> + <string name="effect_Demon"> + 魔鬼 + </string> + <string name="effect_Female Elf"> + 女性 - 小精靈 + </string> + <string name="effect_Flirty"> + 調情 + </string> + <string name="effect_Foxy"> + 香豔 + </string> + <string name="effect_Halloween 2010 Bonus"> + 2010萬聖節加贈 + </string> + <string name="effect_Helium"> + 氦氣 + </string> + <string name="effect_Husky"> + 沙啞 + </string> + <string name="effect_Husky Whisper"> + 沙啞耳語 + </string> + <string name="effect_Intercom"> + 對講機 + </string> + <string name="effect_Julia"> + 茱莉亞 + </string> + <string name="effect_Lo Lilt"> + 輕微抑揚頓挫 + </string> + <string name="effect_Macho"> + 陽剛 + </string> + <string name="effect_Micro"> + Micro + </string> + <string name="effect_Mini"> + 迷你 + </string> + <string name="effect_Model"> + 模型 + </string> + <string name="effect_Nano"> + Nano + </string> + <string name="effect_Nightmare"> + 惡夢 + </string> + <string name="effect_PopBot"> + PopBot + </string> + <string name="effect_Rachel"> + 瑞秋 + </string> + <string name="effect_Radio"> + 收音機 + </string> + <string name="effect_Robot"> + 機器人 + </string> + <string name="effect_Roxanne"> + 蘿姍 + </string> + <string name="effect_Rumble"> + 低沉隆隆聲 + </string> + <string name="effect_Sabrina"> + 薩賓娜 + </string> + <string name="effect_Samantha"> + 姍曼莎 + </string> + <string name="effect_Sexy"> + 性感 + </string> + <string name="effect_Shorty"> + 矮個兒 + </string> + <string name="effect_Smaller"> + 較小 + </string> + <string name="effect_Sneaky"> + 鬼祟 + </string> + <string name="effect_Stallion"> + 種馬 + </string> + <string name="effect_Sultry"> + 勾魂 + </string> + <string name="effect_Thunder"> + 雷聲 + </string> + <string name="effect_Vixen"> + 潑婦 + </string> + <string name="effect_WhinyBot"> + 哭鬧機器人 </string> <text name="preview_text"> - To Preview + 預覽 </text> <text name="status_text"> - Record a sample, then click on a voice to hear how it will sound. + 錄下一段樣本,再點按聲音檢查結果。 </text> - <button label="Record" name="record_btn" tool_tip="Record a sample of your voice."/> + <button label="錄音" name="record_btn" tool_tip="錄下一段你的聲音。"/> <button label="停止" name="record_stop_btn"/> <text name="voice_morphing_link"> - [[URL] Subscribe Now] + [[URL] 現在訂用] </text> - <scroll_list name="voice_effect_list" tool_tip="Record a sample of your voice, then click an effect to preview."> + <scroll_list name="voice_effect_list" tool_tip="錄下一段你的聲音,再點選一個效果試聽。"> <scroll_list.columns label="語音名稱" name="name"/> <scroll_list.columns label="過期" name="expires"/> </scroll_list> diff --git a/indra/newview/skins/default/xui/zh/floater_water.xml b/indra/newview/skins/default/xui/zh/floater_water.xml deleted file mode 100644 index 5fb57272af..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_water.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Water Floater" title="進階水文編輯器"> - <floater.string name="WLDefaultWaterNames"> - Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez - </floater.string> - <text name="KeyFramePresetsText"> - Water Presets: - </text> - <button label="新增" label_selected="新增" name="WaterNewPreset"/> - <button label="儲存" label_selected="儲存" name="WaterSavePreset"/> - <button label="刪除" label_selected="刪除" name="WaterDeletePreset"/> - <tab_container name="Water Tabs"> - <panel label="設定" name="Settings"> - <text name="BHText"> - Water Fog Color - </text> - <color_swatch name="WaterFogColor" tool_tip="點擊以開啟顏色挑選器"/> - <text name="WaterFogDensText"> - Fog Density Exponent - </text> - <text name="WaterUnderWaterFogModText"> - Underwater Fog Modifier - </text> - <text name="BDensText"> - Reflection Wavelet Scale - </text> - <slider label="1" name="WaterNormalScaleX"/> - <slider label="2" name="WaterNormalScaleY"/> - <slider label="3" name="WaterNormalScaleZ"/> - <text name="HDText"> - Fresnel Scale - </text> - <text name="FresnelOffsetText"> - Fresnel Offset - </text> - <text name="DensMultText"> - Refract Scale Above - </text> - <text name="WaterScaleBelowText"> - Refract Scale Below - </text> - <text name="MaxAltText"> - Blur Multiplier - </text> - </panel> - <panel label="圖像" name="Waves"> - <text name="BHText"> - Big Wave Direction - </text> - <text name="WaterWave1DirXText"> - X - </text> - <text name="WaterWave1DirYText"> - Y - </text> - <text name="BHText2"> - Little Wave Direction - </text> - <text name="WaterWave2DirXText"> - X - </text> - <text name="WaterWave2DirYText"> - Y - </text> - <text name="BHText3"> - 正常地圖 - </text> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_windlight_options.xml b/indra/newview/skins/default/xui/zh/floater_windlight_options.xml deleted file mode 100644 index 383e35d50d..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_windlight_options.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="WindLight floater" title="進階天空編輯器"> - <floater.string name="WLDefaultSkyNames"> - A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality - </floater.string> - <text name="KeyFramePresetsText"> - 天空預設值: - </text> - <button label="新增" label_selected="新增" name="WLNewPreset"/> - <button label="儲存" label_selected="儲存" name="WLSavePreset"/> - <button label="刪除" label_selected="刪除" name="WLDeletePreset"/> - <button label="日循環編輯器" label_selected="日循環編輯器" name="WLDayCycleMenuButton"/> - <tab_container name="WindLight Tabs"> - <panel label="大氣" name="Atmosphere"> - <text name="BHText"> - 藍天水平線 - </text> - <text name="BHText2"> - R - </text> - <text name="BHText3"> - G - </text> - <text name="BHText4"> - B - </text> - <text name="BHText5"> - I - </text> - <text name="BDensText"> - 陰霾水平線 - </text> - <text name="BDensText2"> - 藍天密度 - </text> - <text name="BHText6"> - R - </text> - <text name="BHText7"> - G - </text> - <text name="BHText8"> - B - </text> - <text name="BHText9"> - I - </text> - <text name="HDText"> - 陰霾密度 - </text> - <text name="DensMultText"> - 密度倍增 - </text> - <text name="WLDistanceMultText"> - 距離倍增 - </text> - <text name="MaxAltText"> - 最大高度 - </text> - </panel> - <panel label="照明" name="Lighting"> - <text name="SLCText"> - 日/月 顏色 - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="TODText"> - 日/月 位置 - </text> - <text name="WLAmbientText"> - 環境 - </text> - <text name="BHText5"> - R - </text> - <text name="BHText6"> - G - </text> - <text name="BHText7"> - B - </text> - <text name="BHText8"> - I - </text> - <text name="WLEastAngleText"> - 東升角度 - </text> - <text name="SunGlowText"> - 太陽光輝 - </text> - <slider label="焦點" name="WLGlowB"/> - <slider label="尺寸" name="WLGlowR"/> - <text name="SceneGammaText"> - 場景 Gamma 值 - </text> - <text name="WLStarText"> - 星空量度 - </text> - </panel> - <panel label="雲彩" name="Clouds"> - <text name="WLCloudColorText"> - 雲彩顏色 - </text> - <text name="BHText"> - R - </text> - <text name="BHText2"> - G - </text> - <text name="BHText3"> - B - </text> - <text name="BHText4"> - I - </text> - <text name="WLCloudColorText2"> - 雲彩 XY 軸 / 密度 - </text> - <text name="BHText5"> - X - </text> - <text name="BHText6"> - Y - </text> - <text name="BHText7"> - D - </text> - <text name="WLCloudCoverageText"> - 雲彩覆蓋 - </text> - <text name="WLCloudScaleText"> - 雲彩規模 - </text> - <text name="WLCloudDetailText"> - 雲彩細節(XY 軸 / 密度) - </text> - <text name="BHText8"> - X - </text> - <text name="BHText9"> - Y - </text> - <text name="BHText10"> - D - </text> - <text name="WLCloudScrollXText"> - 雲彩 X 滾軸 - </text> - <check_box label="鎖定" name="WLCloudLockX"/> - <text name="WLCloudScrollYText"> - 雲彩 Y 滾軸 - </text> - <check_box label="鎖定" name="WLCloudLockY"/> - <check_box label="描繪傳統雲彩" name="DrawClassicClouds"/> - </panel> - </tab_container> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_window_size.xml b/indra/newview/skins/default/xui/zh/floater_window_size.xml index 54b72afccc..3942f72d76 100644 --- a/indra/newview/skins/default/xui/zh/floater_window_size.xml +++ b/indra/newview/skins/default/xui/zh/floater_window_size.xml @@ -7,10 +7,17 @@ 設定視窗尺寸大小: </text> <combo_box name="window_size_combo" tool_tip="寬度 x 高度"> - <combo_box.item label="1000 x 700 (預設)" name="item0"/> - <combo_box.item label="1024 x 768" name="item1"/> - <combo_box.item label="1280 x 720 (720p)" name="item2"/> - <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + <combo_box.item label="1000 x 700 (預設)" name="item1"/> + <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/> + <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/> + <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/> + <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/> + <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/> + <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/> + <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/> + <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/> + <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/> + <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/> </combo_box> <button label="設定" name="set_btn"/> <button label="取消" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/zh/floater_world_map.xml b/indra/newview/skins/default/xui/zh/floater_world_map.xml index 6ac6fb76b7..4cd05ebaa0 100644 --- a/indra/newview/skins/default/xui/zh/floater_world_map.xml +++ b/indra/newview/skins/default/xui/zh/floater_world_map.xml @@ -8,7 +8,7 @@ <panel name="layout_panel_2"> <button name="Show My Location" tool_tip="以我的化身所在位置居中地圖"/> <text name="me_label"> - 自己 + 我自己 </text> <text name="person_label"> 人 @@ -23,14 +23,14 @@ 土地拍賣 </text> <text name="by_owner_label"> - 依擁有者 + 依所有人 </text> - <button name="Go Home" tool_tip="瞬間傳送到我的家位置"/> + <button name="Go Home" tool_tip="瞬間返回我的家"/> <text name="Home_label"> - 家 + 我的家 </text> <text name="events_label"> - 事件: + 活動: </text> <text name="pg_label"> 一般普級 @@ -57,17 +57,17 @@ </combo_box> <search_editor label="地區依名稱" name="location" tool_tip="輸入一個地區的名稱"/> <button label="尋找" name="DoSearch" tool_tip="搜尋地區"/> - <button name="Clear" tool_tip="Clear tracking lines and reset map"/> + <button name="Clear" tool_tip="清楚追蹤線並重設地圖"/> <text name="events_label"> 位置: </text> <button label="瞬間傳送" name="Teleport" tool_tip="瞬間傳送到所選的位置"/> - <button label="覆製 SLurl" name="copy_slurl" tool_tip="Copies current location as SLurl to be used on the web."/> - <button label="Show Selection" name="Show Destination" tool_tip="Center map on selected location"/> + <button label="覆製 SLurl" name="copy_slurl" tool_tip="將目前位置複製為可在網路上使用的 SLurl。"/> + <button label="顯示選擇" name="Show Destination" tool_tip="將所選位置移到地圖中央"/> </panel> <panel name="layout_panel_5"> <text name="zoom_label"> - Zoom + 縮放 </text> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_avatar.xml b/indra/newview/skins/default/xui/zh/inspect_avatar.xml index 02e81983a6..ef10e5d2d0 100644 --- a/indra/newview/skins/default/xui/zh/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/zh/inspect_avatar.xml @@ -10,16 +10,16 @@ <string name="Details"> [SL_PROFILE] </string> - <text name="user_subtitle" value="11 Months, 3 days old"/> + <text name="user_subtitle" value="年齡 11 個月又 3 天"/> <text name="user_details"> - This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot + 這是我的「第二人生」資訊。這地方太棒了! 只不過,可是嘛……我的訊息相當相當的冗長,因為……我滿愛七嘴八舌的啦。 </text> - <slider name="volume_slider" tool_tip="Voice volume" value="0.5"/> + <slider name="volume_slider" tool_tip="音量" value="0.5"/> <button label="加為朋友" name="add_friend_btn"/> <button label="IM" name="im_btn"/> <button label="檔案" name="view_profile_btn"/> <panel name="moderator_panel"> - <button label="Disable Voice" name="disable_voice"/> - <button label="Enable Voice" name="enable_voice"/> + <button label="停用語音" name="disable_voice"/> + <button label="啟用語音" name="enable_voice"/> </panel> </floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_group.xml b/indra/newview/skins/default/xui/zh/inspect_group.xml index ac331be203..ca5ccc3349 100644 --- a/indra/newview/skins/default/xui/zh/inspect_group.xml +++ b/indra/newview/skins/default/xui/zh/inspect_group.xml @@ -17,14 +17,14 @@ 你是成員 </string> <text name="group_subtitle"> - 123 members + 123 位成員 </text> <text name="group_details"> - A group of folks charged with creating a room with a moose. -Fear the moose! Fear it! And the mongoose too! + 這一群人責在建立有麋鹿的房間。 +麋鹿萬歲!貓鼬萬歲! </text> <text name="group_cost"> - L$123 to join + 加入費用 L$123 </text> <button label="加入" name="join_btn"/> <button label="退出" name="leave_btn"/> diff --git a/indra/newview/skins/default/xui/zh/inspect_object.xml b/indra/newview/skins/default/xui/zh/inspect_object.xml index 58091b3aef..377b8b7c78 100644 --- a/indra/newview/skins/default/xui/zh/inspect_object.xml +++ b/indra/newview/skins/default/xui/zh/inspect_object.xml @@ -5,40 +5,40 @@ --> <floater name="inspect_object"> <string name="Creator"> - By [CREATOR] + 創作人 [CREATOR] </string> <string name="CreatorAndOwner"> - By [CREATOR] -Owner [OWNER] + 創作人 [CREATOR] +所有人 [OWNER] </string> <string name="Price"> L$[AMOUNT] </string> <string name="PriceFree"> - Free! + 免費! </string> <string name="Touch"> - Touch + 觸碰 </string> <string name="Sit"> - Sit + 坐下 </string> <text name="object_creator"> - by secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about -owner secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about + 創作人 secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about +所有人 secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about </text> <text name="price_text"> L$30,000 </text> - <icon name="secure_browsing" tool_tip="Secure Browsing"/> + <icon name="secure_browsing" tool_tip="安全瀏覽"/> <text name="object_media_url"> http://www.superdupertest.com </text> <button label="購買" name="buy_btn"/> <button label="支付" name="pay_btn"/> <button label="取得副本" name="take_free_copy_btn"/> - <button label="Touch" name="touch_btn"/> - <button label="Sit" name="sit_btn"/> - <button label="Open" name="open_btn"/> - <button label="More" name="more_info_btn"/> + <button label="觸碰" name="touch_btn"/> + <button label="坐下" name="sit_btn"/> + <button label="打開" name="open_btn"/> + <button label="更多" name="more_info_btn"/> </floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_remote_object.xml b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml index bed19d6d78..b8418fc8a1 100644 --- a/indra/newview/skins/default/xui/zh/inspect_remote_object.xml +++ b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml @@ -5,10 +5,10 @@ --> <floater name="inspect_remote_object"> <text name="object_name"> - Test Object Name That Is Really Long OMG so long I can't believe how long the name of this object is, I mean really. + 測試很長很長、長到不可思議的、落落長的、長得不得了的、很長很長很長、長到我快發瘋、長之又長的物件名稱。 </text> <text name="object_owner_label"> - 擁有者: + 所有人: </text> <text name="object_owner"> Longavatarname Johnsonlongstonnammer diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml index 1911a1aeff..c14a98c64b 100644 --- a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Attachment Pie"> - <menu_item_call label="Touch" name="Attachment Object Touch"/> + <menu_item_call label="觸碰" name="Attachment Object Touch"/> <menu_item_call label="編輯" name="Edit..."/> <menu_item_call label="卸下" name="Detach"/> <menu_item_call label="坐下" name="Sit Down Here"/> @@ -10,7 +10,7 @@ <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="我的朋友" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> - <menu_item_call label="我的檔案" name="Profile..."/> + <menu_item_call label="我的個人檔案" name="Profile..."/> <menu_item_call label="材質除錯" name="Debug..."/> <menu_item_call label="丟棄" name="Drop"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml index 260571eb54..1d02464748 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml @@ -6,11 +6,11 @@ <menu_item_call label="IM" name="Send IM..."/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="邀請加入群組" name="Invite..."/> - <menu_item_call label="Block" name="Avatar Mute"/> + <menu_item_call label="封鎖" name="Avatar Mute"/> <menu_item_call label="回報" name="abuse"/> <menu_item_call label="凍結" name="Freeze..."/> <menu_item_call label="踢出" name="Eject..."/> <menu_item_call label="材質除錯" name="Debug..."/> - <menu_item_call label="Zoom In" name="Zoom In"/> + <menu_item_call label="放大" name="Zoom In"/> <menu_item_call label="支付" name="Pay..."/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml index d516e3ab58..32757bbff6 100644 --- a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml @@ -14,19 +14,19 @@ <menu_item_call label="內衣" name="Self Undershirt"/> <menu_item_call label="內褲" name="Self Underpants"/> <menu_item_call label="刺青" name="Self Tattoo"/> - <menu_item_call label="Physics" name="Self Physics"/> + <menu_item_call label="身體物理" name="Self Physics"/> <menu_item_call label="半透明" name="Self Alpha"/> <menu_item_call label="全部衣服" name="All Clothes"/> </context_menu> - <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="擡頭顯示" name="Object Detach HUD"/> <context_menu label="卸下" name="Object Detach"/> <menu_item_call label="全部卸下" name="Detach All"/> </context_menu> <menu_item_call label="我的外觀" name="Chenge Outfit"/> - <menu_item_call label="編輯我裝扮" name="Edit Outfit"/> + <menu_item_call label="編輯我的裝扮" name="Edit Outfit"/> <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="我的朋友" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> - <menu_item_call label="我的檔案" name="Profile..."/> + <menu_item_call label="我的個人檔案" name="Profile..."/> <menu_item_call label="材質除錯" name="Debug..."/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_bottomtray.xml b/indra/newview/skins/default/xui/zh/menu_bottomtray.xml deleted file mode 100644 index a00aa7cd35..0000000000 --- a/indra/newview/skins/default/xui/zh/menu_bottomtray.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<menu name="hide_camera_move_controls_menu"> - <menu_item_check label="講話按鈕" name="EnableVoiceChat"/> - <menu_item_check label="姿勢按鈕" name="ShowGestureButton"/> - <menu_item_check label="移動按鈕" name="ShowMoveButton"/> - <menu_item_check label="視角按鈕" name="ShowCameraButton"/> - <menu_item_check label="快照按鈕" name="ShowSnapshotButton"/> - <menu_item_check label="建造按鈕" name="ShowBuildButton"/> - <menu_item_check label="搜尋按鈕" name="ShowSearchButton"/> - <menu_item_check label="地圖按鈕" name="ShowWorldMapButton"/> - <menu_item_check label="迷你地圖按鈕" name="ShowMiniMapButton"/> - <menu_item_call label="剪下" name="NearbyChatBar_Cut"/> - <menu_item_call label="覆製" name="NearbyChatBar_Copy"/> - <menu_item_call label="貼上" name="NearbyChatBar_Paste"/> - <menu_item_call label="刪除" name="NearbyChatBar_Delete"/> - <menu_item_call label="全選" name="NearbyChatBar_Select_All"/> -</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_edit.xml b/indra/newview/skins/default/xui/zh/menu_edit.xml index d6eb87a6b0..bda640e5f3 100644 --- a/indra/newview/skins/default/xui/zh/menu_edit.xml +++ b/indra/newview/skins/default/xui/zh/menu_edit.xml @@ -3,7 +3,7 @@ <menu_item_call label="復原" name="Undo"/> <menu_item_call label="重做" name="Redo"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="恚庨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="覆製貼上" name="Duplicate"/> diff --git a/indra/newview/skins/default/xui/zh/menu_favorites.xml b/indra/newview/skins/default/xui/zh/menu_favorites.xml index c60bebd3dc..a01412ce1c 100644 --- a/indra/newview/skins/default/xui/zh/menu_favorites.xml +++ b/indra/newview/skins/default/xui/zh/menu_favorites.xml @@ -4,7 +4,7 @@ <menu_item_call label="察看 / 編輯 地標" name="Landmark Open"/> <menu_item_call label="覆製 SLurl" name="Copy slurl"/> <menu_item_call label="顯示在地圖上" name="Show On Map"/> - <menu_item_call label="覆製" name="Landmark Copy"/> + <menu_item_call label="恚庨" name="Landmark Copy"/> <menu_item_call label="貼上" name="Landmark Paste"/> <menu_item_call label="刪除" name="Delete"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml index a331c47a6e..5a38197e4c 100644 --- a/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="menu_gesture_gear"> <menu_item_call label="由我的最愛中 添加/移除" name="activate"/> - <menu_item_call label="覆製" name="copy_gesture"/> + <menu_item_call label="恚庨" name="copy_gesture"/> <menu_item_call label="貼上" name="paste"/> <menu_item_call label="覆製 UUID" name="copy_uuid"/> <menu_item_call label="儲存到目前裝扮" name="save_to_outfit"/> diff --git a/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml index dbb8ececaa..3f6820cb32 100644 --- a/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml +++ b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="hide_navbar_menu"> - <menu_item_check label="顯示導覽列" name="ShowNavbarNavigationPanel"/> + <menu_item_check label="顯示導覽列和我的最愛" name="ShowNavbarNavigationPanel"/> <menu_item_check label="顯示最愛列" name="ShowNavbarFavoritesPanel"/> <menu_item_check label="顯示迷你位置列" name="ShowMiniLocationPanel"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml index 7385764e4c..f4e886ff67 100644 --- a/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml @@ -6,16 +6,16 @@ <menu_item_call label="通話" name="call"/> <menu_item_call label="瞬間傳送" name="teleport"/> <menu_item_call label="邀請加入群組" name="invite_to_group"/> - <menu_item_call label="Block" name="block"/> - <menu_item_call label="Unblock" name="unblock"/> + <menu_item_call label="封鎖" name="block"/> + <menu_item_call label="解除封鎖" name="unblock"/> <menu_item_call label="回報" name="report"/> <menu_item_call label="凍結" name="freeze"/> <menu_item_call label="踢出" name="eject"/> <menu_item_call label="踢出" name="kick"/> - <menu_item_call label="CSR" name="csr"/> + <menu_item_call label="客服" name="csr"/> <menu_item_call label="材質除錯" name="debug"/> <menu_item_call label="在地圖上尋找" name="find_on_map"/> - <menu_item_call label="Zoom In" name="zoom_in"/> + <menu_item_call label="放大" name="zoom_in"/> <menu_item_call label="支付" name="pay"/> <menu_item_call label="分享" name="share"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml index 94ab82b8a9..abff0f64ac 100644 --- a/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml @@ -2,17 +2,18 @@ <toggleable_menu name="Gear Menu"> <menu_item_call label="觸碰" name="touch"/> <menu_item_call label="坐下" name="sit"/> - <menu_item_call label="Pay" name="pay"/> + <menu_item_call label="支付" name="pay"/> <menu_item_call label="購買" name="buy"/> <menu_item_call label="取得" name="take"/> <menu_item_call label="取得副本" name="take_copy"/> - <menu_item_call label="開啟" name="open"/> + <menu_item_call label="打開" name="open"/> <menu_item_call label="編輯" name="edit"/> <menu_item_call label="穿上" name="wear"/> <menu_item_call label="添加" name="add"/> <menu_item_call label="回報" name="report"/> - <menu_item_call label="Block" name="block"/> - <menu_item_call label="Zoom In" name="zoom_in"/> + <menu_item_call label="封鎖" name="block"/> + <menu_item_call label="解除封鎖" name="unblock"/> + <menu_item_call label="放大" name="zoom_in"/> <menu_item_call label="移除" name="remove"/> <menu_item_call label="更多資訊" name="more_info"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml index 1c75705743..c48ee0c9be 100644 --- a/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml @@ -17,7 +17,7 @@ <menu_item_call label="半透明" name="Self Alpha"/> <menu_item_call label="全部衣服" name="All Clothes"/> </context_menu> - <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="擡頭顯示" name="Object Detach HUD"/> <context_menu label="卸下" name="Object Detach"/> <menu_item_call label="全部卸下" name="Detach All"/> </context_menu> @@ -26,6 +26,6 @@ <menu_item_call label="編輯我的體形" name="Edit My Shape"/> <menu_item_call label="我的朋友" name="Friends..."/> <menu_item_call label="我的群組" name="Groups..."/> - <menu_item_call label="我的檔案" name="Profile..."/> + <menu_item_call label="我的個人檔案" name="Profile..."/> <menu_item_call label="材質除錯" name="Debug..."/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inventory.xml b/indra/newview/skins/default/xui/zh/menu_inventory.xml index 87d769af0d..7f745ffaa7 100644 --- a/indra/newview/skins/default/xui/zh/menu_inventory.xml +++ b/indra/newview/skins/default/xui/zh/menu_inventory.xml @@ -2,13 +2,13 @@ <menu name="Popup"> <menu_item_call label="分享" name="Share"/> <menu_item_call label="購買" name="Task Buy"/> - <menu_item_call label="開啟" name="Task Open"/> + <menu_item_call label="打開" name="Task Open"/> <menu_item_call label="播放" name="Task Play"/> <menu_item_call label="屬性" name="Task Properties"/> <menu_item_call label="更名" name="Task Rename"/> <menu_item_call label="刪除" name="Task Remove"/> <menu_item_call label="清空垃圾筒" name="Empty Trash"/> - <menu_item_call label="清空 Lost And Found" name="Empty Lost And Found"/> + <menu_item_call label="清空所有失物" name="Empty Lost And Found"/> <menu_item_call label="新資料夾" name="New Folder"/> <menu_item_call label="新腳本" name="New Script"/> <menu_item_call label="新記事卡" name="New Note"/> @@ -18,7 +18,7 @@ <menu_item_call label="新褲子" name="New Pants"/> <menu_item_call label="新鞋子" name="New Shoes"/> <menu_item_call label="新襪子" name="New Socks"/> - <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新外套" name="New Jacket"/> <menu_item_call label="新裙子" name="New Skirt"/> <menu_item_call label="新手套" name="New Gloves"/> <menu_item_call label="新內衣" name="New Undershirt"/> @@ -46,42 +46,46 @@ <menu_item_call label="內衣" name="Undershirt"/> </menu> <menu_item_call label="瞬間傳送" name="Landmark Open"/> - <menu_item_call label="開啟" name="Animation Open"/> - <menu_item_call label="開啟" name="Sound Open"/> + <menu_item_call label="打開" name="Animation Open"/> + <menu_item_call label="打開" name="Sound Open"/> <menu_item_call label="取代目前的裝扮" name="Replace Outfit"/> <menu_item_call label="添加到目前裝扮" name="Add To Outfit"/> <menu_item_call label="由目前的裝扮移除" name="Remove From Outfit"/> <menu_item_call label="尋找原件" name="Find Original"/> <menu_item_call label="清空物品" name="Purge Item"/> - <menu_item_call label="恢復物品" name="Restore Item"/> - <menu_item_call label="開啟" name="Open"/> + <menu_item_call label="還原物品" name="Restore Item"/> + <menu_item_call label="打開" name="Open"/> <menu_item_call label="開啟原件" name="Open Original"/> <menu_item_call label="屬性" name="Properties"/> <menu_item_call label="更名" name="Rename"/> <menu_item_call label="覆製資產 UUID" name="Copy Asset UUID"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="剪下" name="Cut"/> + <menu_item_call label="恚庨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> - <menu_item_call label="Paste As Link" name="Paste As Link"/> + <menu_item_call label="以連結格式貼上" name="Paste As Link"/> <menu_item_call label="刪除" name="Remove Link"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="刪除系統資料夾" name="Delete System Folder"/> - <menu_item_call label="Start Conference Chat" name="Conference Chat Folder"/> + <menu_item_call label="發起多方通話" name="Conference Chat Folder"/> <menu_item_call label="播放" name="Sound Play"/> + <menu_item_call label="覆製 SLurl" name="url_copy"/> <menu_item_call label="添加地標" name="About Landmark"/> - <menu_item_call label="播放於虛擬世界" name="Animation Play"/> - <menu_item_call label="播放於本地" name="Animation Audition"/> + <menu_item_call label="在虛擬世界播放" name="Animation Play"/> + <menu_item_call label="在本地播放" name="Animation Audition"/> <menu_item_call label="送出即時訊息" name="Send Instant Message"/> - <menu_item_call label="發給瞬間傳送請求..." name="Offer Teleport..."/> - <menu_item_call label="開始會議交談" name="Conference Chat"/> - <menu_item_call label="Activate" name="Activate"/> - <menu_item_call label="Deactivate" name="Deactivate"/> - <menu_item_call label="另存" name="Save As"/> - <menu_item_call label="Detach From Yourself" name="Detach From Yourself"/> - <menu_item_call label="Wear" name="Wearable And Object Wear"/> - <menu label="Attach To" name="Attach To"/> - <menu label="Attach To HUD" name="Attach To HUD"/> + <menu_item_call label="發出瞬間傳送邀請..." name="Offer Teleport..."/> + <menu_item_call label="發起多方通話" name="Conference Chat"/> + <menu_item_call label="啟動" name="Activate"/> + <menu_item_call label="停用" name="Deactivate"/> + <menu_item_call label="另存為" name="Save As"/> + <menu_item_call label="從你身上移除" name="Detach From Yourself"/> + <menu_item_call label="穿上" name="Wearable And Object Wear"/> + <menu label="附著到..." name="Attach To"/> + <menu label="附著到擡頭顯示" name="Attach To HUD"/> <menu_item_call label="編輯" name="Wearable Edit"/> <menu_item_call label="添加" name="Wearable Add"/> <menu_item_call label="脫下" name="Take Off"/> + <menu_item_call label="複製到商家發件匣" name="Merchant Copy"/> + <menu_item_call label="送往第二人生購物市集" name="Marketplace Send"/> <menu_item_call label="-- 無選項 --" name="--no options--"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml index a0fc060e27..30bf5a7e75 100644 --- a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml @@ -4,7 +4,9 @@ <menu_item_call label="圖像(L$[COST])..." name="Upload Image"/> <menu_item_call label="聲音(L$[COST])..." name="Upload Sound"/> <menu_item_call label="動作(L$[COST])..." name="Upload Animation"/> - <menu_item_call label="大批(L$[COST] 每檔案)..." name="Bulk Upload"/> + <menu_item_call label="模型…" name="Upload Model"/> + <menu_item_call label="模型精靈…" name="Upload Model Wizard"/> + <menu_item_call label="批量(每檔案 L$[COST] )..." name="Bulk Upload"/> <menu_item_call label="設定預設上傳權限" name="perm prefs"/> </menu> <menu_item_call label="新資料夾" name="New Folder"/> @@ -16,7 +18,7 @@ <menu_item_call label="新褲子" name="New Pants"/> <menu_item_call label="新鞋子" name="New Shoes"/> <menu_item_call label="新襪子" name="New Socks"/> - <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新外套" name="New Jacket"/> <menu_item_call label="新裙子" name="New Skirt"/> <menu_item_call label="新手套" name="New Gloves"/> <menu_item_call label="新內衣" name="New Undershirt"/> diff --git a/indra/newview/skins/default/xui/zh/menu_land.xml b/indra/newview/skins/default/xui/zh/menu_land.xml index 84941d138c..a87ab77dd0 100644 --- a/indra/newview/skins/default/xui/zh/menu_land.xml +++ b/indra/newview/skins/default/xui/zh/menu_land.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Land Pie"> - <menu_item_call label="關於土地" name="Place Information..."/> - <menu_item_call label="坐在此處" name="Sit Here"/> + <menu_item_call label="土地資料" name="Place Information..."/> + <menu_item_call label="坐在這裡" name="Sit Here"/> <menu_item_call label="購買這塊土地" name="Land Buy"/> <menu_item_call label="購買通行權" name="Land Buy Pass"/> <menu_item_call label="建造" name="Create"/> diff --git a/indra/newview/skins/default/xui/zh/menu_login.xml b/indra/newview/skins/default/xui/zh/menu_login.xml index d6bf34c66e..c327b132a1 100644 --- a/indra/newview/skins/default/xui/zh/menu_login.xml +++ b/indra/newview/skins/default/xui/zh/menu_login.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu_bar name="Login Menu"> - <menu label="自己" name="File"> - <menu_item_call label="偏好設定" name="Preferences..."/> - <menu_item_call label="結束退出 [APP_NAME]" name="Quit"/> + <menu label="我自己" name="File"> + <menu_item_call label="偏好設定…" name="Preferences..."/> + <menu_item_call label="退出 [APP_NAME]" name="Quit"/> </menu> <menu label="幫助" name="Help"> <menu_item_call label="[SECOND_LIFE] 幫助" name="Second Life Help"/> @@ -14,11 +14,11 @@ <menu_item_call label="UI / 顏色 設定" name="UI/Color Settings"/> <menu_item_call label="XUI 預覽工具" name="UI Preview Tool"/> <menu label="UI 測試" name="UI Tests"/> - <menu_item_call label="設定視窗尺寸大小..." name="Set Window Size..."/> + <menu_item_call label="設定視窗大小..." name="Set Window Size..."/> <menu_item_call label="顯示 TOS" name="TOS"/> <menu_item_call label="顯示嚴重訊息" name="Critical"/> - <menu_item_call label="媒體瀏覽器測試" name="Web Browser Test"/> - <menu_item_call label="網頁內容浮動視窗測試" name="Web Content Floater Test"/> + <menu_item_call label="網頁內容浮動視窗除錯測試" name="Web Content Floater Debug Test"/> + <menu label="設定記錄細節" name="Set Logging Level"/> <menu_item_check label="顯示網格挑選器" name="Show Grid Picker"/> <menu_item_call label="顯示通知控制台" name="Show Notifications Console"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml index 2ec95aa4f9..d222d7f658 100644 --- a/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml +++ b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="media ctrl context menu"> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="恚庨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> + <menu_item_call label="開啟網頁偵查器" name="open_webinspector"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_mini_map.xml b/indra/newview/skins/default/xui/zh/menu_mini_map.xml index 24bc6355c7..7fd629471a 100644 --- a/indra/newview/skins/default/xui/zh/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/zh/menu_mini_map.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="Popup"> - <menu_item_call label="Zoom Close" name="Zoom Close"/> - <menu_item_call label="Zoom Medium" name="Zoom Medium"/> - <menu_item_call label="Zoom Far" name="Zoom Far"/> - <menu_item_call label="Zoom Default" name="Zoom Default"/> + <menu_item_call label="放大靠近" name="Zoom Close"/> + <menu_item_call label="遠近適距" name="Zoom Medium"/> + <menu_item_call label="縮小遠離" name="Zoom Far"/> + <menu_item_call label="縮放恢復預設" name="Zoom Default"/> <menu_item_check label="旋轉地圖" name="Rotate Map"/> <menu_item_check label="自動居中" name="Auto Center"/> <menu_item_call label="停止追蹤" name="Stop Tracking"/> diff --git a/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml new file mode 100644 index 0000000000..5f82685632 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="model_menu_gear_default"> + <menu_item_check label="顯示側邊" name="show_edges"/> + <menu_item_check label="顯示物理" name="show_physics"/> + <menu_item_check label="顯示材質" name="show_textures"/> + <menu_item_check label="顯示表皮重量" name="show_skin_weight"/> + <menu_item_check label="顯示接點位置" name="show_joint_positions"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_navbar.xml b/indra/newview/skins/default/xui/zh/menu_navbar.xml index 69df4929f2..d8356e6277 100644 --- a/indra/newview/skins/default/xui/zh/menu_navbar.xml +++ b/indra/newview/skins/default/xui/zh/menu_navbar.xml @@ -4,7 +4,7 @@ <menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/> <menu_item_call label="地標" name="Landmark"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="恚庨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="全選" name="Select All"/> diff --git a/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml index cad462eebb..ce5f5b6e17 100644 --- a/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml +++ b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="NearBy Chat Menu"> <menu_item_call label="顯示附近的人..." name="nearby_people"/> - <menu_item_check label="Show Blocked Text" name="muted_text"/> - <menu_item_check label="Show Buddy Icons" name="show_buddy_icons"/> - <menu_item_check label="Show Names" name="show_names"/> - <menu_item_check label="Show Icons and Names" name="show_icons_and_names"/> + <menu_item_check label="顯示被封鎖文字" name="muted_text"/> + <menu_item_check label="顯示密友圖示" name="show_buddy_icons"/> + <menu_item_check label="顯示名字" name="show_names"/> + <menu_item_check label="顯示圖示和名字" name="show_icons_and_names"/> <menu_item_call label="字型尺寸" name="font_size"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_object.xml b/indra/newview/skins/default/xui/zh/menu_object.xml index ed41a4f0bf..4282c1e131 100644 --- a/indra/newview/skins/default/xui/zh/menu_object.xml +++ b/indra/newview/skins/default/xui/zh/menu_object.xml @@ -3,19 +3,21 @@ <menu_item_call label="觸碰" name="Object Touch"/> <menu_item_call label="編輯" name="Edit..."/> <menu_item_call label="建造" name="Build"/> - <menu_item_call label="開啟" name="Open"/> - <menu_item_call label="坐下" name="Object Sit"/> + <menu_item_call label="在聯結集裡顯示" name="show_in_linksets"/> + <menu_item_call label="在角色中顯示" name="show_in_characters"/> + <menu_item_call label="打開" name="Open"/> + <menu_item_call label="坐在這裡" name="Object Sit"/> <menu_item_call label="起立" name="Object Stand Up"/> <menu_item_call label="物件檔案" name="Object Inspect"/> - <menu_item_call label="Zoom In" name="Zoom In"/> + <menu_item_call label="放大" name="Zoom In"/> <context_menu label="穿上" name="Put On"> <menu_item_call label="穿上" name="Wear"/> <menu_item_call label="添加" name="Add"/> - <context_menu label="Attach" name="Object Attach"/> - <context_menu label="Attach HUD" name="Object Attach HUD"/> + <context_menu label="附著" name="Object Attach"/> + <context_menu label="附加擡頭顯示" name="Object Attach HUD"/> </context_menu> <context_menu label="管理" name="Remove"> - <menu_item_call label="舉報濫用" name="Report Abuse..."/> + <menu_item_call label="違規舉報" name="Report Abuse..."/> <menu_item_call label="封鎖" name="Object Mute"/> <menu_item_call label="退回" name="Return..."/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_object_icon.xml b/indra/newview/skins/default/xui/zh/menu_object_icon.xml index d27e75b830..f4f93b0bdc 100644 --- a/indra/newview/skins/default/xui/zh/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/zh/menu_object_icon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="Object Icon Menu"> <menu_item_call label="物件檔案..." name="Object Profile"/> - <menu_item_call label="Block..." name="Block"/> + <menu_item_call label="封鎖…" name="Block"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml index 90704fee65..e85b4b7182 100644 --- a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml @@ -8,7 +8,7 @@ <menu_item_call label="新褲子" name="New Pants"/> <menu_item_call label="新鞋子" name="New Shoes"/> <menu_item_call label="新襪子" name="New Socks"/> - <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新外套" name="New Jacket"/> <menu_item_call label="新裙子" name="New Skirt"/> <menu_item_call label="新手套" name="New Gloves"/> <menu_item_call label="新內衣" name="New Undershirt"/> diff --git a/indra/newview/skins/default/xui/zh/menu_participant_list.xml b/indra/newview/skins/default/xui/zh/menu_participant_list.xml index 81ae6e4e85..2456e9fee9 100644 --- a/indra/newview/skins/default/xui/zh/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/zh/menu_participant_list.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Participant List Context Menu"> <menu_item_check label="依名稱排序" name="SortByName"/> - <menu_item_check label="Sort by Recent Speakers" name="SortByRecentSpeakers"/> + <menu_item_check label="依最近說話者排序" name="SortByRecentSpeakers"/> <menu_item_call label="察看檔案" name="View Profile"/> <menu_item_call label="加為朋友" name="Add Friend"/> <menu_item_call label="IM" name="IM"/> @@ -9,13 +9,13 @@ <menu_item_call label="分享" name="Share"/> <menu_item_call label="支付" name="Pay"/> <menu_item_check label="察看人群圖示" name="View Icons"/> - <menu_item_check label="Block Voice" name="Block/Unblock"/> - <menu_item_check label="Block Text" name="MuteText"/> - <context_menu label="Moderator Options" name="Moderator Options"> - <menu_item_check label="Allow text chat" name="AllowTextChat"/> - <menu_item_call label="Mute this participant" name="ModerateVoiceMuteSelected"/> - <menu_item_call label="Unmute this participant" name="ModerateVoiceUnMuteSelected"/> - <menu_item_call label="Mute everyone" name="ModerateVoiceMute"/> - <menu_item_call label="Unmute everyone" name="ModerateVoiceUnmute"/> + <menu_item_check label="禁止語音" name="Block/Unblock"/> + <menu_item_check label="禁止文字" name="MuteText"/> + <context_menu label="主持人選項" name="Moderator Options"> + <menu_item_check label="允許文字聊天" name="AllowTextChat"/> + <menu_item_call label="將此人消音" name="ModerateVoiceMuteSelected"/> + <menu_item_call label="取消對此人的消音" name="ModerateVoiceUnMuteSelected"/> + <menu_item_call label="所有人消音" name="ModerateVoiceMute"/> + <menu_item_call label="取消所有人的消音" name="ModerateVoiceUnmute"/> </context_menu> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_groups.xml b/indra/newview/skins/default/xui/zh/menu_people_groups.xml index 1d78c1de0a..5768c554c9 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_groups.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_groups.xml @@ -3,6 +3,6 @@ <menu_item_call label="察看資訊" name="View Info"/> <menu_item_call label="聊天" name="Chat"/> <menu_item_call label="通話" name="Call"/> - <menu_item_call label="Activate" name="Activate"/> - <menu_item_call label="Leave" name="Leave"/> + <menu_item_call label="啟動" name="Activate"/> + <menu_item_call label="退出" name="Leave"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml index 9faa35001c..38d5f3d324 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml @@ -2,12 +2,12 @@ <context_menu name="Avatar Context Menu"> <menu_item_call label="察看檔案" name="View Profile"/> <menu_item_call label="加為朋友" name="Add Friend"/> - <menu_item_call label="Remove Friend" name="Remove Friend"/> + <menu_item_call label="移除朋友" name="Remove Friend"/> <menu_item_call label="IM" name="IM"/> <menu_item_call label="通話" name="Call"/> <menu_item_call label="地圖" name="Map"/> <menu_item_call label="分享" name="Share"/> <menu_item_call label="支付" name="Pay"/> - <menu_item_check label="Block/Unblock" name="Block/Unblock"/> + <menu_item_check label="封鎖/不再封鎖" name="Block/Unblock"/> <menu_item_call label="發給瞬間傳送請求" name="teleport"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml index a7f5c74b82..6cb0ac3c89 100644 --- a/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml @@ -4,5 +4,6 @@ <menu_item_check label="依名稱排序" name="sort_name"/> <menu_item_check label="依距離排序" name="sort_distance"/> <menu_item_check label="察看人群圖示" name="view_icons"/> - <menu_item_call label="顯示笨封鎖的居民與物件" name="show_blocked_list"/> + <menu_item_check label="察看地圖" name="view_map"/> + <menu_item_call label="顯示被封鎖的居民與物件" name="show_blocked_list"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_picks_plus.xml b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml index e962bd90d5..80922a757d 100644 --- a/indra/newview/skins/default/xui/zh/menu_picks_plus.xml +++ b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="picks_plus_menu"> <menu_item_call label="新精選地點" name="create_pick"/> - <menu_item_call label="New Classified" name="create_classified"/> + <menu_item_call label="新個人廣告" name="create_classified"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml index 7f4144d14d..27f0c7ebdb 100644 --- a/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml @@ -4,7 +4,7 @@ <menu_item_call label="添加資料夾" name="add_folder"/> <menu_item_call label="還原物品" name="restore_item"/> <menu_item_call label="剪下" name="cut"/> - <menu_item_call label="覆製" name="copy_folder"/> + <menu_item_call label="恚庨" name="copy_folder"/> <menu_item_call label="貼上" name="paste"/> <menu_item_call label="更名" name="rename"/> <menu_item_call label="刪除" name="delete"/> diff --git a/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml index ca637ae54d..f77e7090c4 100644 --- a/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml +++ b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml @@ -3,10 +3,10 @@ <menu_item_call label="地圖" name="show_on_map"/> <menu_item_call label="支付" name="pay"/> <menu_item_call label="分享" name="share"/> - <menu_item_call label="Block" name="block"/> - <menu_item_call label="Unblock" name="unblock"/> + <menu_item_call label="封鎖" name="block"/> + <menu_item_call label="解除封鎖" name="unblock"/> <menu_item_call label="踢出" name="kick"/> <menu_item_call label="凍結" name="freeze"/> <menu_item_call label="解凍" name="unfreeze"/> - <menu_item_call label="CSR" name="csr"/> + <menu_item_call label="客服" name="csr"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_save_outfit.xml b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml index 7884df5b01..53ee6ee977 100644 --- a/indra/newview/skins/default/xui/zh/menu_save_outfit.xml +++ b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <toggleable_menu name="save_outfit_menu"> <menu_item_call label="儲存" name="save_outfit"/> - <menu_item_call label="另存" name="save_as_new_outfit"/> + <menu_item_call label="另存為" name="save_as_new_outfit"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml index f9107a96ed..90e8098348 100644 --- a/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml +++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Teleport History Item Context Menu"> - <menu_item_call label="開啟" name="TabOpen"/> + <menu_item_call label="打開" name="TabOpen"/> <menu_item_call label="關閉" name="TabClose"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_text_editor.xml b/indra/newview/skins/default/xui/zh/menu_text_editor.xml index c25f5128c3..febc0b8b67 100644 --- a/indra/newview/skins/default/xui/zh/menu_text_editor.xml +++ b/indra/newview/skins/default/xui/zh/menu_text_editor.xml @@ -1,7 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Text editor context menu"> + <menu_item_call label="(未知)" name="Suggestion 1"/> + <menu_item_call label="(未知)" name="Suggestion 2"/> + <menu_item_call label="(未知)" name="Suggestion 3"/> + <menu_item_call label="(未知)" name="Suggestion 4"/> + <menu_item_call label="(未知)" name="Suggestion 5"/> + <menu_item_call label="新增到字典" name="Add to Dictionary"/> + <menu_item_call label="新增到忽略清單" name="Add to Ignore"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="恚庨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="刪除" name="Delete"/> <menu_item_call label="全選" name="Select All"/> diff --git a/indra/newview/skins/default/xui/zh/menu_toolbars.xml b/indra/newview/skins/default/xui/zh/menu_toolbars.xml new file mode 100644 index 0000000000..d318992dd5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_toolbars.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Toolbars Popup"> + <menu_item_call label="移除此按鈕" name="Remove button"/> + <menu_item_call label="工具列按鈕…" name="Choose Buttons"/> + <menu_item_check label="圖示和標籤" name="icons_with_text"/> + <menu_item_check label="僅用圖示" name="icons_only"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_topinfobar.xml b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml index debaafaa10..b07e9890ff 100644 --- a/indra/newview/skins/default/xui/zh/menu_topinfobar.xml +++ b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml @@ -3,5 +3,5 @@ <menu_item_check label="顯示座標" name="Show Coordinates"/> <menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/> <menu_item_call label="地標" name="Landmark"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="恚庨" name="Copy"/> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_http.xml b/indra/newview/skins/default/xui/zh/menu_url_http.xml index cf953576f3..861cbfb975 100644 --- a/indra/newview/skins/default/xui/zh/menu_url_http.xml +++ b/indra/newview/skins/default/xui/zh/menu_url_http.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Url Popup"> <menu_item_call label="開啟網頁" name="url_open"/> - <menu_item_call label="Open in Internal Browser" name="url_open_internal"/> - <menu_item_call label="Open in External Browser" name="url_open_external"/> - <menu_item_call label="Copy URL to clipboard" name="url_copy"/> + <menu_item_call label="用內部瀏覽器開啟" name="url_open_internal"/> + <menu_item_call label="用外部瀏覽器開啟" name="url_open_external"/> + <menu_item_call label="覆製 URL 到剪貼簿" name="url_copy"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_slapp.xml b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml index afc15ce13c..6ce9a10d3e 100644 --- a/indra/newview/skins/default/xui/zh/menu_url_slapp.xml +++ b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Url Popup"> - <menu_item_call label="Run This Command" name="run_slapp"/> + <menu_item_call label="執行這個指令" name="run_slapp"/> <menu_item_call label="覆製 SLurl 到剪貼簿" name="url_copy"/> </context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index b6bb79bcbc..ac0e9e7e35 100644 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -1,65 +1,92 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu_bar name="Main Menu"> - <menu label="自己" name="Me"> - <menu_item_call label="偏好設定" name="Preferences"/> - <menu_item_call label="我的塗鴉牆" name="Manage My Account"/> - <menu_item_call label="購買 L$" name="Buy and Sell L$"/> - <menu_item_call label="我的個人檔案" name="Profile"/> - <menu_item_call label="我的外觀" name="ChangeOutfit"/> - <menu_item_check label="我的庫存" name="Inventory"/> - <menu_item_check label="我的庫存" name="ShowSidetrayInventory"/> - <menu_item_check label="我的姿勢" name="Gestures"/> - <menu_item_check label="我的聲音" name="ShowVoice"/> - <menu label="移動" name="Movement"> + <menu label="我自己" name="Me"> + <menu_item_call label="檔案..." name="Profile"/> + <menu_item_call label="外觀…" name="ChangeOutfit"/> + <menu_item_call label="選擇一個化身…" name="Avatar Picker"/> + <menu_item_check label="收納區…" name="Inventory"/> + <menu_item_call label="新收納區視窗" name="NewInventoryWindow"/> + <menu_item_call label="地點…" name="Places"/> + <menu_item_call label="精選地點…" name="Picks"/> + <menu_item_call label="攝影機控制…" name="Camera Controls"/> + <menu label="動作" name="Movement"> <menu_item_call label="坐下" name="Sit Down Here"/> <menu_item_check label="飛行" name="Fly"/> - <menu_item_check label="總是奔跑" name="Always Run"/> + <menu_item_check label="以跑代步" name="Always Run"/> <menu_item_call label="停止我身上的動作" name="Stop Animating My Avatar"/> + <menu_item_call label="行走 / 跑步 / 飛行…" name="Walk / run / fly"/> </menu> - <menu label="我的狀態" name="Status"> + <menu label="狀態" name="Status"> <menu_item_call label="離開" name="Set Away"/> <menu_item_call label="忙碌" name="Set Busy"/> </menu> - <menu_item_call label="結束退出 [APP_NAME]" name="Quit"/> + <menu_item_call label="購買 L$…" name="Buy and Sell L$"/> + <menu_item_call label="商家發件匣…" name="MerchantOutbox"/> + <menu_item_call label="帳戶主控臺…" name="Manage My Account"/> + <menu_item_call label="偏好設定…" name="Preferences"/> + <menu_item_call label="工具列按鈕…" name="Toolbars"/> + <menu_item_call label="隱藏所有控制" name="Hide UI"/> + <menu_item_check label="顯示 HUD 附件" name="Show HUD Attachments"/> + <menu_item_call label="退出 [APP_NAME]" name="Quit"/> </menu> <menu label="溝通" name="Communicate"> - <menu_item_call label="我的朋友" name="My Friends"/> - <menu_item_call label="我的群組" name="My Groups"/> - <menu_item_check label="附近的聊天" name="Nearby Chat"/> + <menu_item_check label="聊天…" name="Nearby Chat"/> + <menu_item_check label="說話" name="Speak"/> + <menu_item_check label="語音設定…" name="Nearby Voice"/> + <menu_item_check label="語音變聲…" name="ShowVoice"/> + <menu_item_check label="姿勢…" name="Gestures"/> + <menu_item_call label="朋友" name="My Friends"/> + <menu_item_call label="群組" name="My Groups"/> <menu_item_call label="附近的人群" name="Active Speakers"/> + <menu_item_call label="封鎖清單" name="Block List"/> </menu> <menu label="世界" name="World"> - <menu_item_check label="迷你地圖" name="Mini-Map"/> + <menu_item_call label="將此處記為地標" name="Create Landmark Here"/> + <menu_item_call label="目的地…" name="Destinations"/> <menu_item_check label="世界地圖" name="World Map"/> + <menu_item_check label="迷你地圖" name="Mini-Map"/> <menu_item_check label="搜尋" name="Search"/> - <menu_item_call label="拍攝快照" name="Take Snapshot"/> - <menu_item_call label="將此處記下地標" name="Create Landmark Here"/> - <menu_item_separator/> - <menu_item_call label="地點檔案" name="Place Profile"/> - <menu_item_call label="關於土地" name="About Land"/> - <menu_item_call label="地區 / 領地" name="Region/Estate"/> + <menu_item_call label="瞬間傳送回家" name="Teleport Home"/> + <menu_item_call label="把這裡設為我的家" name="Set Home to Here"/> + <menu_item_call label="快照" name="Take Snapshot"/> + <menu_item_call label="地點小檔案" name="Place Profile"/> + <menu_item_call label="土地資料" name="About Land"/> + <menu_item_call label="地區/領地" name="Region/Estate"/> + <menu_item_call label="我所擁有的土地…" name="My Land"/> <menu_item_call label="購買這塊土地" name="Buy Land"/> - <menu_item_call label="我的土地" name="My Land"/> <menu label="顯示" name="LandShow"> - <menu_item_check label="移動控制" name="Movement Controls"/> - <menu_item_check label="視角控制" name="Camera Controls"/> <menu_item_check label="禁越線" name="Ban Lines"/> <menu_item_check label="指標" name="beacons"/> - <menu_item_check label="土地邊界" name="Property Lines"/> + <menu_item_check label="地產邊界" name="Property Lines"/> <menu_item_check label="地主" name="Land Owners"/> <menu_item_check label="座標" name="Coordinates"/> <menu_item_check label="地段屬性" name="Parcel Properties"/> <menu_item_check label="進階選單" name="Show Advanced Menu"/> </menu> - <menu_item_call label="瞬間瞬間傳送回家" name="Teleport Home"/> - <menu_item_call label="設定家在此處" name="Set Home to Here"/> <menu label="太陽" name="Sun"> <menu_item_call label="日出" name="Sunrise"/> <menu_item_call label="中午" name="Noon"/> <menu_item_call label="日落" name="Sunset"/> <menu_item_call label="午夜" name="Midnight"/> - <menu_item_call label="領地時間" name="Revert to Region Default"/> - <menu_item_call label="環境編輯器" name="Environment Editor"/> + <menu_item_call label="使用地區設定" name="Use Region Settings"/> + </menu> + <menu label="環境編輯器" name="Environment Editor"> + <menu_item_call label="環境設定…" name="Environment Settings"/> + <menu label="水的自訂配置" name="Water Presets"> + <menu_item_call label="新的自訂配置…" name="new_water_preset"/> + <menu_item_call label="編輯自訂配置…" name="edit_water_preset"/> + <menu_item_call label="刪除自訂配置…" name="delete_water_preset"/> + </menu> + <menu label="天空自訂配置" name="Sky Presets"> + <menu_item_call label="新的自訂配置…" name="new_sky_preset"/> + <menu_item_call label="編輯自訂配置…" name="edit_sky_preset"/> + <menu_item_call label="刪除自訂配置…" name="delete_sky_preset"/> + </menu> + <menu label="日的自訂配置" name="Day Presets"> + <menu_item_call label="新的自訂配置…" name="new_day_preset"/> + <menu_item_call label="編輯自訂配置…" name="edit_day_preset"/> + <menu_item_call label="刪除自訂配置…" name="delete_day_preset"/> + </menu> </menu> </menu> <menu label="建造" name="BuildTools"> @@ -97,65 +124,69 @@ <menu_item_call label="設定腳本為執行中" name="Set Scripts to Running"/> <menu_item_call label="設定腳本為非執行中" name="Set Scripts to Not Running"/> </menu> + <menu label="尋徑" name="Pathfinding"> + <menu_item_call label="聯結集…" name="pathfinding_linksets_menu_item"/> + <menu_item_call label="角色…" name="pathfinding_characters_menu_item"/> + <menu_item_call label="察看 / 測試…" name="pathfinding_console_menu_item"/> + </menu> <menu label="選項" name="Options"> <menu_item_check label="顯示進階權限" name="DebugPermissions"/> <menu_item_check label="只選取我的物件" name="Select Only My Objects"/> <menu_item_check label="只選取可移動的物件" name="Select Only Movable Objects"/> - <menu_item_check label="Select By Surrounding" name="Select By Surrounding"/> - <menu_item_check label="Show Selection Outlines" name="Show Selection Outlines"/> - <menu_item_check label="Show Hidden Selection" name="Show Hidden Selection"/> - <menu_item_check label="Show Light Radius for Selection" name="Show Light Radius for Selection"/> - <menu_item_check label="Show Selection Beam" name="Show Selection Beam"/> + <menu_item_check label="環繞選取" name="Select By Surrounding"/> + <menu_item_check label="顯示選取輪廓線" name="Show Selection Outlines"/> + <menu_item_check label="顯示隱藏的選取" name="Show Hidden Selection"/> + <menu_item_check label="顯示選擇的 Light 半徑" name="Show Light Radius for Selection"/> + <menu_item_check label="顯示選擇導引線" name="Show Selection Beam"/> <menu_item_check label="貼齊格線" name="Snap to Grid"/> <menu_item_call label="貼齊物件 XY 軸到格線" name="Snap Object XY to Grid"/> - <menu_item_call label="Use Selection for Grid" name="Use Selection for Grid"/> + <menu_item_call label="以所選擇作為格線" name="Use Selection for Grid"/> <menu_item_call label="格線選項" name="Grid Options"/> </menu> <menu label="上傳" name="Upload"> <menu_item_call label="圖像(L$[COST])..." name="Upload Image"/> <menu_item_call label="聲音(L$[COST])..." name="Upload Sound"/> <menu_item_call label="動作(L$[COST])..." name="Upload Animation"/> - <menu_item_call label="大量上傳(每檔案 L$[COST] )..." name="Bulk Upload"/> + <menu_item_call label="模型…" name="Upload Model"/> + <menu_item_call label="批量(每檔案 L$[COST] )..." name="Bulk Upload"/> <menu_item_call label="設定預設上傳權限" name="perm prefs"/> </menu> <menu_item_call label="復原" name="Undo"/> <menu_item_call label="重做" name="Redo"/> </menu> <menu label="幫助" name="Help"> + <menu_item_call label="簡易教學…" name="How To"/> <menu_item_call label="[SECOND_LIFE] 幫助" name="Second Life Help"/> - <menu_item_check label="啟用提示" name="Enable Hints"/> - <menu_item_call label="舉報濫用" name="Report Abuse"/> + <menu_item_call label="違規舉報" name="Report Abuse"/> <menu_item_call label="回報臭蟲" name="Report Bug"/> <menu_item_call label="關於 [APP_NAME]" name="About Second Life"/> </menu> <menu label="進階" name="Advanced"> - <menu_item_call label="Rebake Textures" name="Rebake Texture"/> - <menu_item_call label="設定使用者界面大小至預設值" name="Set UI Size to Default"/> - <menu_item_call label="設定視窗尺寸大小..." name="Set Window Size..."/> + <menu_item_call label="重新產出材質" name="Rebake Texture"/> + <menu_item_call label="以預設值設定使用者界面大小" name="Set UI Size to Default"/> + <menu_item_call label="設定視窗大小..." name="Set Window Size..."/> <menu_item_check label="限制選擇距離" name="Limit Select Distance"/> - <menu_item_check label="Disable Camera Constraints" name="Disable Camera Distance"/> + <menu_item_check label="取消鏡頭限制" name="Disable Camera Distance"/> <menu_item_check label="高解析度快照" name="HighResSnapshot"/> <menu_item_check label="靜音拍攝快照到硬碟" name="QuietSnapshotsToDisk"/> - <menu_item_check label="壓縮快照存到硬碟" name="CompressSnapshotsToDisk"/> <menu label="效能工具" name="Performance Tools"> - <menu_item_call label="Lag Meter" name="Lag Meter"/> + <menu_item_call label="Lag 測量器" name="Lag Meter"/> <menu_item_check label="統計列" name="Statistics Bar"/> - <menu_item_check label="Show Avatar Rendering Cost" name="Avatar Rendering Cost"/> + <menu_item_check label="顯示化身的繪製重量" name="Avatar Rendering Cost"/> </menu> <menu label="高亮顯示與可見度" name="Highlighting and Visibility"> - <menu_item_check label="Cheesy Beacon" name="Cheesy Beacon"/> + <menu_item_check label="Cheesy 指標" name="Cheesy Beacon"/> <menu_item_check label="隱藏粒子效果" name="Hide Particles"/> <menu_item_check label="隱藏所選擇的" name="Hide Selected"/> <menu_item_check label="高亮顯示透明物件" name="Highlight Transparent"/> - <menu_item_check label="顯示 HUD 附件" name="Show HUD Attachments"/> <menu_item_check label="顯示第一人稱視角準星" name="ShowCrosshairs"/> </menu> - <menu label="Rendering Types" name="Rendering Types"> + <menu label="呈像類型" name="Rendering Types"> <menu_item_check label="簡單" name="Rendering Type Simple"/> <menu_item_check label="半透明" name="Rendering Type Alpha"/> <menu_item_check label="樹木" name="Rendering Type Tree"/> <menu_item_check label="化身" name="Rendering Type Character"/> - <menu_item_check label="地表" name="Rendering Type Surface Patch"/> + <menu_item_check label="表面修補" name="Rendering Type Surface Patch"/> <menu_item_check label="天空" name="Rendering Type Sky"/> <menu_item_check label="水文" name="Rendering Type Water"/> <menu_item_check label="地面" name="Rendering Type Ground"/> @@ -165,32 +196,32 @@ <menu_item_check label="粒子效果" name="Rendering Type Particles"/> <menu_item_check label="碰撞" name="Rendering Type Bump"/> </menu> - <menu label="Rendering Features" name="Rendering Features"> - <menu_item_check label="UI" name="ToggleUI"/> - <menu_item_check label="Selected" name="Selected"/> - <menu_item_check label="Highlighted" name="Highlighted"/> - <menu_item_check label="Dynamic Textures" name="Dynamic Textures"/> + <menu label="呈像功能" name="Rendering Features"> + <menu_item_check label="使用者界面" name="ToggleUI"/> + <menu_item_check label="選擇" name="Selected"/> + <menu_item_check label="高亮顯示" name="Highlighted"/> + <menu_item_check label="動態材質" name="Dynamic Textures"/> <menu_item_check label="腳步陰影" name="Foot Shadows"/> <menu_item_check label="霧氣" name="Fog"/> - <menu_item_check label="Test FRInfo" name="Test FRInfo"/> + <menu_item_check label="測試 FRInfo" name="Test FRInfo"/> <menu_item_check label="彈性物件" name="Flexible Objects"/> </menu> <menu_item_check label="使用外卦讀取緒" name="Use Plugin Read Thread"/> <menu_item_call label="清除群組快取資料" name="ClearGroupCache"/> <menu_item_check label="滑鼠平滑移動" name="Mouse Smoothing"/> + <menu_item_call label="釋出按鍵" name="Release Keys"/> <menu label="快速鍵" name="Shortcuts"> - <menu_item_call label="釋出按鍵" name="Release Keys"/> <menu_item_check label="顯示進階選單 - 舊版捷徑" name="Show Advanced Menu - legacy shortcut"/> <menu_item_call label="關閉視窗" name="Close Window"/> <menu_item_call label="關閉全部視窗" name="Close All Windows"/> <menu_item_call label="拍攝快照到硬碟" name="Snapshot to Disk"/> <menu_item_call label="第一人稱視角" name="Mouselook"/> - <menu_item_check label="Joystick Flycam" name="Joystick Flycam"/> + <menu_item_check label="搖桿移動攝影機" name="Joystick Flycam"/> <menu_item_call label="重設視角" name="Reset View"/> <menu_item_call label="注視上一位聊天者" name="Look at Last Chatter"/> - <menu_item_call label="Zoom In" name="Zoom In"/> - <menu_item_call label="Zoom Default" name="Zoom Default"/> - <menu_item_call label="Zoom Out" name="Zoom Out"/> + <menu_item_call label="放大" name="Zoom In"/> + <menu_item_call label="縮放恢復預設" name="Zoom Default"/> + <menu_item_call label="縮小" name="Zoom Out"/> </menu> <menu_item_call label="顯示除錯設定" name="Debug Settings"/> <menu_item_check label="顯示開發選單" name="Debug Mode"/> @@ -200,25 +231,27 @@ <menu_item_check label="材質控制台" name="Texture Console"/> <menu_item_check label="除錯控制台" name="Debug Console"/> <menu_item_call label="通知控制台" name="Notifications"/> - <menu_item_check label="材質尺寸控制台" name="Texture Size"/> - <menu_item_check label="材質分類控制台" name="Texture Category"/> <menu_item_check label="快速碼錶" name="Fast Timers"/> <menu_item_check label="記憶體" name="Memory"/> + <menu_item_check label="場景統計資料" name="Scene Statistics"/> + <menu_item_call label="材質擷取除錯控制台" name="Texture Fetch Debug Console"/> <menu_item_call label="地區資訊傳至除錯控制台" name="Region Info to Debug Console"/> <menu_item_call label="群組資訊至除錯控制台" name="Group Info to Debug Console"/> - <menu_item_call label="Capabilities Info to Debug Console" name="Capabilities Info to Debug Console"/> + <menu_item_call label="性能資訊傳至除錯控制台" name="Capabilities Info to Debug Console"/> <menu_item_check label="攝影機" name="Camera"/> <menu_item_check label="風力" name="Wind"/> - <menu_item_check label="FOV" name="FOV"/> - <menu_item_check label="Badge" name="Badge"/> + <menu_item_check label="視角" name="FOV"/> + <menu_item_check label="勛章" name="Badge"/> </menu> <menu label="顯示資訊" name="Display Info"> <menu_item_check label="顯示時間" name="Show Time"/> - <menu_item_check label="Show Render Info" name="Show Render Info"/> + <menu_item_check label="顯示上傳費用" name="Show Upload Cost"/> + <menu_item_check label="顯示呈像資訊" name="Show Render Info"/> <menu_item_check label="顯示材質資訊" name="Show Texture Info"/> - <menu_item_check label="Show Matrices" name="Show Matrices"/> - <menu_item_check label="Show Color Under Cursor" name="Show Color Under Cursor"/> + <menu_item_check label="顯示矩陣" name="Show Matrices"/> + <menu_item_check label="游標下顯示顏色" name="Show Color Under Cursor"/> <menu_item_check label="顯示記憶體" name="Show Memory"/> + <menu_item_check label="顯示私區記憶體資訊" name="Show Private Mem Info"/> <menu_item_check label="顯示更新到物件" name="Show Updates"/> </menu> <menu label="強制錯誤" name="Force Errors"> @@ -231,60 +264,71 @@ <menu_item_call label="強制瀏覽器斷線" name="Force Disconnect Viewer"/> <menu_item_call label="模擬記憶體不足" name="Memory Leaking Simulation"/> </menu> - <menu label="Render Tests" name="Render Tests"> + <menu label="呈像測試" name="Render Tests"> <menu_item_check label="攝影機位移" name="Camera Offset"/> - <menu_item_check label="Randomize Framerate" name="Randomize Framerate"/> - <menu_item_check label="Periodic Slow Frame" name="Periodic Slow Frame"/> - <menu_item_check label="Frame Test" name="Frame Test"/> - </menu> - <menu label="Render Metadata" name="Render Metadata"> - <menu_item_check label="Bounding Boxes" name="Bounding Boxes"/> - <menu_item_check label="Octree" name="Octree"/> - <menu_item_check label="Shadow Frusta" name="Shadow Frusta"/> - <menu_item_check label="Occlusion" name="Occlusion"/> - <menu_item_check label="Render Batches" name="Render Batches"/> - <menu_item_check label="Update Type" name="Update Type"/> - <menu_item_check label="Texture Anim" name="Texture Anim"/> - <menu_item_check label="Texture Priority" name="Texture Priority"/> - <menu_item_check label="Texture Area" name="Texture Area"/> - <menu_item_check label="Face Area" name="Face Area"/> - <menu_item_check label="Lights" name="Lights"/> - <menu_item_check label="Collision Skeleton" name="Collision Skeleton"/> - <menu_item_check label="Raycast" name="Raycast"/> - </menu> - <menu label="Rendering" name="Rendering"> - <menu_item_check label="Axes" name="Axes"/> - <menu_item_check label="Tangent Basis" name="Tangent Basis"/> - <menu_item_call label="Selected Texture Info Basis" name="Selected Texture Info Basis"/> - <menu_item_check label="Wireframe" name="Wireframe"/> - <menu_item_check label="Object-Object Occlusion" name="Object-Object Occlusion"/> - <menu_item_check label="Framebuffer Objects" name="Framebuffer Objects"/> - <menu_item_check label="Lighting and Shadows" name="Lighting and Shadows"/> - <menu_item_check label="Shadows from Sun/Moon/Projectors" name="Shadows from Sun/Moon/Projectors"/> - <menu_item_check label="SSAO and Shadow Smoothing" name="SSAO and Shadow Smoothing"/> - <menu_item_check label="Global Illumination (experimental)" name="Global Illumination"/> + <menu_item_check label="隨機變動幀率" name="Randomize Framerate"/> + <menu_item_check label="定期出現慢幀率" name="Periodic Slow Frame"/> + <menu_item_check label="畫面測試" name="Frame Test"/> + </menu> + <menu label="呈像的元資料" name="Render Metadata"> + <menu_item_check label="外框箱" name="Bounding Boxes"/> + <menu_item_check label="法線" name="Normals"/> + <menu_item_check label="八叉樹" name="Octree"/> + <menu_item_check label="陰影平截頭體" name="Shadow Frusta"/> + <menu_item_check label="物理形狀" name="Physics Shapes"/> + <menu_item_check label="遮蔽" name="Occlusion"/> + <menu_item_check label="呈像批次" name="Render Batches"/> + <menu_item_check label="更新類型" name="Update Type"/> + <menu_item_check label="材質動畫" name="Texture Anim"/> + <menu_item_check label="材質優先序" name="Texture Priority"/> + <menu_item_check label="材質區域" name="Texture Area"/> + <menu_item_check label="臉區域" name="Face Area"/> + <menu_item_check label="細節層次資訊" name="LOD Info"/> + <menu_item_check label="建製佇列" name="Build Queue"/> + <menu_item_check label="燈光" name="Lights"/> + <menu_item_check label="碰撞骨架" name="Collision Skeleton"/> + <menu_item_check label="光線投射" name="Raycast"/> + <menu_item_check label="風力向量" name="Wind Vectors"/> + <menu_item_check label="繪出複雜度" name="rendercomplexity"/> + <menu_item_check label="附件位元組" name="attachment bytes"/> + <menu_item_check label="雕刻" name="Sculpt"/> + <menu label="材質密度" name="Texture Density"> + <menu_item_check label="無" name="None"/> + <menu_item_check label="目前" name="Current"/> + <menu_item_check label="理想" name="Desired"/> + <menu_item_check label="完全" name="Full"/> + </menu> + </menu> + <menu label="呈像" name="Rendering"> + <menu_item_check label="軸" name="Axes"/> + <menu_item_check label="切線基礎" name="Tangent Basis"/> + <menu_item_call label="已選取材質資訊基礎" name="Selected Texture Info Basis"/> + <menu_item_check label="線框" name="Wireframe"/> + <menu_item_check label="物件導向的遮蔽" name="Object-Object Occlusion"/> + <menu_item_check label="光線和陰影" name="Lighting and Shadows"/> + <menu_item_check label="來自日/月/投影物的陰影" name="Shadows from Sun/Moon/Projectors"/> + <menu_item_check label="屏幕空間環境光遮蔽和陰影平滑技術" name="SSAO and Shadow Smoothing"/> <menu_item_check label="GL 除錯" name="Debug GL"/> <menu_item_check label="管線除錯" name="Debug Pipeline"/> <menu_item_check label="自動半透明遮罩(遞延)" name="Automatic Alpha Masks (deferred)"/> <menu_item_check label="自動半透明遮罩(非遞延)" name="Automatic Alpha Masks (non-deferred)"/> - <menu_item_check label="Animation Textures" name="Animation Textures"/> + <menu_item_check label="動作材質" name="Animation Textures"/> <menu_item_check label="關閉材質" name="Disable Textures"/> - <menu_item_check label="Full Res Textures" name="Rull Res Textures"/> - <menu_item_check label="Audit Textures" name="Audit Textures"/> - <menu_item_check label="Texture Atlas (experimental)" name="Texture Atlas"/> - <menu_item_check label="Render Attached Lights" name="Render Attached Lights"/> - <menu_item_check label="Render Attached Particles" name="Render Attached Particles"/> - <menu_item_check label="Hover Glow Objects" name="Hover Glow Objects"/> + <menu_item_check label="全解析度材質" name="Rull Res Textures"/> + <menu_item_check label="材質圖集(實驗性質)" name="Texture Atlas"/> + <menu_item_check label="使附著燈光呈像" name="Render Attached Lights"/> + <menu_item_check label="使附著例子效果呈像" name="Render Attached Particles"/> + <menu_item_check label="停懸發光物件" name="Hover Glow Objects"/> </menu> <menu label="網路" name="Network"> - <menu_item_check label="Pause Agent" name="AgentPause"/> - <menu_item_call label="Enable Message Log" name="Enable Message Log"/> - <menu_item_call label="Disable Message Log" name="Disable Message Log"/> - <menu_item_check label="Velocity Interpolate Objects" name="Velocity Interpolate Objects"/> - <menu_item_check label="Ping Interpolate Object Positions" name="Ping Interpolate Object Positions"/> - <menu_item_call label="Drop a Packet" name="Drop a Packet"/> - </menu> - <menu_item_call label="Dump Scripted Camera" name="Dump Scripted Camera"/> + <menu_item_check label="暫停用戶" name="AgentPause"/> + <menu_item_call label="啟用訊息記錄" name="Enable Message Log"/> + <menu_item_call label="停用訊息記錄" name="Disable Message Log"/> + <menu_item_check label="速度內插物件" name="Velocity Interpolate Objects"/> + <menu_item_check label="探詢內插物件位置" name="Ping Interpolate Object Positions"/> + <menu_item_call label="丟出一個封包" name="Drop a Packet"/> + </menu> + <menu_item_call label="傾印腳本控制的攝影機" name="Dump Scripted Camera"/> <menu_item_call label="碰撞、推擠與打擊" name="Bumps, Pushes &amp; Hits"/> <menu label="錄製器" name="Recorder"> <menu_item_call label="開始播放" name="Start Playback"/> @@ -298,24 +342,24 @@ <menu_item_check label="固定天氣" name="Fixed Weather"/> <menu_item_call label="傾印地區物件快取" name="Dump Region Object Cache"/> </menu> - <menu label="UI" name="UI"> - <menu_item_call label="測試媒體瀏覽器" name="Web Browser Test"/> + <menu label="使用者界面" name="UI"> + <menu_item_call label="媒體瀏覽器測試" name="Web Browser Test"/> <menu_item_call label="網頁內容瀏覽器" name="Web Content Browser"/> - <menu_item_call label="Dump SelectMgr" name="Dump SelectMgr"/> + <menu_item_call label="傾印 SelectMgr" name="Dump SelectMgr"/> <menu_item_call label="傾印收納區" name="Dump Inventory"/> <menu_item_call label="傾印碼錶" name="Dump Timers"/> - <menu_item_call label="Dump Focus Holder" name="Dump Focus Holder"/> - <menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/> - <menu_item_call label="Print Agent Info" name="Print Agent Info"/> + <menu_item_call label="傾印焦點容器" name="Dump Focus Holder"/> + <menu_item_call label="列印所選物件資訊" name="Print Selected Object Info"/> + <menu_item_call label="列印用戶資訊" name="Print Agent Info"/> <menu_item_call label="計憶體狀態" name="Memory Stats"/> - <menu_item_check label="Region Debug Console" name="Region Debug Console"/> - <menu_item_check label="Debug SelectMgr" name="Debug SelectMgr"/> - <menu_item_check label="Debug Clicks" name="Debug Clicks"/> + <menu_item_check label="地區除錯控制台" name="Region Debug Console"/> + <menu_item_check label="除錯 SelectMgr" name="Debug SelectMgr"/> + <menu_item_check label="除錯點按動作" name="Debug Clicks"/> <menu_item_check label="視角除錯" name="Debug Views"/> - <menu_item_check label="Debug Name Tooltips" name="Debug Name Tooltips"/> + <menu_item_check label="除錯名稱訊息提示" name="Debug Name Tooltips"/> <menu_item_check label="滑鼠事件除錯" name="Debug Mouse Events"/> <menu_item_check label="按鍵除錯" name="Debug Keys"/> - <menu_item_check label="Debug WindowProc" name="Debug WindowProc"/> + <menu_item_check label="除錯 WindowProc" name="Debug WindowProc"/> </menu> <menu label="XUI" name="XUI"> <menu_item_call label="重新載入顏色設定" name="Reload Color Settings"/> @@ -325,19 +369,18 @@ <menu_item_call label="沖洗名稱快取資料" name="Flush Names Caches"/> </menu> <menu label="化身" name="Character"> - <menu label="Grab Baked Texture" name="Grab Baked Texture"> - <menu_item_call label="Iris" name="Grab Iris"/> + <menu label="抓取已產出材質" name="Grab Baked Texture"> + <menu_item_call label="虹膜" name="Grab Iris"/> <menu_item_call label="頭部" name="Grab Head"/> - <menu_item_call label="Upper Body" name="Grab Upper Body"/> - <menu_item_call label="Lower Body" name="Grab Lower Body"/> + <menu_item_call label="上半身" name="Grab Upper Body"/> + <menu_item_call label="下半身" name="Grab Lower Body"/> <menu_item_call label="裙子" name="Grab Skirt"/> </menu> - <menu label="Character Tests" name="Character Tests"> - <menu_item_call label="Appearance To XML" name="Appearance To XML"/> - <menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/> + <menu label="字元測試" name="Character Tests"> + <menu_item_call label="將外觀轉成 XML" name="Appearance To XML"/> + <menu_item_call label="切換字元幾何特性" name="Toggle Character Geometry"/> <menu_item_call label="男性測試" name="Test Male"/> <menu_item_call label="女性測試" name="Test Female"/> - <menu_item_call label="PG 切換" name="Toggle PG"/> <menu_item_check label="允許選擇化身" name="Allow Select Avatar"/> </menu> <menu_item_call label="強制參數為預設值" name="Force Params to Default"/> @@ -345,47 +388,56 @@ <menu_item_check label="慢動作" name="Slow Motion Animations"/> <menu_item_check label="顯示注視在" name="Show Look At"/> <menu_item_check label="顯示指向在" name="Show Point At"/> - <menu_item_check label="Debug Joint Updates" name="Debug Joint Updates"/> - <menu_item_check label="Disable LOD" name="Disable LOD"/> - <menu_item_check label="Debug Character Vis" name="Debug Character Vis"/> - <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/> - <menu_item_check label="Display Agent Target" name="Display Agent Target"/> + <menu_item_check label="除錯旋軸的更新" name="Debug Joint Updates"/> + <menu_item_check label="停用細節層次" name="Disable LOD"/> + <menu_item_check label="除錯字元可見性" name="Debug Character Vis"/> + <menu_item_check label="顯示碰撞骨架" name="Show Collision Skeleton"/> + <menu_item_check label="顯示用戶目標" name="Display Agent Target"/> --> - <menu_item_call label="Dump Attachments" name="Dump Attachments"/> - <menu_item_call label="Debug Avatar Textures" name="Debug Avatar Textures"/> - <menu_item_call label="Dump Local Textures" name="Dump Local Textures"/> + <menu_item_call label="傾印附件" name="Dump Attachments"/> + <menu_item_call label="除錯化身材質" name="Debug Avatar Textures"/> + <menu_item_call label="傾印本地材質" name="Dump Local Textures"/> </menu> <menu_item_check label="HTTP 材質" name="HTTP Textures"/> - <menu_item_call label="Compress Images" name="Compress Images"/> - <menu_item_check label="Output Debug Minidump" name="Output Debug Minidump"/> - <menu_item_check label="Console Window on next Run" name="Console Window"/> - <menu_item_call label="Request Admin Status" name="Request Admin Options"/> - <menu_item_call label="Leave Admin Status" name="Leave Admin Options"/> - <menu_item_check label="Show Admin Menu" name="View Admin Options"/> + <menu_item_check label="HTTP 收納區" name="HTTP Inventory"/> + <menu_item_call label="壓縮圖像" name="Compress Images"/> + <menu_item_call label="啟用記憶體洩漏視覺偵測器" name="Enable Visual Leak Detector"/> + <menu_item_check label="輸出除錯小型傾印" name="Output Debug Minidump"/> + <menu_item_check label="下次執行時顯示控制台視窗" name="Console Window"/> + <menu label="設定記錄細節" name="Set Logging Level"> + <menu_item_check label="除錯" name="Debug"/> + <menu_item_check label="資訊" name="Info"/> + <menu_item_check label="警告" name="Warning"/> + <menu_item_check label="錯誤" name="Error"/> + <menu_item_check label="無" name="None"/> + </menu> + <menu_item_call label="要求管理員狀態" name="Request Admin Options"/> + <menu_item_call label="離開管理員狀態" name="Leave Admin Options"/> + <menu_item_check label="顯示管理員選單" name="View Admin Options"/> </menu> - <menu label="Admin" name="Admin"> - <menu label="Object" name="AdminObject"> + <menu label="管理員" name="Admin"> + <menu label="物件" name="AdminObject"> <menu_item_call label="取得副本" name="Admin Take Copy"/> - <menu_item_call label="強制擁有者為我" name="Force Owner To Me"/> - <menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/> + <menu_item_call label="將所有人強設為我自己" name="Force Owner To Me"/> + <menu_item_call label="強設為「准許所有人」" name="Force Owner Permissive"/> <menu_item_call label="刪除" name="Delete"/> - <menu_item_call label="Lock" name="Lock"/> - <menu_item_call label="Get Assets IDs" name="Get Assets IDs"/> + <menu_item_call label="鎖定" name="Lock"/> + <menu_item_call label="取得資產 ID" name="Get Assets IDs"/> </menu> <menu label="地段" name="Parcel"> - <menu_item_call label="強制擁有者為我" name="Owner To Me"/> - <menu_item_call label="Set to Linden Content" name="Set to Linden Content"/> - <menu_item_call label="Claim Public Land" name="Claim Public Land"/> + <menu_item_call label="將所有人強設為我自己" name="Owner To Me"/> + <menu_item_call label="設為 Linden 內容" name="Set to Linden Content"/> + <menu_item_call label="收取公共地" name="Claim Public Land"/> </menu> <menu label="地區" name="Region"> - <menu_item_call label="Dump Temp Asset Data" name="Dump Temp Asset Data"/> - <menu_item_call label="Save Region State" name="Save Region State"/> + <menu_item_call label="傾印暫用資產資料" name="Dump Temp Asset Data"/> + <menu_item_call label="儲存區域狀態" name="Save Region State"/> </menu> - <menu_item_call label="God Tools" name="God Tools"/> + <menu_item_call label="神之工具" name="God Tools"/> </menu> - <menu label="Admin" name="Deprecated"> - <menu label="Attach Object" name="Attach Object"/> - <menu label="Detach Object" name="Detach Object"/> + <menu label="管理員" name="Deprecated"> + <menu label="附著物件" name="Attach Object"/> + <menu label="卸去物件" name="Detach Object"/> <menu label="脫下服裝" name="Take Off Clothing"> <menu_item_call label="襯衫" name="Shirt"/> <menu_item_call label="褲子" name="Pants"/> @@ -403,13 +455,13 @@ </menu> <menu label="幫助" name="DeprecatedHelp"> <menu_item_call label="林登官方部落格" name="Official Linden Blog"/> - <menu_item_call label="Scripting Portal" name="Scripting Portal"/> + <menu_item_call label="腳本門戶" name="Scripting Portal"/> <menu label="臭蟲回報" name="Bug Reporting"> - <menu_item_call label="Public Issue Tracker" name="Public Issue Tracker"/> - <menu_item_call label="Public Issue Tracker Help" name="Publc Issue Tracker Help"/> + <menu_item_call label="大眾問題反應追蹤處" name="Public Issue Tracker"/> + <menu_item_call label="大眾問題反應追蹤處幫助" name="Publc Issue Tracker Help"/> <menu_item_call label="臭蟲回報 101" name="Bug Reporing 101"/> - <menu_item_call label="Security Issues" name="Security Issues"/> - <menu_item_call label="QA Wiki" name="QA Wiki"/> + <menu_item_call label="安全問題" name="Security Issues"/> + <menu_item_call label="品管維基" name="QA Wiki"/> </menu> </menu> </menu> diff --git a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml index 2eea314dd8..576f7f3b73 100644 --- a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Outfit Wearable Context Menu"> <menu_item_call label="取代" name="wear_replace"/> - <menu_item_call label="Wear" name="wear_wear"/> + <menu_item_call label="穿上" name="wear_wear"/> <menu_item_call label="添加" name="wear_add"/> - <menu_item_call label="Take Off / Detach" name="take_off_or_detach"/> + <menu_item_call label="脫下裝扮 / 卸除附件" name="take_off_or_detach"/> <menu_item_call label="卸下" name="detach"/> - <context_menu label="Attach to" name="wearable_attach_to"/> - <context_menu label="Attach to HUD" name="wearable_attach_to_hud"/> + <context_menu label="附著到..." name="wearable_attach_to"/> + <context_menu label="附著到擡頭顯示" name="wearable_attach_to_hud"/> <menu_item_call label="脫下" name="take_off"/> <menu_item_call label="編輯" name="edit"/> <menu_item_call label="物品檔案" name="object_profile"/> diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml index d9f4acb27b..6184f956d1 100644 --- a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml +++ b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml @@ -2,4 +2,5 @@ <toggleable_menu name="Gear Wearing"> <menu_item_call label="編輯裝扮" name="edit"/> <menu_item_call label="脫下" name="takeoff"/> + <menu_item_call label="複製裝扮清單到剪貼簿" name="copy"/> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml index 8ac1bf6920..70af2d2f19 100644 --- a/indra/newview/skins/default/xui/zh/mime_types.xml +++ b/indra/newview/skins/default/xui/zh/mime_types.xml @@ -5,7 +5,7 @@ 網頁內容 </label> <tooltip name="web_tooltip"> - 這位置有網頁內容 + 這個位置有網頁內容 </tooltip> <playtip name="web_playtip"> 顯示網頁內容 @@ -41,7 +41,7 @@ 有一個音頻在此位置 </tooltip> <playtip name="audio_playtip"> - 播放這個硾的音頻 + 播放這個位置的音頻 </playtip> </widgetset> <scheme name="rtsp"> @@ -66,7 +66,7 @@ </mimetype> <mimetype name="video/*"> <label name="video2_label"> - 視頻 + 影片 </label> </mimetype> <mimetype name="image/*"> @@ -111,7 +111,7 @@ </mimetype> <mimetype name="application/xhtml+xml"> <label name="application/xhtml+xml_label"> - 選項(XHTML) + 網頁(XHTML) </label> </mimetype> <mimetype name="application/x-director"> @@ -171,7 +171,7 @@ </mimetype> <mimetype name="text/html"> <label name="text/html_label"> - 選項 + 網頁 </label> </mimetype> <mimetype name="text/plain"> diff --git a/indra/newview/skins/default/xui/zh/mime_types_linux.xml b/indra/newview/skins/default/xui/zh/mime_types_linux.xml index 90f17b841c..70af2d2f19 100644 --- a/indra/newview/skins/default/xui/zh/mime_types_linux.xml +++ b/indra/newview/skins/default/xui/zh/mime_types_linux.xml @@ -5,7 +5,7 @@ 網頁內容 </label> <tooltip name="web_tooltip"> - This location has Web content + 這個位置有網頁內容 </tooltip> <playtip name="web_playtip"> 顯示網頁內容 @@ -27,7 +27,7 @@ 圖像 </label> <tooltip name="image_tooltip"> - There is an image at this location + 有一個圖像在此位置 </tooltip> <playtip name="image_playtip"> 察看這個位置的圖像 @@ -106,12 +106,12 @@ </mimetype> <mimetype name="application/smil"> <label name="application/smil_label"> - Synchronized Multimedia Integration Language (SMIL) + 同步多媒體整合語言(SMIL) </label> </mimetype> <mimetype name="application/xhtml+xml"> <label name="application/xhtml+xml_label"> - 選項(XHTML) + 網頁(XHTML) </label> </mimetype> <mimetype name="application/x-director"> @@ -171,7 +171,7 @@ </mimetype> <mimetype name="text/html"> <label name="text/html_label"> - 選項 + 網頁 </label> </mimetype> <mimetype name="text/plain"> diff --git a/indra/newview/skins/default/xui/zh/mime_types_mac.xml b/indra/newview/skins/default/xui/zh/mime_types_mac.xml index b8105c145c..70af2d2f19 100644 --- a/indra/newview/skins/default/xui/zh/mime_types_mac.xml +++ b/indra/newview/skins/default/xui/zh/mime_types_mac.xml @@ -30,7 +30,7 @@ 有一個圖像在此位置 </tooltip> <playtip name="image_playtip"> - 察看在此位置的圖像 + 察看這個位置的圖像 </playtip> </widgetset> <widgetset name="audio"> @@ -41,7 +41,7 @@ 有一個音頻在此位置 </tooltip> <playtip name="audio_playtip"> - 播放在此位置的音頻 + 播放這個位置的音頻 </playtip> </widgetset> <scheme name="rtsp"> @@ -66,7 +66,7 @@ </mimetype> <mimetype name="video/*"> <label name="video2_label"> - 視頻 + 影片 </label> </mimetype> <mimetype name="image/*"> @@ -76,7 +76,7 @@ </mimetype> <mimetype name="video/vnd.secondlife.qt.legacy"> <label name="vnd.secondlife.qt.legacy_label"> - 視頻 (QuickTime) + 視頻(QuickTime) </label> </mimetype> <mimetype name="application/javascript"> @@ -86,7 +86,7 @@ </mimetype> <mimetype name="application/ogg"> <label name="application/ogg_label"> - OGG 音頻/視頻 + Ogg 音頻/視頻 </label> </mimetype> <mimetype name="application/pdf"> @@ -121,7 +121,7 @@ </mimetype> <mimetype name="audio/mid"> <label name="audio/mid_label"> - 音頻 (MIDI) + 音頻(MIDI) </label> </mimetype> <mimetype name="audio/mpeg"> diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml index 3fa8ff3f78..9fecf2c104 100644 --- a/indra/newview/skins/default/xui/zh/notifications.xml +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -37,6 +37,12 @@ <button name="Help" text="$helptext"/> </form> </template> + <template name="okhelpignore"> + <form> + <button name="OK_okhelpignore" text="$yestext"/> + <button name="Help_okhelpignore" text="$helptext"/> + </form> + </template> <template name="yesnocancelbuttons"> <form> <button name="Yes" text="$yestext"/> @@ -45,19 +51,19 @@ </form> </template> <notification label="未知的通知訊息" name="MissingAlert"> - Your version of [APP_NAME] does not know how to display the notification it just received. Please verify that you have the latest Viewer installed. + 你的 [APP_NAME] 版本無法顯示它剛剛收到的通知。 請確定你安裝了最新版本的 Viewer。 -Error details: The notification called '[_NAME]' was not found in notifications.xml. +錯誤詳情:在 notifications.xml 裡找不到名為「[_NAME]」的通知。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="FloaterNotFound"> - Floater error: Could not find the following controls: + 浮動視窗錯誤:找不到以下的控制: [CONTROLS] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="TutorialNotFound"> - No tutorial is currently available. + 目前尚無教學內容。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="GenericAlert"> @@ -68,67 +74,101 @@ Error details: The notification called '[_NAME]' was not found in noti <usetemplate name="okcancelbuttons" notext="取消" yestext="是"/> </notification> <notification name="BadInstallation"> - An error occurred while updating [APP_NAME]. Please [http://get.secondlife.com download the latest version] of the Viewer. + [APP_NAME] 更新時出錯。 請 [http://get.secondlife.com 下載] 最新版本的 Viewer。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="LoginFailedNoNetwork"> - 無法連接到[SECOND_LIFE_GRID]. - '[DIAGNOSTIC]' -請確定你的網際網路是正常運作的。 + 無法連接到 [SECOND_LIFE_GRID]。 + ([DIAGNOSTIC]) +請確定你的網路連線沒有問題。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="MessageTemplateNotFound"> - Message Template [PATH] not found. + 找不到訊息模板 [PATH]。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="WearableSave"> 除存變更到目前的衣服/身體部位? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="不要儲存" yestext="儲存"/> </notification> + <notification name="ConfirmNoCopyToOutbox"> + 你無權將至少一件物項複製到第二人生購物市集的發件匣。 你可以移動這些物項,或保留不動。 + <usetemplate name="okcancelbuttons" notext="保留不移動物項" yestext="移動物項"/> + </notification> + <notification name="OutboxFolderCreated"> + 已經為你所轉移到商家發件匣頂層的每一個物項,各自建立了一個新資料夾。 + <usetemplate ignoretext="商家發件匣裡成功建立了一個新資料夾" name="okignore" yestext="確定"/> + </notification> + <notification name="OutboxImportComplete"> + 成功 + +所有資料夾已成功送往第二人生購物市集。 + <usetemplate ignoretext="所有資料夾已送往第二人生購物市集" name="okignore" yestext="確定"/> + </notification> + <notification name="OutboxImportHadErrors"> + 一部分的資料夾無法轉移 + +將一部分資料夾送往第二人生購物市集時出錯。 這些資料夾仍在你的商家發件匣。 + +詳情請參閱[[MARKETPLACE_IMPORTS_URL]錯誤記錄]。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="OutboxImportFailed"> + 轉移失敗 + +未將任何資料夾送往第二人生購物市集,系統或網路出錯。 請稍候再試一次。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="OutboxInitFailed"> + 第二人生購物市集初始化失敗 + +第二人生購物市集初始化失敗,系統或網路出錯。 請稍候再試一次。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="CompileQueueSaveText"> - There was a problem uploading the text for a script due to the following reason: [REASON]. Please try again later. + 上傳腳本文字時出問題,原因:[REASON]。 請稍候再試一次。 </notification> <notification name="CompileQueueSaveBytecode"> - There was a problem uploading the compiled script due to the following reason: [REASON]. Please try again later. + 上傳已編譯腳本時出問題,原因:[REASON]。 請稍候再試一次。 </notification> <notification name="WriteAnimationFail"> - There was a problem writing animation data. Please try again later. + 寫入動作資料時出錯。 請稍候再試一次。 </notification> <notification name="UploadAuctionSnapshotFail"> - There was a problem uploading the auction snapshot due to the following reason: [REASON] + 上傳拍賣快照時出問題,原因:[REASON] </notification> <notification name="UnableToViewContentsMoreThanOne"> - Unable to view the contents of more than one item at a time. -Please select only one object and try again. + 無法一次瀏覽多個項目的內容。 +請只選擇一個物件,再試一次。 </notification> <notification name="SaveClothingBodyChanges"> 儲存全部服裝或身體部位的變更? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="不要儲存" yestext="全部儲存"/> </notification> <notification name="FriendsAndGroupsOnly"> - Non-friends won't know that you've choosen to ignore their calls and instant messages. + 不是朋友的人不會知道你選擇忽略他們的通話要求和即時訊息。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="FavoritesOnLogin"> - Note: When you turn on this option, anyone who uses this computer can see your list of favorite locations. + 注意:你一旦同意這選項,任何使用這部電腦的人都可看到你有哪些「最愛」地點。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="GrantModifyRights"> - Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission. -Do you want to grant modify rights for [NAME]? - <usetemplate name="okcancelbuttons" notext="No" yestext="是"/> + 賦予另一居民「修改」權,將允許他更改、刪除或拿取你在虛擬世界裡擁有的任何物件。 賦予這項權限時,敬請慎重考慮。 +你仍要賦予 [NAME] 修改權嗎? + <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="GrantModifyRightsMultiple"> - Granting modify rights to another Resident allows them to change ANY objects you may have in-world. Be VERY careful when handing out this permission. -Do you want to grant modify rights for the selected Residents? + 賦予另一居民「修改」權,將允許他更改你在虛擬世界裡擁有的任何物件。 賦予這項權限時,敬請慎重考慮。 +你仍要將修改權賦予所選居民嗎? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="RevokeModifyRights"> - Do you want to revoke modify rights for [NAME]? + 你要撤銷 [NAME] 的修改權嗎? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="RevokeModifyRightsMultiple"> - Do you want to revoke modify rights for the selected Residents? + 你要撤銷所選居民的修改權嗎? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="UnableToCreateGroup"> @@ -146,33 +186,33 @@ Do you want to grant modify rights for the selected Residents? <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AddGroupOwnerWarning"> - You are about to add group members to the role of [ROLE_NAME]. -Members cannot be removed from that role. -The members must resign from the role themselves. -Are you sure you want to continue? - <usetemplate ignoretext="在我添加一個新的群組擁有者前確認" name="okcancelignore" notext="否" yestext="是"/> + 你即將賦予群組成員 [ROLE_NAME] 的角色。 +成員一旦獲得此角色,你就不能自行撤銷。 +成員必須自行離職才能撤銷這角色。 +你確定你要繼續? + <usetemplate ignoretext="在我添加一個新的群組所有人前再次確認" name="okcancelignore" notext="否" yestext="是"/> </notification> <notification name="AssignDangerousActionWarning"> - You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + 你即將把「[ACTION_NAME]」能力增加給「[ROLE_NAME]」角色。 - *WARNING* - Any Member in a Role with this Ability can assign themselves -- and any other member -- to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability. + *警告* + 任何屬於帶有這能力的角色的成員,都可以賦予自己或任何人新的角色,因此得到比現在更多的權力,最終可能擁有近似「所有人」的權力。 賦予這項能力之前,敬請慎重考慮。 -Add this Ability to '[ROLE_NAME]'? +你仍要新增這項能力給「[ROLE_NAME]」? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="AssignDangerousAbilityWarning"> - You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + 你即將把「[ACTION_NAME]」能力增加給「[ROLE_NAME]」角色。 - *WARNING* - Any Member in a Role with this Ability can assign themselves -- and any other member -- all Abilities, elevating themselves to near-Owner power. + *警告* + 任何屬於帶有這能力的角色的成員,都可以將所有能力賦予自己或任何人,提升為近似「所有人」權力的層級。 -Add this Ability to '[ROLE_NAME]'? +你仍要新增這項能力給「[ROLE_NAME]」? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="AttachmentDrop"> - You are about to drop your attachment. - Are you sure you want to continue? + 你即將卸除你的附件。 + 你確定你要繼續? <usetemplate ignoretext="在丟下附件前確認" name="okcancelignore" notext="否" yestext="是"/> </notification> <notification name="JoinGroupCanAfford"> @@ -181,178 +221,184 @@ Add this Ability to '[ROLE_NAME]'? <usetemplate name="okcancelbuttons" notext="取消" yestext="加入"/> </notification> <notification name="JoinGroupNoCost"> - You are joining group [NAME]. -Do you wish to proceed? + 你即將加入 [NAME] 群組。 +你確定要繼續嗎? <usetemplate name="okcancelbuttons" notext="取消" yestext="加入"/> </notification> <notification name="JoinGroupCannotAfford"> - Joining this group costs L$[COST]. -You do not have enough L$ to join this group. + 加入此群組須花費 L$[COST]。 +你的 L$ 不夠加入這群組。 </notification> <notification name="CreateGroupCost"> - Creating this group will cost L$100. -Groups need more than one member, or they are deleted forever. -Please invite members within 48 hours. + 創立這個群組費用為 L$100。 +群組需有至少兩位成員,否則將永久被刪除。 +請在 48 小時內邀請成員加入。 <usetemplate canceltext="取消" name="okcancelbuttons" notext="取消" yestext="花費 L$100 建立群組"/> </notification> <notification name="LandBuyPass"> - For L$[COST] you can enter this land ('[PARCEL_NAME]') for [TIME] hours. Buy a pass? + 花費 L$[COST],可進入「[PARCEL_NAME]」土地,停留 [TIME] 小時。 購買通行權? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="SalePriceRestriction"> - Sale price must be set to more than L$0 if selling to anyone. -Please select an individual to sell to if selling for L$0. + 若是出售給任何人,售價必須超過 L$0。 +如果售價定為 L$0,請選定一位出售對象。 </notification> <notification name="ConfirmLandSaleChange"> - The selected [LAND_SIZE] m² land is being set for sale. -Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. + 所選的 [LAND_SIZE] 平方公尺土地即將準備出售。 +售價將為 L$[SALE_PRICE],並將經你授權出售給 [NAME]。 <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmLandSaleToAnyoneChange"> - ATTENTION: Clicking 'sell to anyone' makes your land available to the entire [SECOND_LIFE] community, even those not in this region. + 請注意:若點按「出售給任何人」,你的土地將允許整個 [SECOND_LIFE] 社群前來購買,包括此地區外的人。 -The selected [LAND_SIZE] m² land is being set for sale. -Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. +所選的 [LAND_SIZE] 平方公尺土地即將準備出售。 +售價將為 L$[SALE_PRICE],並將經你授權出售給 [NAME]。 <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ReturnObjectsDeededToGroup"> - Are you sure you want to return all objects shared with the group '[NAME]' on this parcel of land back to their previous owner's inventory? + 你確定要將和本土地地段的「[NAME]」群組分享的所有物件送返到原所有人的收納區? -*WARNING* This will delete the non-transferable objects deeded to the group! +警告:這動作將會刪除原先讓渡給這群組的所有不可轉讓物件! -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ReturnObjectsOwnedByUser"> - Are you sure you want to return all objects owned by the Resident '[NAME]' on this parcel of land back to their inventory? + 你確定要將本地段裡「[NAME]」居民所擁有的所有物件送返其收納區? -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ReturnObjectsOwnedBySelf"> - Are you sure you want to return all objects owned by you on this parcel of land back to your inventory? + 你確定要將本地段裡你所擁有的所有物件送返你的收納區? -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ReturnObjectsNotOwnedBySelf"> - Are you sure you want to return all objects NOT owned by you on this parcel of land back to their owner's inventory? -Transferable objects deeded to a group will be returned to their previous owners. + 你確定要將本地段裡不屬於你的所有物件送返其所有人的收納區? +先前讓渡給群組的可轉讓物件將送返給原物主。 -*WARNING* This will delete the non-transferable objects deeded to the group! +警告:這動作將會刪除原先讓渡給這群組的所有不可轉讓物件! -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ReturnObjectsNotOwnedByUser"> - Are you sure you want to return all objects NOT owned by [NAME] on this parcel of land back to their owner's inventory? -Transferable objects deeded to a group will be returned to their previous owners. + 你確定要將本地段裡不屬於 [NAME] 的所有物件送返其所有人的收納區? +先前讓渡給群組的可轉讓物件將送返給原物主。 -*WARNING* This will delete the non-transferable objects deeded to the group! +警告:這動作將會刪除原先讓渡給這群組的所有不可轉讓物件! -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ReturnAllTopObjects"> - Are you sure you want to return all listed objects back to their owner's inventory? + 你確定要將所列的所有物件送返其所有人的收納區? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="DisableAllTopObjects"> - Are you sure you want to disable all objects in this region? + 你確定要停用本地區裡所有物件? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ReturnObjectsNotOwnedByGroup"> - Return the objects on this parcel of land that are NOT shared with the group [NAME] back to their owners? + 將本地段裡未和 [NAME] 群組分享的物件送返給物主? -Objects: [N] +物件:[N] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="UnableToDisableOutsideScripts"> - Can not disable scripts. -This entire region is damage enabled. -Scripts must be allowed to run for weapons to work. + 無法停用腳本。 +這整個地區允許傷害。 +腳本必須獲准執行,武器才有效。 </notification> <notification name="MultipleFacesSelected"> - Multiple faces are currently selected. -If you continue this action, separate instances of media will be set on multiple faces of the object. -To place the media on only one face, choose Select Face and click on the desired face of that object then click Add. - <usetemplate ignoretext="Media will be set on multiple selected faces" name="okcancelignore" notext="取消" yestext="確定"/> + 目前選擇了多個臉部。 +如果你繼續,物件的多個臉部將有各自的媒體啟動。 +若想只在一個臉部放置媒體,請「選擇臉部」,點按物件上你所要的臉部,再按「新增」。 + <usetemplate ignoretext="所選的多個臉部都將啟用各自的媒體。" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="MustBeInParcel"> - You must be standing inside the land parcel to set its Landing Point. + 你必須站在地段上才能設定其登陸點。 </notification> <notification name="PromptRecipientEmail"> - Please enter a valid email address for the recipient(s). + 請輸入居民的有效的電郵地址。 </notification> <notification name="PromptSelfEmail"> - Please enter your email address. + 請輸入你的電郵地址。 </notification> <notification name="PromptMissingSubjMsg"> - Email snapshot with the default subject or message? + 用預設的電郵主旨或內文送出快照? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ErrorProcessingSnapshot"> - Error processing snapshot data + 處理快照資料時出錯 </notification> <notification name="ErrorEncodingSnapshot"> - Error encoding snapshot. + 為快照編碼時出錯。 </notification> <notification name="ErrorUploadingPostcard"> - There was a problem sending a snapshot due to the following reason: [REASON] + 發送快照時出問題,原因:[REASON] </notification> <notification name="ErrorUploadingReportScreenshot"> - There was a problem uploading a report screenshot due to the following reason: [REASON] + 上傳舉報用快照時出問題,原因:[REASON] </notification> <notification name="MustAgreeToLogIn"> - You must agree to the Terms of Service to continue logging into [SECOND_LIFE]. + 你必須同意服務條款才可繼續登入 [SECOND_LIFE]。 </notification> <notification name="CouldNotPutOnOutfit"> - Could not put on outfit. -The outfit folder contains no clothing, body parts, or attachments. + 無法穿上裝扮。 +裝扮資料夾裡沒有任何衣物、身體部位或附件。 </notification> <notification name="CannotWearTrash"> - You can not wear clothes or body parts that are in the trash + 你不能穿戴垃圾桶裡的衣物或身體部位。 </notification> <notification name="MaxAttachmentsOnOutfit"> - Could not attach object. -Exceeds the attachments limit of [MAX_ATTACHMENTS] objects. Please detach another object first. + 無法附加物件。 +超過 [MAX_ATTACHMENTS] 項物件的附加上限。 請先卸除一個物件。 </notification> <notification name="CannotWearInfoNotComplete"> - You can not wear that item because it has not yet loaded. Please try again in a minute. + 無法穿戴該物件,它尚未完成載入。 請稍候再試。 </notification> <notification name="MustHaveAccountToLogIn"> - Oops! Something was left blank. -You need to enter the Username name of your avatar. + 糟糕! 發現有內容留白。 +你必須為化身輸入一個使用者名稱。 -You need an account to enter [SECOND_LIFE]. Would you like to create one now? +進入 [SECOND_LIFE] 需要一個帳號。 你現在要不要新建一個? <url name="url"> - http://join.secondlife.com/ + [create_account_url] </url> <usetemplate name="okcancelbuttons" notext="再試一次" yestext="創造新帳戶"/> </notification> <notification name="InvalidCredentialFormat"> - You need to enter either the Username or both the First and Last name of your avatar into the Username field, then login again. + 你必須在「使用者名稱」欄位裡輸入使用者名稱,或輸入化身的名和姓,然後再登入。 + </notification> + <notification name="InvalidGrid"> + '[GRID]' 不是有效的網格辨識元。 + </notification> + <notification name="InvalidLocationSLURL"> + 你的開始位置所指定的網格無效。 </notification> <notification name="DeleteClassified"> - Delete classified '[NAME]'? -There is no reimbursement for fees paid. + 刪除個人廣告「[NAME]」? +已付費用恕不退回。 <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="DeleteMedia"> - You have selected to delete the media associated with this face. -Are you sure you want to continue? + 你選擇刪除置於這臉部的媒體。 +你確定你要繼續? <usetemplate ignoretext="在我由一個部件中刪除媒體前確認" name="okcancelignore" notext="否" yestext="是"/> </notification> <notification name="ClassifiedSave"> - Save changes to classified [NAME]? + 儲存個人廣告「[NAME]」的變更? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="不要儲存" yestext="儲存"/> </notification> <notification name="ClassifiedInsufficientFunds"> - Insufficient funds to create classified. + 金額不足,無法刊登個人廣告。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="DeleteAvatarPick"> - Delete pick <nolink>[PICK]</nolink>? + 刪除精選位置<nolink>[PICK]</nolink>? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="DeleteOutfits"> @@ -367,7 +413,7 @@ Are you sure you want to continue? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="SelectProposalToView"> - Please select a proposal to view. + 請選擇一個要察看的提議。 </notification> <notification name="SelectHistoryItemToView"> 請選擇一個歷史紀錄物品去察看。 @@ -380,13 +426,13 @@ Are you sure you want to continue? 注意:這將會清除快取資料。 </notification> <notification name="ChangeConnectionPort"> - Port settings take effect after you restart [APP_NAME]. + 重新啟動 [APP_NAME] 後將啟用新的埠設定。 </notification> <notification name="ChangeSkin"> - The new skin will appear after you restart [APP_NAME]. + 重新啟動 [APP_NAME] 後將顯現新的皮膚。 </notification> <notification name="ChangeLanguage"> - Changing language will take effect after you restart [APP_NAME]. + 重新啟動 [APP_NAME] 後將換成新的語言。 </notification> <notification name="GoToAuctionPage"> 前往 [SECOND_LIFE] 網頁去察看拍賣細節或下標? @@ -396,92 +442,101 @@ Are you sure you want to continue? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="SaveChanges"> - Save Changes? + 儲存變更? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="不要儲存" yestext="儲存"/> </notification> <notification name="GestureSaveFailedTooManySteps"> - Gesture save failed. -This gesture has too many steps. -Try removing some steps, then save again. + 姿勢儲存失敗。 +這個姿勢步驟太多。 +請去除一些步驟再儲存。 </notification> <notification name="GestureSaveFailedTryAgain"> - Gesture save failed. Please try again in a minute. + 姿勢儲存失敗。 請稍候再試。 </notification> <notification name="GestureSaveFailedObjectNotFound"> - Could not save gesture because the object or the associated object inventory could not be found. -The object may be out of range or may have been deleted. + 無法儲存姿勢,找不到該物件或所屬物件收納區。 +該物件可能超出範圍或已被刪除。 </notification> <notification name="GestureSaveFailedReason"> - There was a problem saving a gesture due to the following reason: [REASON]. Please try resaving the gesture later. + 儲存姿勢時出問題,原因:[REASON]。 請稍後再嘗試儲存姿勢。 </notification> <notification name="SaveNotecardFailObjectNotFound"> - Could not save notecard because the object or the associated object inventory could not be found. -The object may be out of range or may have been deleted. + 無法儲存記事卡,找不到該物件或所屬物件收納區。 +該物件可能超出範圍或已被刪除。 </notification> <notification name="SaveNotecardFailReason"> - There was a problem saving a notecard due to the following reason: [REASON]. Please try re-saving the notecard later. + 儲存記事卡時出問題,原因:[REASON]。 請稍後再嘗試儲存記事卡。 </notification> <notification name="ScriptCannotUndo"> - Could not undo all changes in your version of the script. -Would you like to load the server's last saved version? -(**Warning** This operation cannot be undone.) + 無法取消你這個版本腳本的變更。 +是否從伺服器載入上次成功儲存的版本? +(*警告* 這動作無法還原。) <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="SaveScriptFailReason"> - There was a problem saving a script due to the following reason: [REASON]. Please try re-saving the script later. + 儲存腳本時出問題,原因:[REASON]。 請稍後再嘗試儲存腳本。 </notification> <notification name="SaveScriptFailObjectNotFound"> - Could not save the script because the object it is in could not be found. -The object may be out of range or may have been deleted. + 無法儲存腳本,找不到它所屬的物件。 +該物件可能超出範圍或已被刪除。 </notification> <notification name="SaveBytecodeFailReason"> - There was a problem saving a compiled script due to the following reason: [REASON]. Please try re-saving the script later. + 儲存編譯腳本時出問題,原因:[REASON]。 請稍後再嘗試儲存腳本。 </notification> <notification name="StartRegionEmpty"> - Oops, Your Start Region is not defined. -Please type the Region name in Start Location box or choose My Last Location or My Home as your Start Location. + 你的起始地區尚未定義。 +請在「開始位置」框裡輸入區域名,或選擇「我上一次位置」或「我的家」作為開始位置。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CouldNotStartStopScript"> - Could not start or stop the script because the object it is on could not be found. -The object may be out of range or may have been deleted. + 無法啟動或停止腳本,找不到它所屬的物件。 +該物件可能超出範圍或已被刪除。 </notification> <notification name="CannotDownloadFile"> - Unable to download file + 無法下載檔案 </notification> <notification name="CannotWriteFile"> - Unable to write file [[FILE]] + 無法寫入檔案 [[FILE]] </notification> <notification name="UnsupportedHardware"> - Just so you know, your computer does not meet [APP_NAME]'s minimum system requirements. You may experience poor performance. Unfortunately, the [SUPPORT_SITE] can't provide technical support for unsupported system configurations. + 要告知你,你的電腦未達 [APP_NAME] 的最低系統需求。 你可能會發現電腦性能不佳。 很遺憾,[SUPPORT_SITE] 無法針對不支援的系統設置提供技術支援。 -Visit [_URL] for more information? +要造訪 [_URL] 獲取進一步資訊? <url name="url"> http://www.secondlife.com/corporate/sysreqs.php </url> <usetemplate ignoretext="我的電腦硬體並不支援" name="okcancelignore" notext="否" yestext="是"/> </notification> + <notification name="IntelOldDriver"> + 你的顯示卡很可能有新版的驅動程式。 更新顯示驅動程式會大幅改善性能。 + + 前往 [_URL] 察看是否有新版驅動程式? + <url name="url"> + http://www.intel.com/p/en_US/support/detect/graphics + </url> + <usetemplate ignoretext="我的顯示驅動程式太老舊" name="okcancelignore" notext="否" yestext="是"/> + </notification> <notification name="UnknownGPU"> - Your system contains a graphics card that [APP_NAME] doesn't recognize. -This is often the case with new hardware that hasn't been tested yet with [APP_NAME]. It will probably be ok, but you may need to adjust your graphics settings. -(Me > Preferences > Graphics). + 你的系統含有一個 [APP_NAME] 無法辨認的顯像卡。 +原因很可能是 [APP_NAME] 尚未針對新硬體完成測試。 這大概不會出問題,但你可能需要調整顯像設定。 +(我自己 > 偏好設定 > 顯像) <form name="form"> <ignore name="ignore" text="我的顯示卡無法辨識"/> </form> </notification> <notification name="DisplaySettingsNoShaders"> - [APP_NAME] crashed while initializing graphics drivers. -Graphics Quality will be set to Low to avoid some common driver errors. This will disable some graphics features. -We recommend updating your graphics card drivers. -Graphics Quality can be raised in Preferences > Graphics. + [APP_NAME] 初始化顯像驅動程式時當掉了。 +顯像度將設為低階,以防發生常見的驅動程式或錯誤。 這將停用一些顯像功能。 +我們建議你更新顯像驅動程式。 +請到「偏好設定 > 顯像」提高顯像度。 </notification> <notification name="RegionNoTerraforming"> 這個 [REGION] 地區並不允許變更地形。 </notification> <notification name="CannotCopyWarning"> - You do not have permission to copy the following items: + 你沒有權限複製以下項目: [ITEMS] -and will lose it from your inventory if you give it away. Do you really want to offer these items? +如果你將它送人,它將無法續留在收納區。 你確定要送出這些東西嗎? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="CannotGiveItem"> @@ -491,18 +546,18 @@ and will lose it from your inventory if you give it away. Do you really want to 交易已取消。 </notification> <notification name="TooManyItems"> - Cannot give more than 42 items in a single inventory transfer. + 每一次的收納區轉移動作不能超過 42 項物件。 </notification> <notification name="NoItems"> - You do not have permission to transfer the selected items. + 你沒有權限轉移所選項目。 </notification> <notification name="CannotCopyCountItems"> - You do not have permission to copy [COUNT] of the selected items. You will lose these items from your inventory. -Do you really want to give these items? + 你沒有權限複製所選物件當中的 [COUNT] 項。 你的收納區將無法續留這些物件。 +你確定要送出這些東西嗎? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="CannotGiveCategory"> - You do not have permission to transfer the selected folder. + 你沒有權限轉移所選資料夾。 </notification> <notification name="FreezeAvatar"> 凍結這位化身? @@ -533,75 +588,78 @@ Do you really want to give these items? 取得錯誤:太多物件被選取。 </notification> <notification name="AcquireErrorObjectSpan"> - ACQUIRE ERROR: Objects span more than one region. -Please move all objects to be acquired onto the same region. + 取得錯誤:物件跨越多個地區。 +請將所欲取得的物件移到同一區域。 </notification> <notification name="PromptGoToCurrencyPage"> [EXTRA] -Go to [_URL] for information on purchasing L$? +前往 [_URL] 得知如何購買 L$? <url name="url"> http://secondlife.com/app/currency/ </url> <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="UnableToLinkObjects"> - Unable to link these [COUNT] objects. -You can link a maximum of [MAX] objects. + 無法聯結這 [COUNT] 個物件。 +你最多可以聯結 [MAX] 個物件。 </notification> <notification name="CannotLinkIncompleteSet"> - You can only link complete sets of objects, and must select more than one object. + 可以聯結的必需是一套物件,請選擇至少兩個物件。 </notification> <notification name="CannotLinkModify"> - Unable to link because you don't have modify permission on all the objects. + 無法聯結;你對某些物件沒有修改權。 -Please make sure none are locked, and that you own all of them. +請確定沒有物件被鎖住,並確定你擁有所有物件。 + </notification> + <notification name="CannotLinkPermanent"> + 物件無法跨越地區界限進行聯結。 </notification> <notification name="CannotLinkDifferentOwners"> - Unable to link because not all of the objects have the same owner. + 無法聯結;有些物件的所有人不同。 -Please make sure you own all of the selected objects. +請確定你是所選所有物件的所有人。 </notification> <notification name="NoFileExtension"> - No file extension for the file: '[FILE]' + 檔案沒有副檔名:'[FILE]' -Please make sure the file has a correct file extension. +請確定檔案具備正確的副檔名。 </notification> <notification name="InvalidFileExtension"> - Invalid file extension [EXTENSION] -Expected [VALIDS] + 無效的副檔名:[EXTENSION] +應該是 [VALIDS] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CannotUploadSoundFile"> - Couldn't open uploaded sound file for reading: + 無法開啟並讀取上傳的聲音檔: [FILE] </notification> <notification name="SoundFileNotRIFF"> - File does not appear to be a RIFF WAVE file: + 檔案似乎不是 RIFF WAVE 檔: [FILE] </notification> <notification name="SoundFileNotPCM"> - File does not appear to be a PCM WAVE audio file: + 檔案似乎不是 PCM WAVE 音頻檔: [FILE] </notification> <notification name="SoundFileInvalidChannelCount"> - File has invalid number of channels (must be mono or stereo): + 檔案的頻道數無效(必需為單聲道或立體聲) [FILE] </notification> <notification name="SoundFileInvalidSampleRate"> - File does not appear to be a supported sample rate (must be 44.1k): + 檔案似乎帶有不支援的採樣率(需為 44.1 k): [FILE] </notification> <notification name="SoundFileInvalidWordSize"> - File does not appear to be a supported word size (must be 8 or 16 bit): + 檔案似乎帶有不支援的字組(需為 8 或 16 位元): [FILE] </notification> <notification name="SoundFileInvalidHeader"> - Could not find 'data' chunk in WAV header: + 找不到 WAV 檔頭的「data」區塊: [FILE] </notification> <notification name="SoundFileInvalidChunkSize"> - Wrong chunk size in WAV file: + WAV 檔區塊大小錯誤: [FILE] </notification> <notification name="SoundFileInvalidTooLong"> @@ -609,41 +667,41 @@ Expected [VALIDS] [FILE] </notification> <notification name="ProblemWithFile"> - Problem with file [FILE]: + 檔案 [FILE] 有問題: [ERROR] </notification> <notification name="CannotOpenTemporarySoundFile"> - Couldn't open temporary compressed sound file for writing: [FILE] + 無法開啟並寫入暫時壓縮音頻檔:[FILE] </notification> <notification name="UnknownVorbisEncodeFailure"> - Unknown Vorbis encode failure on: [FILE] + 發生不明的 Vorbis 編碼錯誤:[FILE] </notification> <notification name="CannotEncodeFile"> - Unable to encode file: [FILE] + 無法將檔案編碼:[FILE] </notification> <notification name="CorruptedProtectedDataStore"> - We can't fill in your username and password. This may happen when you change network setup + 我們無法填入你的使用者名稱和密碼。 這可能因為你變更了網路設定。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CorruptResourceFile"> - Corrupt resource file: [FILE] + 毀損的資源檔:[FILE] </notification> <notification name="UnknownResourceFileVersion"> - Unknown Linden resource file version in file: [FILE] + 檔案中發現不明的 Linden 資源檔版本:[FILE] </notification> <notification name="UnableToCreateOutputFile"> - Unable to create output file: [FILE] + 無法建立輸出檔:[FILE] </notification> <notification name="DoNotSupportBulkAnimationUpload"> - [APP_NAME] does not currently support bulk upload of animation files. + [APP_NAME] 目前尚不支援 BVH 格式的動作檔批量上傳。 </notification> <notification name="CannotUploadReason"> - Unable to upload [FILE] due to the following reason: [REASON] -Please try again later. + 無法上傳 [FILE],原因:[REASON] +請稍候再試一次。 </notification> <notification name="LandmarkCreated"> - 你已經添加 "[LANDMARK_NAME]" 到你的 [FOLDER_NAME] 資料夾。 + 你已新增「[LANDMARK_NAME]」到你的 [FOLDER_NAME] 資料夾。 </notification> <notification name="LandmarkAlreadyExists"> 你已經有這個位置的地標。 @@ -653,132 +711,132 @@ Please try again later. 你不能創造地標,因為地主並不允許你這樣做。 </notification> <notification name="CannotRecompileSelectObjectsNoScripts"> - Not able to perform 'recompilation'. -Select an object with a script. + 無法進行重新編譯。 +請選擇帶有腳本的物件。 </notification> <notification name="CannotRecompileSelectObjectsNoPermission"> - Not able to perform 'recompilation'. + 無法進行重新編譯。 -Select objects with scripts that you have permission to modify. +選擇帶有你可修改的腳本的物件。 </notification> <notification name="CannotResetSelectObjectsNoScripts"> - Not able to perform 'reset'. + 無法重新啟動。 -Select objects with scripts. +選擇帶有腳本的物件。 </notification> <notification name="CannotResetSelectObjectsNoPermission"> - Not able to perform 'reset'. + 無法重新啟動。 -Select objects with scripts that you have permission to modify. +選擇帶有你可修改的腳本的物件。 </notification> <notification name="CannotOpenScriptObjectNoMod"> - Unable to open script in object without modify permissions. + 無法開啟物件裡的腳本,因為你沒有修改權。 </notification> <notification name="CannotSetRunningSelectObjectsNoScripts"> - Not able to set any scripts to 'running'. + 無法將任何腳本設定為「執行中」。 -Select objects with scripts. +選擇帶有腳本的物件。 </notification> <notification name="CannotSetRunningNotSelectObjectsNoScripts"> - Unable to set any scripts to 'not running'. + 無法將任何腳本設定為「不執行」。 -Select objects with scripts. +選擇帶有腳本的物件。 </notification> <notification name="NoFrontmostFloater"> - No frontmost floater to save. + 沒有最前置的浮動視窗可儲存。 </notification> <notification name="SeachFilteredOnShortWords"> - Your search query was modified and the words that were too short were removed. + 你的搜尋字串已被修改,太短的字已被移除。 -Searched for: [FINALQUERY] +搜尋:[FINALQUERY] </notification> <notification name="SeachFilteredOnShortWordsEmpty"> - Your search terms were too short so no search was performed. + 你的搜尋字串太短,所以沒有啟動搜索。 </notification> <notification name="CouldNotTeleportReason"> 瞬間傳送失敗。 [REASON] </notification> <notification name="invalid_tport"> - Problem encountered processing your teleport request. You may need to log back in before you can teleport. -If you continue to get this message, please check the [SUPPORT_SITE]. + 處理你瞬間傳送要求時發生問題。 如果想要瞬間傳送,你可能需要重新登入。 +如果你持續得到此訊息,請查閱 [SUPPORT_SITE]。 </notification> <notification name="invalid_region_handoff"> - Problem encountered processing your region crossing. You may need to log back in before you can cross regions. -If you continue to get this message, please check the [SUPPORT_SITE]. + 處理你跨越地區動作時發生問題。 如果想要跨越地區,你可能需要重新登入。 +如果你持續得到此訊息,請查閱 [SUPPORT_SITE]。 </notification> <notification name="blocked_tport"> - Sorry, teleport is currently blocked. Try again in a moment. If you still cannot teleport, please log out and log back in to resolve the problem. + 抱歉,目前禁止瞬間傳送。 請稍後再試。 如果你仍無法進行瞬間傳送,請登出後重新入來解決此一問題。 </notification> <notification name="nolandmark_tport"> - Sorry, but system was unable to locate landmark destination. + 抱歉,不過系統無法找到地標所在目的地。 </notification> <notification name="timeout_tport"> - Sorry, but system was unable to complete the teleport connection. Try again in a moment. + 抱歉,不過系統無法完成瞬間傳送的聯接。 請稍後再試。 </notification> <notification name="noaccess_tport"> - Sorry, you do not have access to that teleport destination. + 抱歉,你並沒有權限進入要瞬間傳送的目的地。 </notification> <notification name="missing_attach_tport"> - Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport. + 你的附件尚未抵達。 請稍候一會兒,或請登出後重新登入,再嘗試瞬間傳送。 </notification> <notification name="too_many_uploads_tport"> - The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area. + 該地區的資產查詢目前太過擁塞,因此你的瞬間傳送動作可能無法即時發生。 請稍候再試,或請前往較不擁塞的地區。 </notification> <notification name="expired_tport"> - Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes. + 抱歉,系統無法即時完成為你瞬間傳送。 請稍待幾分鐘再試。 </notification> <notification name="expired_region_handoff"> - Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes. + 抱歉,系統無法即時讓你跨越地區。 請稍待幾分鐘再試。 </notification> <notification name="no_host"> - Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes. + 找不到瞬間傳送的目的地。 目的地可能暫時不可用,或已不存在。 請稍待幾分鐘再試。 </notification> <notification name="no_inventory_host"> 收納區功能目前無法使用。 </notification> <notification name="CannotSetLandOwnerNothingSelected"> - 無法設定土地擁有者: -無地段被選取。 + 無法設定土地所有人: +未選擇地段。 </notification> <notification name="CannotSetLandOwnerMultipleRegions"> - Unable to force land ownership because selection spans multiple regions. Please select a smaller area and try again. + 無法強設土地所有權;所選部分跨越多個區域。 請縮小選擇範圍,再試一次。 </notification> <notification name="ForceOwnerAuctionWarning"> - This parcel is up for auction. Forcing ownership will cancel the auction and potentially make some Residents unhappy if bidding has begun. -Force ownership? + 這地段正在拍賣中。 強設所有權將取消拍賣,這恐將造成某些已出價的居民不高興。 +要強設所有權嗎? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="CannotContentifyNothingSelected"> - Unable to contentify: -No parcel selected. + 無法進行「內容化」: +未選擇地段。 </notification> <notification name="CannotContentifyNoRegion"> - Unable to contentify: -No region selected. + 無法進行「內容化」: +未選擇區域。 </notification> <notification name="CannotReleaseLandNothingSelected"> 無法放棄土地: -無地段被選擇。 +未選擇地段。 </notification> <notification name="CannotReleaseLandNoRegion"> 無法放棄土地: -無法尋找地區。 +找不到地區。 </notification> <notification name="CannotBuyLandNothingSelected"> 無法購買土地: -無地段被選擇。 +未選擇地段。 </notification> <notification name="CannotBuyLandNoRegion"> - Unable to buy land: -Cannot find the region this land is in. + 無法購買土地: +找不到這土地所在的地區。 </notification> <notification name="CannotCloseFloaterBuyLand"> - You cannot close the Buy Land window until [APP_NAME] estimates the price of this transaction. + 必須等待 [APP_NAME] 估計此交易的價格後,你才能關閉「購買土地」視窗。 </notification> <notification name="CannotDeedLandNothingSelected"> 無法讓渡土地: -無地段被選取。 +未選擇地段。 </notification> <notification name="CannotDeedLandNoGroup"> 無法讓渡土地: @@ -786,7 +844,7 @@ Cannot find the region this land is in. </notification> <notification name="CannotDeedLandNoRegion"> 無法讓渡土地: -無法發現這塊土地所在的地區。 +找不到這土地所在的地區。 </notification> <notification name="CannotDeedLandMultipleSelected"> 無法讓渡土地: @@ -802,7 +860,7 @@ Cannot find the region this land is in. </notification> <notification name="CannotDeedLandNoTransfer"> 無法讓渡土地: -此 [REGION] 地區並不允許土地轉移。 +「[REGION]」地區不允許土地轉移。 </notification> <notification name="CannotReleaseLandWatingForServer"> 無法放棄土地: @@ -823,11 +881,11 @@ Cannot find the region this land is in. </notification> <notification name="CannotReleaseLandRegionNotFound"> 無法放棄土地: -無法發現這快土地所在的地區。 +找不到這土地所在的地區。 </notification> <notification name="CannotReleaseLandNoTransfer"> 無法放棄土地: -此 [REGION] 地區並不許土地轉移。 +「[REGION]」地區不允許土地轉移。 </notification> <notification name="CannotReleaseLandPartialSelection"> 無法放棄土地: @@ -845,7 +903,7 @@ Cannot find the region this land is in. <notification name="CannotDivideLandNothingSelected"> 無法分割土地: -無地段被選取。 +未選擇地段。 </notification> <notification name="CannotDivideLandPartialSelection"> 無法分割土地: @@ -854,22 +912,22 @@ Cannot find the region this land is in. 請試著選取其中部分地段。 </notification> <notification name="LandDivideWarning"> - 分割土地會將佌地段一分為二,每一個地段將都各自有其設定。 在這個操作之後,一些設定值將會回復到預設值。 + 分割土地將把地段分為兩份,每個新地段有各自的設定。 完成後,部分設定將重設為預設值。 進行分割土地? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="CannotDivideLandNoRegion"> 無法分割土地: -無法發現這塊土地所在的地區。 +找不到這土地所在的地區。 </notification> <notification name="CannotJoinLandNoRegion"> 無法合併土地: -無法發現這塊土地所在的地區。 +找不到這土地所在的地區。 </notification> <notification name="CannotJoinLandNothingSelected"> 無法合併土地: -無地段被選取。 +未選擇地段。 </notification> <notification name="CannotJoinLandEntireParcelSelected"> 無法合併土地: @@ -891,42 +949,42 @@ Cannot find the region this land is in. <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmNotecardSave"> - 在物品能被覆製或察看前,這記事卡必須先進行儲存。儲存記事卡? + 覆製或察看前,這記事卡必須先進行儲存。 儲存記事卡? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmItemCopy"> 覆製這個物品到你的收納區? - <usetemplate name="okcancelbuttons" notext="取消" yestext="覆製"/> + <usetemplate name="okcancelbuttons" notext="取消" yestext="恚庨"/> </notification> <notification name="ResolutionSwitchFail"> - Failed to switch resolution to [RESX] by [RESY] + 無法將解析度調為 [RESX] X [RESY] </notification> <notification name="ErrorUndefinedGrasses"> - Error: Undefined grasses: [SPECIES] + 錯誤:未定義的草種:[SPECIES] </notification> <notification name="ErrorUndefinedTrees"> - Error: Undefined trees: [SPECIES] + 錯誤:未定義的樹種:[SPECIES] </notification> <notification name="CannotSaveWearableOutOfSpace"> - Unable to save '[NAME]' to wearable file. You will need to free up some space on your computer and save the wearable again. + 無法將「[NAME]」儲存為可穿裝扮檔案。 你需要空出一些電腦空間,再試著儲存可穿裝扮。 </notification> <notification name="CannotSaveToAssetStore"> - Unable to save [NAME] to central asset store. -This is usually a temporary failure. Please customize and save the wearable again in a few minutes. + 無法將「[NAME]」儲存到中央資產儲庫。 +這異常狀況通常只是暫時的。 請稍待幾分鐘後,再自訂並儲存可穿裝扮。 </notification> <notification name="YouHaveBeenLoggedOut"> - Darn. You have been logged out of [SECOND_LIFE] + 糟糕! 你已被登出 [SECOND_LIFE] [MESSAGE] - <usetemplate name="okcancelbuttons" notext="結束退出" yestext="View IM & Chat"/> + <usetemplate name="okcancelbuttons" notext="結束退出" yestext="察看 IM 和聊天內容"/> </notification> <notification name="OnlyOfficerCanBuyLand"> - Unable to buy land for the group: -You do not have permission to buy land for your active group. + 無法為這群組購買土地: +你沒有權限為你當前的群組購買土地。 </notification> <notification label="加為朋友" name="AddFriendWithMessage"> - Friends can give permissions to track each other on the map and receive online status updates. + 朋友可以允許彼此在地圖上追蹤對方,並接收彼此的線上狀態更新訊息。 -Offer friendship to [NAME]? +向 [NAME] 發出交友邀請? <form name="form"> <input name="message"> 你願意成為我的朋友嗎? @@ -935,21 +993,55 @@ Offer friendship to [NAME]? <button name="Cancel" text="取消"/> </form> </notification> + <notification label="新增自動取代清單" name="AddAutoReplaceList"> + 新清單名稱: + <form name="form"> + <button name="SetName" text="確定"/> + </form> + </notification> + <notification label="更改自動取代清單的名稱" name="RenameAutoReplaceList"> + 「[DUPNAME]」名稱已有人使用。 + 輸入另一個獨特的名稱: + <form name="form"> + <button name="ReplaceList" text="取代目前的清單"/> + <button name="SetName" text="使用新名稱"/> + </form> + </notification> + <notification name="InvalidAutoReplaceEntry"> + 關鍵字必須是一個字,取代字不得空白。 + </notification> + <notification name="InvalidAutoReplaceList"> + 該取代清單無效。 + </notification> + <notification name="SpellingDictImportRequired"> + 你必須指定一個檔案、一個名稱和一種語言。 + </notification> + <notification name="SpellingDictIsSecondary"> + [DIC_NAME] 字典似乎沒有 "aff" 檔案,這表示該字典是「次級」字典。 +它可用做附加字典,但不得作為主要字典。 + +參見 https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries + </notification> + <notification name="SpellingDictImportFailed"> + 無法複製 [FROM_NAME] + + 到 [TO_NAME] + </notification> <notification label="儲存裝扮" name="SaveOutfitAs"> 儲存我正在穿的為新裝扮: <form name="form"> <input name="message"> - [DESC] (新) + [DESC](新) </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> - <notification label="Save Wearable" name="SaveWearableAs"> + <notification label="儲存可穿裝扮" name="SaveWearableAs"> 儲存物品到我的收納區為: <form name="form"> <input name="message"> - [DESC] (新) + [DESC](新) </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> @@ -966,7 +1058,7 @@ Offer friendship to [NAME]? </form> </notification> <notification name="RemoveFromFriends"> - Do you want to remove <nolink>[NAME]</nolink> from your Friends List? + 確定要從朋友名單中移除 <nolink>[NAME]</nolink>? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="RemoveMultipleFromFriends"> @@ -974,148 +1066,147 @@ Offer friendship to [NAME]? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="GodDeleteAllScriptedPublicObjectsByUser"> - Are you sure you want to delete all scripted objects owned by -** [AVATAR_NAME] ** -on all others land in this sim? + 你確定要刪除本模擬世界所有其他土地裡,** [AVATAR_NAME] ** 所擁有的全部帶腳本的物件? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="GodDeleteAllScriptedObjectsByUser"> - Are you sure you want to DELETE ALL scripted objects owned by -** [AVATAR_NAME] ** -on ALL LAND in this sim? + 你確定要刪除本模擬世界所有土地裡,** [AVATAR_NAME] ** 所擁有的全部帶腳本的物件? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="GodDeleteAllObjectsByUser"> - Are you sure you want to DELETE ALL objects (scripted or not) owned by -** [AVATAR_NAME] ** -on ALL LAND in this sim? + 你確定要刪除本模擬世界所有土地裡,** [AVATAR_NAME] ** 所擁有的全部物件(無論是否帶腳本)? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BlankClassifiedName"> - You must specify a name for your classified. + 你的個人廣告必須指定一個名稱。 </notification> <notification name="MinClassifiedPrice"> - Price to pay for listing must be at least L$[MIN_PRICE]. + 購買此刊登物的價格必須至少為 L$[MIN_PRICE]。 -Please enter a higher price. +請輸入一個較高的價格。 </notification> <notification name="ConfirmItemDeleteHasLinks"> - At least one of the items you has link items that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first. + 所選項目中至少有一個帶有來自其他項目的聯結。 如果你刪除這一項目,聯結將永久失效。 我們強烈建議你先刪除聯結。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLock"> - At least one of the items you have selected is locked. + 你所選項目中至少有一個被鎖住。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteNoCopy"> - At least one of the items you have selected is not copyable. + 你所選項目中至少有一個不能複製。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteNoOwn"> - You do not own least one of the items you have selected. + 你所選項目中至少有一個不是你所擁有。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLockNoCopy"> - At least one object is locked. -At least one object is not copyable. + 至少有一個物件被鎖住。 +至少有一個物件不能複製。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLockNoOwn"> - At least one object is locked. -You do not own least one object. + 至少有一個物件被鎖住。 +至少有一個物件不是你所擁有。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteNoCopyNoOwn"> - At least one object is not copyable. -You do not own least one object. + 至少有一個物件不能複製。 +至少有一個物件不是你所擁有。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectDeleteLockNoCopyNoOwn"> - At least one object is locked. -At least one object is not copyable. -You do not own least one object. + 至少有一個物件被鎖住。 +至少有一個物件不能複製。 +至少有一個物件不是你所擁有。 -Are you sure you want to delete these items? +你確定你要刪除這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectTakeLock"> - At least one object is locked. + 至少有一個物件被鎖住。 -Are you sure you want to take these items? +你確定你要拿取這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectTakeNoOwn"> - You do not own all of the objects you are taking. -If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them. + 你要拿取的物件中,有些不是你所擁有。 +如果繼續,將套用「下一個所有人」權限,這可能會限制你修改或複製權。 -Are you sure you want to take these items? +你確定你要拿取這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmObjectTakeLockNoOwn"> - At least one object is locked. -You do not own all of the objects you are taking. -If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them. -However, you can take the current selection. + 至少有一個物件被鎖住。 +你要拿取的物件中,有些不是你所擁有。 +如果繼續,將套用「下一個所有人」權限,這可能會限制你修改或複製權。 +不過,你可以拿取目前所選的。 -Are you sure you want to take these items? +你確定你要拿取這些物項? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="CantBuyLandAcrossMultipleRegions"> - Unable to buy land because selection spans multiple regions. + 無法購買土地,所選部分跨越多個地區。 -Please select a smaller area and try again. +請縮小選擇範圍,再試一次。 </notification> <notification name="DeedLandToGroup"> - By deeding this parcel, the group will be required to have and maintain sufficient land use credits. -The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members. + 若讓渡此地段,這個群組將必須具備並保持足夠的土地使用信用額度。 +土地收購價將不會退還給所有人。 如果讓渡的地段被售出,售出價將均分給每位群組成員。 -Deed this [AREA] m² of land to the group '[GROUP_NAME]'? +是否讓渡這塊 [AREA] 平方公尺的土地給群組「[GROUP_NAME]」? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="DeedLandToGroupWithContribution"> - By deeding this parcel, the group will be required to have and maintain sufficient land use credits. -The deed will include a simultaneous land contribution to the group from '[NAME]'. -The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members. + 若讓渡此地段,這個群組將必須具備並保持足夠的土地使用信用額度。 +此一讓渡將同時包括來自 [NAME] 的,給予群組的土地捐獻。 +土地收購價將不會退還給所有人。 如果讓渡的地段被售出,售出價將均分給每位群組成員。 -Deed this [AREA] m² of land to the group '[GROUP_NAME]'? +是否讓渡這塊 [AREA] 平方公尺的土地給群組「[GROUP_NAME]」? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="DisplaySetToSafe"> - Display settings have been set to safe levels because you have specified the -safe option. + 因為你指定了 -safe 選項,已將顯示設為安全等級。 + </notification> + <notification name="DisplaySetToRecommendedGPUChange"> + 由於你的顯像卡有所變更,已將顯示狀態設為推薦採用的等級。 +原顯像卡:[LAST_GPU] +新顯像卡:[THIS_GPU] </notification> - <notification name="DisplaySetToRecommended"> - Display settings have been set to recommended levels based on your system configuration. + <notification name="DisplaySetToRecommendedFeatureChange"> + 由於呈像子系統有所變更,已將顯示狀態設為推薦的設定。 </notification> <notification name="ErrorMessage"> [ERROR_MESSAGE] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AvatarMovedDesired"> - Your desired location is not currently available. -You have been moved into a nearby region. + 你所要的地點目前無法前往。 +你已被移往一個鄰近地區。 </notification> <notification name="AvatarMovedLast"> - Your last location is not currently available. -You have been moved into a nearby region. + 你所請求的地點目前無法前往。 +你已被移往一個鄰近地區。 </notification> <notification name="AvatarMovedHome"> - Your home location is not currently available. -You have been moved into a nearby region. -You may want to set a new home location. + 你設為家的地點目前無法前往。 +你已被移往一個鄰近地區。 +建議你另選新地點設為家。 </notification> <notification name="ClothingLoading"> 你的服裝仍在下載中。 @@ -1127,14 +1218,13 @@ You may want to set a new home location. <notification name="FirstRun"> [APP_NAME] 安裝完成。 -If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in. -Return to [http://join.secondlife.com secondlife.com] to create a new account? - <usetemplate name="okcancelbuttons" notext="繼續" yestext="新帳戶..."/> +如果你是第一次使用 [SECOND_LIFE],你將需要建立新帳號才可登入。 + <usetemplate name="okcancelbuttons" notext="繼續" yestext="建立帳號…"/> </notification> <notification name="LoginPacketNeverReceived"> - We're having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID]. + 連線出現問題。 問題可能出在你的網路連線或 [SECOND_LIFE_GRID]。 -You can either check your Internet connection and try again in a few minutes, click Help to view the [SUPPORT_SITE], or click Teleport to attempt to teleport home. +請檢查你的網路連線,幾分鐘後再試一次,或者點按幫助瀏覽 [SUPPORT_SITE],或點按瞬間傳送試著回到你的家。 <url name="url"> http://secondlife.com/support/ </url> @@ -1145,70 +1235,70 @@ You can either check your Internet connection and try again in a few minutes, cl </form> </notification> <notification name="WelcomeChooseSex"> - Your character will appear in a moment. + 你的人物很快將會出現。 -Use arrow keys to walk. -Press the F1 key at any time for help or to learn more about [SECOND_LIFE]. -Please choose the male or female avatar. You can change your mind later. +用方向鍵行走。 +任何時候你都可按 F1 鍵察看幫助,進一步瞭解 [SECOND_LIFE]。 +請選擇男性或女性化身。 以後你仍可改變這個選擇。 <usetemplate name="okcancelbuttons" notext="女性" yestext="男性"/> </notification> <notification name="CantTeleportToGrid"> - Could not teleport to [SLURL] as it's on a different grid ([GRID]) than the current grid ([CURRENT_GRID]). Please close your viewer and try again. + 無法瞬間傳送到 [SLURL],它位於不同的網格([GRID]),目前網格是 [CURRENT_GRID]。 請關閉 Viewer 再試一次。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="GeneralCertificateError"> 無法連接到伺服器。 [REASON] -SubjectName: [SUBJECT_NAME_STRING] -IssuerName: [ISSUER_NAME_STRING] -Valid From: [VALID_FROM] -Valid To: [VALID_TO] -MD5 Fingerprint: [SHA1_DIGEST] -SHA1 Fingerprint: [MD5_DIGEST] -Key Usage: [KEYUSAGE] -Extended Key Usage: [EXTENDEDKEYUSAGE] -Subject Key Identifier: [SUBJECTKEYIDENTIFIER] +SubjectName:[SUBJECT_NAME_STRING] +IssuerName:[ISSUER_NAME_STRING] +有效來源:[VALID_FROM] +有效目標:[VALID_TO] +MD5 指紋:[SHA1_DIGEST] +SHA1 指紋:[MD5_DIGEST] +鍵的使用:[KEYUSAGE] +延伸鍵的使用:[EXTENDEDKEYUSAGE] +主題鍵辨識元:[SUBJECTKEYIDENTIFIER] <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="TrustCertificateError"> - The certification authority for this server is not known. - -Certificate Information: -SubjectName: [SUBJECT_NAME_STRING] -IssuerName: [ISSUER_NAME_STRING] -Valid From: [VALID_FROM] -Valid To: [VALID_TO] -MD5 Fingerprint: [SHA1_DIGEST] -SHA1 Fingerprint: [MD5_DIGEST] -Key Usage: [KEYUSAGE] -Extended Key Usage: [EXTENDEDKEYUSAGE] -Subject Key Identifier: [SUBJECTKEYIDENTIFIER] - -Would you like to trust this authority? - <usetemplate name="okcancelbuttons" notext="取消" yestext="Trust"/> + 不明的伺服器認證權限。 + +認證資訊: +SubjectName:[SUBJECT_NAME_STRING] +IssuerName:[ISSUER_NAME_STRING] +有效來源:[VALID_FROM] +有效目標:[VALID_TO] +MD5 指紋:[SHA1_DIGEST] +SHA1 指紋:[MD5_DIGEST] +鍵的使用:[KEYUSAGE] +延伸鍵的使用:[EXTENDEDKEYUSAGE] +主題鍵辨識元:[SUBJECTKEYIDENTIFIER] + +是否信任這個權限? + <usetemplate name="okcancelbuttons" notext="取消" yestext="信任"/> </notification> <notification name="NotEnoughCurrency"> - [NAME] L$ [PRICE] You don't have enough L$ to do that. + [NAME] L$ [PRICE] 你沒有足夠 L$ 進行這動作。 </notification> <notification name="GrantedModifyRights"> - [NAME] has given you permission to edit their objects. + [NAME] 已授權你編輯他們的物件。 </notification> <notification name="RevokedModifyRights"> - Your privilege to modify [NAME]'s objects has been revoked + 你修改 [NAME] 的物件的權限已被撤銷。 </notification> <notification name="FlushMapVisibilityCaches"> - This will flush the map caches on this region. -This is really only useful for debugging. -(In production, wait 5 minutes, then everyone's map will update after they relog.) + 這將清除本地區的地圖快取資料。 +這麼做只在除錯時有用。 +(實地環境中,等待 5 分鐘,每個人的地圖將在他們重新登入後更新。) <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BuyOneObjectOnly"> - Unable to buy more than one object at a time. Please select only one object and try again. + 無法一次購買多個物件。 請只選擇一個物件,再試一次。 </notification> <notification name="OnlyCopyContentsOfSingleItem"> - Unable to copy the contents of more than one item at a time. -Please select only one object and try again. + 無法一次複製多個物項的內容。 +請只選擇一個物件,再試一次。 <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="KickUsersFromRegion"> @@ -1216,66 +1306,66 @@ Please select only one object and try again. <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="EstateObjectReturn"> - Are you sure you want to return objects owned by [USER_NAME]? + 你確定要送返 [USER_NAME] 所擁有的物件? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="InvalidTerrainBitDepth"> - Couldn't set region textures: -Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. + 無法設定地區材質: +地形材質 [TEXTURE_NUM] 的位元深度 [TEXTURE_BIT_DEPTH] 無效。 -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +請將材質 [TEXTURE_NUM] 替換成 24 位元 512x512 或更小圖像,然後點按「套用」。 </notification> <notification name="InvalidTerrainSize"> - Couldn't set region textures: -Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. + 無法設定地區材質: +地形材質 [TEXTURE_NUM] 的尺寸 [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y] 太大。 -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +請將材質 [TEXTURE_NUM] 替換成 24 位元 512x512 或更小圖像,然後點按「套用」。 </notification> <notification name="RawUploadStarted"> - 上傳開始。將會花費約兩分鐘,這取決於你的連線速度。 + 上傳開始。 視你的連線速度而定,這最多需時兩分鐘。 </notification> <notification name="ConfirmBakeTerrain"> - Do you really want to bake the current terrain, make it the center for terrain raise/lower limits and the default for the 'Revert' tool? + 你真的要確定產出目前地形,使其成為地形升/降極限的中間值,並設為「復原」工具的預設值? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="MaxAllowedAgentOnRegion"> - You can only have [MAX_AGENTS] Allowed Residents. + 你最多只能有 [MAX_AGENTS] 位允許居民。 </notification> <notification name="MaxBannedAgentsOnRegion"> 你只可以有最多 [MAX_BANNED] 位被封鎖的居民。 </notification> <notification name="MaxAgentOnRegionBatch"> - Failure while attempting to add [NUM_ADDED] agents: -Exceeds the [MAX_AGENTS] [LIST_TYPE] limit by [NUM_EXCESS]. + 試圖增加 [NUM_ADDED] 人時失敗: +超過人數上限 [MAX_AGENTS] [LIST_TYPE](超過 [NUM_EXCESS] 人)。 </notification> <notification name="MaxAllowedGroupsOnRegion"> - You can only have [MAX_GROUPS] Allowed Groups. - <usetemplate name="okcancelbuttons" notext="取消" yestext="Bake"/> + 你只能有 [MAX_GROUPS] 個允許的群組。 + <usetemplate name="okcancelbuttons" notext="取消" yestext="確定產出"/> </notification> <notification name="MaxManagersOnRegion"> 你只可以有最多 [MAX_MANAGER] 位領地經理。 </notification> <notification name="OwnerCanNotBeDenied"> - 無法添加領地擁有者到領地的 '被封鎖的居民' 名單中。 + 無法添加領地所有人到領地的 '被封鎖的居民' 名單中。 </notification> <notification name="CanNotChangeAppearanceUntilLoaded"> 無法變更外觀,直到服裝與體形下載完畢。 </notification> <notification name="ClassifiedMustBeAlphanumeric"> - The name of your classified must start with a letter from A to Z or a number. No punctuation is allowed. + 你的個人廣告名稱必須以 A-Z 字母或數字開頭。 不允許標點符號。 </notification> <notification name="CantSetBuyObject"> - Can't set Buy Object, because the object is not for sale. -Please set the object for sale and try again. + 無法設定購買物件,該物件無法出售。 +請選定出售物件,再試一次。 </notification> <notification name="FinishedRawDownload"> - Finished download of raw terrain file to: -[DOWNLOAD_PATH]. + 原始地形檔案下載完成: +[DOWNLOAD_PATH]。 </notification> <notification name="DownloadWindowsMandatory"> - 一個新版本的 [APP_NAME] 已經可用。 + 有個新版本的 [APP_NAME] 可供使用。 [MESSAGE] -你必須下載這個更新以使用 [APP_NAME]。 +你必須下載這個更新才可使用 [APP_NAME]。 <usetemplate name="okcancelbuttons" notext="結束退出" yestext="下載"/> </notification> <notification name="DownloadWindows"> @@ -1285,89 +1375,86 @@ Please set the object for sale and try again. <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadWindowsReleaseForDownload"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] 更新過的版本已經可用。 [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadLinuxMandatory"> - A new version of [APP_NAME] is available. + 有個新版本的 [APP_NAME] 可供使用。 [MESSAGE] -You must download this update to use [APP_NAME]. +你必須下載這個更新才可使用 [APP_NAME]。 <usetemplate name="okcancelbuttons" notext="結束退出" yestext="下載"/> </notification> <notification name="DownloadLinux"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] 更新過的版本已經可用。 [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadLinuxReleaseForDownload"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] 更新過的版本已經可用。 [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadMacMandatory"> - A new version of [APP_NAME] is available. + 有個新版本的 [APP_NAME] 可供使用。 [MESSAGE] -You must download this update to use [APP_NAME]. +你必須下載這個更新才可使用 [APP_NAME]。 -Download to your Applications folder? +下載到 Applications 資料夾? <usetemplate name="okcancelbuttons" notext="結束退出" yestext="下載"/> </notification> <notification name="DownloadMac"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] 更新過的版本已經可用。 [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 -Download to your Applications folder? +下載到 Applications 資料夾? <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="DownloadMacReleaseForDownload"> - An updated version of [APP_NAME] is available. + 一個 [APP_NAME] 更新過的版本已經可用。 [MESSAGE] -This update is not required, but we suggest you install it to improve performance and stability. +這個更新並非強制更新,但我們建議你安裝以增強效能及穩定性。 -Download to your Applications folder? +下載到 Applications 資料夾? <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> </notification> <notification name="FailedUpdateInstall"> - An error occurred installing the viewer update. -Please download and install the latest viewer from -http://secondlife.com/download. + 安裝更新版 Viewer 時出錯。 +請到 http://secondlife.com/download 下載並安裝最新版 Viewer。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="FailedRequiredUpdateInstall"> - We were unable to install a required update. -You will be unable to log in until [APP_NAME] has been updated. + 無法安裝必要的更新。 +除非 [APP_NAME] 更新,你將無法登入。 -Please download and install the latest viewer from -http://secondlife.com/download. +請到 http://secondlife.com/download 下載並安裝最新版 Viewer。 <usetemplate name="okbutton" yestext="結束退出"/> </notification> <notification name="UpdaterServiceNotRunning"> - There is a required update for your Second Life Installation. + 你已安裝的第二人生軟體現有一個必要的更新。 -You may download this update from http://www.secondlife.com/downloads -or you can install it now. +你可以到 http://www.secondlife.com/downloads 下載此更新,或者現在立即安裝。 <usetemplate name="okcancelbuttons" notext="結束退出第二人生" yestext="立即下載及安裝"/> </notification> <notification name="DownloadBackgroundTip"> - We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] + 我們已為你的 [APP_NAME] 軟體下載了更新。 +[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] 關於此更新的資訊] <usetemplate name="okcancelbuttons" notext="稍候..." yestext="立即安裝及重新啟動 [APP_NAME]"/> </notification> <notification name="DownloadBackgroundDialog"> - We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] - <usetemplate name="okcancelbuttons" notext="梢候..." yestext="立即安裝及重新啟動 [APP_NAME]"/> + 我們已為你的 [APP_NAME] 軟體下載了更新。 +[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] 關於此更新的資訊] + <usetemplate name="okcancelbuttons" notext="稍候..." yestext="立即安裝及重新啟動 [APP_NAME]"/> </notification> <notification name="RequiredUpdateDownloadedVerboseDialog"> - We have downloaded a required software update. -Version [VERSION] + 我們已下載了一個必要的軟體更新。 +版本:[VERSION] -We must restart [APP_NAME] to install the update. +我門必須重新啟動 [APP_NAME] 以安裝更新。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="RequiredUpdateDownloadedDialog"> @@ -1375,8 +1462,8 @@ We must restart [APP_NAME] to install the update. <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="DeedObjectToGroup"> - Deeding this object will cause the group to: -* Receive L$ paid into the object + 讓渡此物件將可讓這個群組: +* 收取付給此物件的 L$ <usetemplate ignoretext="在我讓渡一個物件給群組前確認" name="okcancelignore" notext="取消" yestext="讓渡"/> </notification> <notification name="WebLaunchExternalTarget"> @@ -1388,7 +1475,7 @@ We must restart [APP_NAME] to install the update. <usetemplate ignoretext="啟動我的瀏覽器以管理我的帳戶" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="WebLaunchSecurityIssues"> - Visit the [SECOND_LIFE] Wiki for details of how to report a security issue. + 造訪 [SECOND_LIFE] 維基察看如何提報安全問題。 <usetemplate ignoretext="開啟我的網頁瀏覽器以學習如何回報一個安全性的議題" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="WebLaunchQAWiki"> @@ -1412,10 +1499,10 @@ We must restart [APP_NAME] to install the update. <usetemplate ignoretext="開啟我的網頁瀏覽器以察看 LSL 入口" name="okcancelignore" notext="取消" yestext="前往頁面"/> </notification> <notification name="ReturnToOwner"> - 你確定要退回所選擇的物件給它們的擁有者嗎? 可轉移並讓渡的物件將會退回給它們的前一位擁有者。 + 你確定要送返所選物件給物主? 可轉讓的已讓渡物件將送返原物主。 *警告* 非可轉移並讓渡的物件將會被刪除! - <usetemplate ignoretext="在我退回物件給它們的擁有者前確認" name="okcancelignore" notext="取消" yestext="確定"/> + <usetemplate ignoretext="在我退回物件給它們的所有人前確認" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="GroupLeaveConfirmMember"> 你目前是 <nolink>[GROUP]</nolink> 群組的成員。 @@ -1427,57 +1514,57 @@ We must restart [APP_NAME] to install the update. <usetemplate name="okcancelbuttons" notext="取消" yestext="踢出全部居民"/> </notification> <notification name="MuteLinden"> - Sorry, you cannot block a Linden. + 抱歉,你無法封鎖任何一位 Linden。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CannotStartAuctionAlreadyForSale"> - You cannot start an auction on a parcel which is already set for sale. Disable the land sale if you are sure you want to start an auction. + 你無法在已在出售中的地段裡進行拍賣。 你如果確定要拍賣,請先停止土地出售。 </notification> - <notification label="Block object by name failed" name="MuteByNameFailed"> - You already have blocked this name. + <notification label="依名稱封鎖物件失敗" name="MuteByNameFailed"> + 你已經封鎖了這個名稱。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="RemoveItemWarn"> - Though permitted, deleting contents may damage the object. Do you want to delete that item? + 雖然允許這麼做,刪除內容可能會破壞物件。 你要刪除該物項嗎? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="CantOfferCallingCard"> - Cannot offer a calling card at this time. Please try again in a moment. + 此時無法提供名片。 請稍候再試。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="CantOfferFriendship"> - Cannot offer friendship at this time. Please try again in a moment. + 此時無法發出交友邀請。 請稍候再試。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="BusyModeSet"> - Busy mode is set. -Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash. + 已設為忙碌模式。 +聊天和即時訊息內容將被隱藏。 即時訊息發送者將收到你的「忙碌模式」回應。 所有的瞬間傳送邀請都將被婉拒。 此時起送給你的收納區物項都將丟入垃圾桶。 <usetemplate ignoretext="我變更我的狀態為忙碌模式" name="okignore" yestext="確定"/> </notification> <notification name="JoinedTooManyGroupsMember"> - You have reached your maximum number of groups. Please leave another group before joining this one, or decline the offer. -[NAME] has invited you to join a group as a member. + 你已達可同時加入的群組數上限。 請先離開另一個群組再加入這一個,或婉拒加入邀請。 +[NAME] 已邀請你加入一個群組成為一員。 <usetemplate name="okcancelbuttons" notext="謝絕" yestext="加入"/> </notification> <notification name="JoinedTooManyGroups"> - You have reached your maximum number of groups. Please leave some group before joining or creating a new one. + 你已達可同時加入的群組數上限。 請先離開某些群組再加入或新建新群組。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="KickUser"> 踢出這個居民並留給他什麼訊息? <form name="form"> <input name="message"> - An administrator has logged you off. + 一位管理員已迫使你登出。 </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> <notification name="KickAllUsers"> - Kick everyone currently on the grid with what message? + 踢出網格上的每個人,留給他們什麼訊息? <form name="form"> <input name="message"> - An administrator has logged you off. + 一位管理員已迫使你登出。 </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> @@ -1487,7 +1574,7 @@ Chat and instant messages will be hidden. Instant messages will get your Busy mo 凍結這位居民時同時留下什麼訊息? <form name="form"> <input name="message"> - 你已經被凍結了。你將不能移動或聊天。管理員將會以即時訊息聯繫你(IM)。 + 你已被凍結。 你無法移動或聊天。 會有管理員透過即時訊息 IM 和你聯絡。 </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> @@ -1497,75 +1584,80 @@ Chat and instant messages will be hidden. Instant messages will get your Busy mo 將這位居民解凍並同時留下什麼訊息? <form name="form"> <input name="message"> - You are no longer frozen. + 你已被解除凍結。 </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> <notification name="SetDisplayNameSuccess"> - Hi [DISPLAY_NAME]! + [DISPLAY_NAME],你好! -Just like in real life, it takes a while for everyone to learn about a new name. Please allow several days for [http://wiki.secondlife.com/wiki/Setting_your_display_name your name to update] in objects, scripts, search, etc. +瞭解適應一個新名字是需要時間的,正如現實生活那樣。 請給我們幾天時間針對所有物件、腳本、搜尋等方面 [http://wiki.secondlife.com/wiki/Setting_your_display_name 更新你的名字]。 </notification> <notification name="SetDisplayNameBlocked"> - 抱歉,你不可以變更你的顯示名稱。如果你覺得這是錯誤,請連繫支援廠商。 + 抱歉,你無法更改你的顯示名。 如你認為有出錯,請聯絡支援人員。 </notification> <notification name="SetDisplayNameFailedLength"> - 抱歉,這名稱太長。顯示名稱最大長度為 [LENGTH] 字元。 + 抱歉,該名稱太長。 顯示名稱最大長度為 [LENGTH] 字元。 請嘗試短一些的名稱。 </notification> <notification name="SetDisplayNameFailedGeneric"> - Sorry, we could not set your display name. Please try again later. + 抱歉,我們無法設定你的顯示名。 請稍候再試一次。 </notification> <notification name="SetDisplayNameMismatch"> - The display names you entered do not match. Please re-enter. + 你所輸入的顯示名不相符。 請再輸入一次。 </notification> <notification name="AgentDisplayNameUpdateThresholdExceeded"> - Sorry, you have to wait longer before you can change your display name. + 抱歉,你必須再等一段時間才能更改你的顯示名。 -See http://wiki.secondlife.com/wiki/Setting_your_display_name +參見 http://wiki.secondlife.com/wiki/Setting_your_display_name -Please try again later. +請稍候再試一次。 </notification> <notification name="AgentDisplayNameSetBlocked"> - Sorry, we could not set your requested name because it contains a banned word. + 抱歉,我們無法設定你想要的名稱,它含有禁用字眼。 - Please try a different name. + 請用不同的名稱試試。 </notification> <notification name="AgentDisplayNameSetInvalidUnicode"> - The display name you wish to set contains invalid characters. + 你希望設定的顯示名含有無效字元。 </notification> <notification name="AgentDisplayNameSetOnlyPunctuation"> - Your display name must contain letters other than punctuation. + 你的顯示名必須包含非標點符號的字元。 </notification> <notification name="DisplayNameUpdate"> - [OLD_NAME] ([SLID]) is now known as [NEW_NAME]. + [OLD_NAME] ([SLID]) 現在有了新名字 [NEW_NAME]。 </notification> <notification name="OfferTeleport"> - Offer a teleport to your location with the following message? + 用下列訊息發出瞬間傳送邀請來到你的位置? <form name="form"> <input name="message"> - 加入我到 [REGION] + 在 [REGION] 和我會面 </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> + <notification name="TooManyTeleportOffers"> + 你試圖送出 [OFFERS] 個瞬間傳送邀請。 +超過了 [LIMIT] 個的上限。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="OfferTeleportFromGod"> - God summon Resident to your location? + 用神的權力把居民召到你的位置? <form name="form"> <input name="message"> - Join me in [REGION] + 在 [REGION] 和我會面 </input> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> <notification name="TeleportFromLandmark"> - Are you sure you want to teleport to <nolink>[LOCATION]</nolink>? - <usetemplate ignoretext="Confirm that I want to teleport to a landmark" name="okcancelignore" notext="取消" yestext="瞬間傳送"/> + 你確定要瞬間傳送到<nolink>[LOCATION]</nolink>? + <usetemplate ignoretext="確認我要瞬間傳送到某個地標" name="okcancelignore" notext="取消" yestext="瞬間傳送"/> </notification> <notification name="TeleportToPick"> 瞬間傳送到 [PICK]? @@ -1580,57 +1672,57 @@ Please try again later. <usetemplate ignoretext="確認我要瞬間傳送到歷史紀錄中的位置" name="okcancelignore" notext="取消" yestext="瞬間傳送"/> </notification> <notification label="送出訊息給你領地內的每一個人" name="MessageEstate"> - Type a short announcement which will be sent to everyone currently in your estate. + 輸入簡短公告,公告將發送給領地裡所有人。 <form name="form"> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> - <notification label="Change Linden Estate" name="ChangeLindenEstate"> - You are about to change a Linden owned estate (mainland, teen grid, orientation, etc.). + <notification label="更改 Linden 領地" name="ChangeLindenEstate"> + 你即將更改一個 Linden 所擁有的領地(大陸、青少年網格、導引區等)。 -This is EXTREMELY DANGEROUS because it can fundamentally affect the Resident experience. On the mainland, it will change thousands of regions and make the spaceserver hiccup. +這動作非常危險,它會根本影響所有居民的體驗。 在大陸上,它將更動數千個地區,導致空間伺服器發生不順。 -Proceed? +繼續? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> - <notification label="Change Linden Estate Access" name="ChangeLindenAccess"> - You are about to change the access list for a Linden owned estate (mainland, teen grid, orientation, etc.). + <notification label="更改 Linden 領地出入權" name="ChangeLindenAccess"> + 你即將更改一個 Linden 所擁有領地(大陸、青少年網格、導引區等)的出入權。 -This is DANGEROUS and should only be done to invoke the hack allowing objects/L$ to be transfered in/out of a grid. -It will change thousands of regions and make the spaceserver hiccup. +這動作很危險,只在需要把物件或 L$ 送出或送入網格,又無更好方法時不得已使用。 +它將更動數千個地區,導致空間伺服器發生不順。 <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification label="選擇領地" name="EstateAllowedAgentAdd"> - Add to allowed list for this estate only or for [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 將它新增到允許清單? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="選擇領地" name="EstateAllowedAgentRemove"> - Remove from allowed list for this estate only or for [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 將它從允許清單中移除? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="選擇領地" name="EstateAllowedGroupAdd"> - Add to group allowed list for this estate only or for [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 將它新增到群組允許清單? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="選擇領地" name="EstateAllowedGroupRemove"> - Remove from group allowed list for this estate only or [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 將它從群組允許清單中移除? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="選擇領地" name="EstateBannedAgentAdd"> - Deny access for this estate only or for [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 禁止出入? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="選擇領地" name="EstateBannedAgentRemove"> - Remove this Resident from the ban list for access for this estate only or for [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 將這個居民從禁止出入清單中除名? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="選擇領地" name="EstateManagerAdd"> - Add estate manager for this estate only or for [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 新增領地管理人? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="選擇領地" name="EstateManagerRemove"> - Remove estate manager for this estate only or for [ALL_ESTATES]? + 僅針對這個領地或針對 [ALL_ESTATES] 移除領地管理人? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/> </notification> <notification label="確認踢出" name="EstateKickUser"> @@ -1638,251 +1730,295 @@ It will change thousands of regions and make the spaceserver hiccup. <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="EstateChangeCovenant"> - Are you sure you want to change the Estate Covenant? + 你確定要更改領地契約? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="RegionEntryAccessBlocked"> - You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + 你所欲前往的地區含有超過你目前偏好的分級的內容。 你可以到「我自己 > 偏好設定 > 一般設定」變更你的偏好設定。 <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="RegionEntryAccessBlocked_KB"> - You are not allowed in that region due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + <notification name="RegionEntryAccessBlocked_AdultsOnlyContent"> + 你所欲前往的地區含有 [REGIONMATURITY] 的分級內容,僅限成人。 <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="I can't enter this Region, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + <usetemplate ignoretext="跨越地區:你所欲前往的地區含有限制給成人的內容。" name="okcancelignore" notext="關閉" yestext="前往知識庫"/> </notification> <notification name="RegionEntryAccessBlocked_Notify"> - You are not allowed in that region due to your maturity Rating. + 你所欲前往的地區包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly"> + 你所欲前往的地區含有 [REGIONMATURITY] 的分級內容,僅限成人。 </notification> <notification name="RegionEntryAccessBlocked_Change"> - You are not allowed in that Region due to your maturity Rating preference. - -To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me > Preferences > General. + 你所欲前往的地區包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 你可以變更你的偏好設定,或取消前往。 你的偏好設定變更後,你可以試圖再進入該地區。 <form name="form"> - <button name="OK" text="Change Preference"/> - <button name="Cancel" text="Close"/> - <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/> + <button name="OK" text="變更偏好設定"/> + <button name="Cancel" text="取消"/> + <ignore name="ignore" text="跨越地區:你所欲前往的地區含有被你目前的偏好設定排除的分級內容。"/> </form> </notification> + <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync"> + 發生技術問題,你的偏好設定和伺服器上的不一致。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="TeleportEntryAccessBlocked"> + 你所欲前往的地區含有超過你目前偏好的分級的內容。 你可以到「我自己 > 偏好設定 > 一般設定」變更你的偏好設定。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent"> + 你所欲前往的地區含有 [REGIONMATURITY] 的分級內容,僅限成人。 + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="瞬間傳送:你所欲前往的地區含有限制給成人的內容。" name="okcancelignore" notext="關閉" yestext="前往知識庫"/> + </notification> + <notification name="TeleportEntryAccessBlocked_Notify"> + 你所欲前往的地區包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly"> + 你所欲前往的地區含有 [REGIONMATURITY] 的分級內容,僅限成人。 + </notification> + <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport"> + 你所欲前往的地區包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 我們可以變更你的偏好設定好讓你繼續瞬間傳送,你也可取消這動作。 + <form name="form"> + <button name="OK" text="變更後繼續"/> + <button name="Cancel" text="取消"/> + <ignore name="ignore" text="瞬間傳送(可重啟):你所欲前往的地區含有被你目前的偏好設定排除的分級內容。"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_Change"> + 你所欲前往的地區包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 我們可以變更你的偏好設定,你也可取消瞬間傳送。 你的偏好設定變更後,你可以再嘗試瞬間傳送。 + <form name="form"> + <button name="OK" text="變更偏好設定"/> + <button name="Cancel" text="取消"/> + <ignore name="ignore" text="瞬間傳送(不可重啟):你所欲前往的地區含有被你目前的偏好設定排除的分級內容。"/> + </form> + </notification> + <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync"> + 發生技術問題,你的偏好設定和伺服器上的不一致。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="PreferredMaturityChanged"> - Your maturity Rating preference is now [RATING]. + 你將不再收到通知,告知你即將進入一個 [RATING] 內容分級的地區。 你可以到選單列底下的「我自己 > 偏好設定 > 一般設定」變更你的內容偏好。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="MaturityChangeError"> + 我們此時無法變更你的偏好設定,讓你觀看 [PREFERRED_MATURITY] 分級的內容。 你的偏好設定已經重設,可觀看 [ACTUAL_MATURITY] 的分級內容。 你可以到選單列的「我自己 > 偏好設定 > 一般設定」再次變更你的偏好。 + <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="LandClaimAccessBlocked"> - You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + 你所欲收取的土地含有超過你目前偏好的分級內容。 你可以到「我自己 > 偏好設定 > 一般設定」變更你的偏好設定。 <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="LandClaimAccessBlocked_KB"> - You cannot claim this land due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + <notification name="LandClaimAccessBlocked_AdultsOnlyContent"> + 只有成人才能收取這土地。 <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="I can't claim this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + <usetemplate ignoretext="只有成人才能收取這土地。" name="okcancelignore" notext="關閉" yestext="前往知識庫"/> </notification> <notification name="LandClaimAccessBlocked_Notify"> - You cannot claim this land due to your maturity Rating. + 你所欲收取的土地包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="LandClaimAccessBlocked_NotifyAdultsOnly"> + 你所欲收取的土地包含 [REGIONMATURITY] 的分級內容,僅限成人。 </notification> <notification name="LandClaimAccessBlocked_Change"> - You cannot claim this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. - <usetemplate ignoretext="My chosen Rating preference prevents me from claiming Land" name="okcancelignore" notext="關閉" yestext="Change Preference"/> + 你所欲收取的土地包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 我們可以變更你的偏好,讓你再試圖收取土地。 + <form name="form"> + <button name="OK" text="變更偏好設定"/> + <button name="Cancel" text="取消"/> + <ignore name="ignore" text="你所欲收取的土地含有被你目前的偏好所排除的分級內容。"/> + </form> </notification> <notification name="LandBuyAccessBlocked"> - You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + 你所欲購買的土地的內容分級超過你目前所設偏好。 你可以到「我自己 > 偏好設定 > 一般設定」變更你的偏好設定。 <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="LandBuyAccessBlocked_KB"> - You cannot buy this land due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + <notification name="LandBuyAccessBlocked_AdultsOnlyContent"> + 只有成人才能購買這土地。 <url name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> - <usetemplate ignoretext="I can't buy this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + <usetemplate ignoretext="只有成人才能購買這土地。" name="okcancelignore" notext="關閉" yestext="前往知識庫"/> </notification> <notification name="LandBuyAccessBlocked_Notify"> - You cannot buy this land due to your maturity Rating. + 你所欲購買的土地包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 + </notification> + <notification name="LandBuyAccessBlocked_NotifyAdultsOnly"> + 你所欲購買的土地含有 [REGIONMATURITY] 分級的內容,僅限成人。 </notification> <notification name="LandBuyAccessBlocked_Change"> - You cannot buy this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. - <usetemplate ignoretext="My chosen Rating preference prevents me from buying Land" name="okcancelignore" notext="關閉" yestext="變更偏好設定"/> + 你所欲購買的土地包含 [REGIONMATURITY] 分級的內容,可是你目前的偏好設定排除了 [REGIONMATURITY] 分級的內容。 我們可以變更你的偏好,讓你再試圖購買土地。 + <form name="form"> + <button name="OK" text="變更偏好設定"/> + <button name="Cancel" text="取消"/> + <ignore name="ignore" text="你所欲購買的土地含有被你目前的偏好所排除的分級內容。"/> + </form> </notification> <notification name="TooManyPrimsSelected"> - There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again + 選擇了太多項的幾何元件。 請至多選擇 [MAX_PRIM_COUNT] 項幾何元件,再試一次。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="ProblemImportingEstateCovenant"> - Problem importing estate covenant. + 匯入領地契約時出問題。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="ProblemAddingEstateManager"> - Problems adding a new estate manager. One or more estates may have a full manager list. + 新增領地管理人時出問題。 其中一個領地的管理人清單可能已經額滿。 </notification> <notification name="ProblemAddingEstateGeneric"> - Problems adding to this estate list. One or more estates may have a full list. + 新增到這個領地清單時出問題。 其中一個領地的清單可能已滿。 </notification> <notification name="UnableToLoadNotecardAsset"> - Unable to load notecard's asset at this time. + 此刻無法載入記事卡資產。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="NotAllowedToViewNotecard"> - Insufficient permissions to view notecard associated with asset ID requested. + 權限不足無法察看此資產編號的記事卡。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="MissingNotecardAssetID"> - Asset ID for notecard is missing from database. + 記事卡的資產編號在資料庫中找不到。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="PublishClassified"> - Remember: Classified ad fees are non-refundable. + 請注意:個人廣告刊登費恕不退還。 -Publish this classified now for L$[AMOUNT]? +支付 L$ [AMOUNT] 刊載這則個人廣告? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="SetClassifiedMature"> - Does this classified contain Moderate content? + 這則個人廣告是否含適度成人分級的內容? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="否" yestext="是"/> </notification> <notification name="SetGroupMature"> 這個群組將包含適度成人內容? <usetemplate canceltext="取消" name="yesnocancelbuttons" notext="否" yestext="是"/> </notification> - <notification label="Confirm restart" name="ConfirmRestart"> - Do you really want to restart this region in 2 minutes? + <notification label="確定重新啟動" name="ConfirmRestart"> + 你確定要在 2 分鐘後重新啟動這個地區? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> - <notification label="Message everyone in this region" name="MessageRegion"> - Type a short announcement which will be sent to everyone in this region. + <notification label="對地區裡每個人發出訊息" name="MessageRegion"> + 輸入簡短公告,公告將發送給地區裡所有人。 <form name="form"> <button name="OK" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> - <notification label="Changed Region Maturity" name="RegionMaturityChange"> - The maturity rating for this region has been updated. -It may take some time for the change to be reflected on the map. - -To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification. + <notification label="已變更地區的內容分級" name="RegionMaturityChange"> + 此地區的內容分級已經變更。 +可能需要稍候一段時間,地圖才會反映這個變更。 + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification label="Voice Version Mismatch" name="VoiceVersionMismatch"> - This version of [APP_NAME] is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update [APP_NAME]. + <notification label="聲音版本不相符" name="VoiceVersionMismatch"> + 這版本的 [APP_NAME] 和本地區的語音聊天功能不相容。 想要語音聊天正常運作,你必須更新 [APP_NAME]。 </notification> <notification label="無法購買物件" name="BuyObjectOneOwner"> - Cannot buy objects from different owners at the same time. -Please select only one object and try again. + 無法同時向不同物主購買物件。 +請只選擇一個物件,再試一次。 </notification> <notification label="無法購買內容物" name="BuyContentsOneOnly"> - Unable to buy the contents of more than one object at a time. -Please select only one object and try again. + 無法一次購買多個物件的內容。 +請只選擇一個物件,再試一次。 </notification> <notification label="無法購買內容物" name="BuyContentsOneOwner"> - Cannot buy objects from different owners at the same time. -Please select only one object and try again. + 無法同時向不同物主購買物件。 +請只選擇一個物件,再試一次。 </notification> <notification name="BuyOriginal"> - Buy original object from [OWNER] for L$[PRICE]? -You will become the owner of this object. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + 向 [OWNER] 支付 L$[PRICE],購買原版物件? +你將成為這物件的所有人。 +你將可以: + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或送人:[RESELLPERM] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BuyOriginalNoOwner"> - Buy original object for L$[PRICE]? -You will become the owner of this object. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + 支付 L$[PRICE] 購買原版物件? +你將成為這物件的所有人。 +你將可以: + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或送人:[RESELLPERM] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BuyCopy"> - Buy a copy from [OWNER] for L$[PRICE]? -The object will be copied to your inventory. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + 向 [OWNER] 支付 L$[PRICE],購買複製物件? +這物件將複製到你的收納區。 +你將可以: + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或送人:[RESELLPERM] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BuyCopyNoOwner"> - Buy a copy for L$[PRICE]? -The object will be copied to your inventory. -You will be able to: - Modify: [MODIFYPERM] - Copy: [COPYPERM] - Resell or Give Away: [RESELLPERM] + 支付 L$[PRICE] 購買複製物件? +這物件將複製到你的收納區。 +你將可以: + 修改:[MODIFYPERM] + 複製:[COPYPERM] + 轉售或送人:[RESELLPERM] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BuyContents"> - Buy contents from [OWNER] for L$[PRICE]? -They will be copied to your inventory. + 向 [OWNER] 支付 L$[PRICE] 購買內容? +內容將複製到你的收納區。 <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BuyContentsNoOwner"> - Buy contents for L$[PRICE]? -They will be copied to your inventory. + 支付 L$[PRICE] 購買內容? +內容將複製到你的收納區。 <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmPurchase"> - This transaction will: + 這項交易將會: [ACTION] -Are you sure you want to proceed with this purchase? +你確定要購買? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmPurchasePassword"> - This transaction will: + 這項交易將會: [ACTION] -Are you sure you want to proceed with this purchase? -Please re-enter your password and click OK. +你確定要購買? +請重新輸入密碼再點按確定。 <form name="form"> <button name="ConfirmPurchase" text="確定"/> <button name="Cancel" text="取消"/> </form> </notification> <notification name="SetPickLocation"> - Note: -You have updated the location of this pick but the other details will retain their original values. + 附註: +你已經更新這個精選地點的地點細節,其他細節將保留原內容。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="MoveInventoryFromObject"> - You have selected 'no copy' inventory items. -These items will be moved to your inventory, not copied. + 你選擇了「禁止複製」的收納區物項。 +這些物項將被移到你的收納區,不會被複製。 -Move the inventory item(s)? - <usetemplate ignoretext="Warn me before I move 'no-copy' items from an object" name="okcancelignore" notext="取消" yestext="確定"/> +要移動收納區物項嗎? + <usetemplate ignoretext="在我從物件中移動「禁止複製」物項之前警告我" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="MoveInventoryFromScriptedObject"> - You have selected 'no copy' inventory items. These items will be moved to your inventory, not copied. -Because this object is scripted, moving these items to your inventory may cause the script to malfunction. + 你選擇了「禁止複製」的收納區物項。 這些物項將被移到你的收納區,不會被複製。 +由於這物件帶有腳本,移動這些物項到收納區可能會導致腳本運作不正常。 -Move the inventory item(s)? - <usetemplate ignoretext="Warn me before I move 'no-copy' items which might break a scripted object" name="okcancelignore" notext="取消" yestext="確定"/> +要移動收納區物項嗎? + <usetemplate ignoretext="在我移動可能破壞帶腳本物件的「禁止複製」物項之前警告我" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="ClickActionNotPayable"> - Warning: The 'Pay object' click action has been set, but it will only work if a script is added with a money() event. + 警告:「支付物件」點按動作已設定,但新增的腳本必須含有 money() 事件,該動作才有作用。 <form name="form"> - <ignore name="ignore" text="I set the action 'Pay object' when building an object without a money() script"/> + <ignore name="ignore" text="我在創建不含 money() 腳本的物件時設定了「支付物件」動作"/> </form> </notification> <notification name="OpenObjectCannotCopy"> - There are no items in this object that you are allowed to copy. + 這物件中沒有任何准許你複製的物項。 </notification> <notification name="WebLaunchAccountHistory"> 前往你的[http://secondlife.com/account/ 塗鴉牆]以察看你的帳戶歷史紀錄? @@ -1892,58 +2028,70 @@ Move the inventory item(s)? 你確定你要結束退出? <usetemplate ignoretext="當我結束退出時進行確認" name="okcancelignore" notext="不要結束退出" yestext="結束退出"/> </notification> + <notification name="ConfirmRestoreToybox"> + 這動作將會恢復你預設的按鈕和工具列。 + +你不能取消這動作。 + <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> + </notification> + <notification name="ConfirmClearAllToybox"> + 這動作將把所有按鈕收入工具箱,你的工具列將會清空。 + +你不能取消這動作。 + <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> + </notification> <notification name="DeleteItems"> [QUESTION] <usetemplate ignoretext="刪除物品前確認" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="HelpReportAbuseEmailLL"> - Use this tool to report violations of the [http://secondlife.com/corporate/tos.php Terms of Service] and [http://secondlife.com/corporate/cs.php Community Standards]. + 使用這個工具舉報任何違反[http://secondlife.com/corporate/tos.php 服務條款]和[http://secondlife.com/corporate/cs.php 社群準則]的情事。 -All reported abuses are investigated and resolved. +所有舉報的違規事件都有人調查,加以解決。 </notification> <notification name="HelpReportAbuseSelectCategory"> - Please select a category for this abuse report. -Selecting a category helps us file and process abuse reports. + 請選擇適合這次違規舉報的類別。 +選對類別可以幫助我們歸類並處理違規舉報。 </notification> <notification name="HelpReportAbuseAbuserNameEmpty"> - Please enter the name of the abuser. -Entering an accurate value helps us file and process abuse reports. + 請輸入違規人的名字。 +輸入準確的內容可以幫助我們歸類並處理違規舉報。 </notification> <notification name="HelpReportAbuseAbuserLocationEmpty"> - Please enter the location where the abuse took place. -Entering an accurate value helps us file and process abuse reports. + 請輸入違規情事發生地點。 +輸入準確的內容可以幫助我們歸類並處理違規舉報。 </notification> <notification name="HelpReportAbuseSummaryEmpty"> - Please enter a summary of the abuse that took place. -Entering an accurate summary helps us file and process abuse reports. + 請概述違規情事。 +準確的概述可以幫助我們歸類並處理違規舉報。 </notification> <notification name="HelpReportAbuseDetailsEmpty"> - Please enter a detailed description of the abuse that took place. -Be as specific as you can, including names and the details of the incident you are reporting. -Entering an accurate description helps us file and process abuse reports. + 請詳述違規情事。 +請儘可能提供具體詳情,包括你要舉報的案情細節和涉案的名稱。 +準確的詳述可以幫助我們歸類並處理違規舉報。 </notification> <notification name="HelpReportAbuseContainsCopyright"> - Dear Resident, + 這位居民,你好: -You appear to be reporting intellectual property infringement. Please make sure you are reporting it correctly: +你似乎正在舉報有人侵犯智慧財產權。 請確定你舉報內容確鑿無誤: -(1) The Abuse Process. You may submit an abuse report if you believe a Resident is exploiting the [SECOND_LIFE] permissions system, for example, by using CopyBot or similar copying tools, to infringe intellectual property rights. The Abuse Team investigates and issues appropriate disciplinary action for behavior that violates the [SECOND_LIFE] [http://secondlife.com/corporate/tos.php Terms of Service] or [http://secondlife.com/corporate/cs.php Community Standards]. However, the Abuse Team does not handle and will not respond to requests to remove content from the [SECOND_LIFE] world. +(1) 違規舉報處理程序。 你若相信有居民利用 [SECOND_LIFE] 權限遂行侵犯智慧財產權,如使用複製機器程式碼(CopyBot)或其他類似複製工具,得以舉報此情事。 違規處理小組會就任何違反[SECOND_LIFE][http://secondlife.com/corporate/tos.php 服務條款]或[http://secondlife.com/corporate/cs.php 社群準則]的行為展開調查,並採取適當處置。 然而,違規處理小組並不受理要求將某內容自[SECOND_LIFE]虛擬世界刪除,這類要求將不予回應。 -(2) The DMCA or Content Removal Process. To request removal of content from [SECOND_LIFE], you MUST submit a valid notification of infringement as provided in our [http://secondlife.com/corporate/dmca.php DMCA Policy]. +(2) DMCA(刪除內容作業程序)。 若欲要求刪除[SECOND_LIFE]內容,你必須按照[http://secondlife.com/corporate/dmca.php DMCA 政策]提出有效的侵權通知。 -If you still wish to continue with the abuse process, please close this window and finish submitting your report. You may need to select the specific category 'CopyBot or Permissions Exploit'. +如果你仍希望繼續,請關閉此視窗,完成舉報。 你可能需要選擇「CopyBot 或濫用權限」這一具體類別。 -Thank you, +謝謝你, -Linden Lab +林登實驗室謹上 </notification> <notification name="FailedRequirementsCheck"> - The following required components are missing from [FLOATER]: + [FLOATER] 裡找不到下列必要元件: [COMPONENTS] </notification> <notification label="取代現有的附件" name="ReplaceAttachment"> - There is already an object attached to this point on your body. -Do you want to replace it with the selected object? + 你身上的這個部位已經附著了物件。 +你要用所選物件將它取代嗎? <form name="form"> <ignore name="ignore" text="以所選擇的物品取代現有的附加物"/> <button ignore="自動取代" name="Yes" text="確定"/> @@ -1951,9 +2099,9 @@ Do you want to replace it with the selected object? </form> </notification> <notification label="忙碌模式警告" name="BusyModePay"> - You are in Busy Mode, which means you will not receive any items offered in exchange for this payment. + 你現在處於忙碌模式,這意味著你付費後仍將不會收到任何物項。 -Would you like to leave Busy Mode before completing this transaction? +你是否要先離開忙碌模式,再完成交易? <form name="form"> <ignore name="ignore" text="當我在忙碌模式時,將要支付金錢或給他人物件"/> <button ignore="總是離開忙碌模式" name="Yes" text="確定"/> @@ -1961,7 +2109,7 @@ Would you like to leave Busy Mode before completing this transaction? </form> </notification> <notification name="ConfirmDeleteProtectedCategory"> - 資料夾 '[FOLDERNAME]' 是系統資料夾。刪除系統資料夾將導致不穩定。你確定你要刪除它? + 「[FOLDERNAME]」屬於系統資料夾。 刪除系統資料夾可能導致系統不穩定。 你確定要加以刪除? <usetemplate ignoretext="在我刪除系統資料夾前確認" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="ConfirmEmptyTrash"> @@ -1972,6 +2120,10 @@ Would you like to leave Busy Mode before completing this transaction? 你確定要刪除你的旅行、網頁及搜尋歷史紀錄嗎? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> + <notification name="ConfirmClearCache"> + 確定要清除你 Viewer 的快取? + <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> + </notification> <notification name="ConfirmClearCookies"> 你確定要清除你的 cookies 嗎? <usetemplate name="okcancelbuttons" notext="取消" yestext="是"/> @@ -1988,7 +2140,7 @@ Would you like to leave Busy Mode before completing this transaction? 下列的 SLurl 位置已經覆製到你的剪貼簿上: [SLURL] -Link to this from a web page to give others easy access to this location, or try it out yourself by pasting it into the address bar of any web browser. +從某個網頁連結到這裡,讓其他人更容易知道這個地點,或請自行嘗試將它貼到任何網頁瀏覽器的地址欄裡。 <form name="form"> <ignore name="ignore" text="SLurl 已經覆製到我的剪貼簿。"/> </form> @@ -1997,48 +2149,30 @@ Link to this from a web page to give others easy access to this location, or try 你要覆寫已儲存的預設配置嗎? <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> - <notification name="WLDeletePresetAlert"> - 你要刪除 [SKY]? - <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> - </notification> <notification name="WLNoEditDefault"> - You cannot edit or delete a default preset. + 你不能編輯或刪除預設的設定。 </notification> <notification name="WLMissingSky"> - This day cycle file references a missing sky file: [SKY]. + 這個「一日循環」檔案參考了一個不存在的天空檔案:[SKY]。 </notification> - <notification name="PPSaveEffectAlert"> - PostProcess Effect exists. Do you still wish overwrite it? - <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> + <notification name="WLRegionApplyFail"> + 抱歉,設定無法套用到地區。 離開地區再返回也許可以解決這個問題。 所得的原因為:[FAIL_REASON] </notification> - <notification name="NewSkyPreset"> - Give me a name for the new sky. - <form name="form"> - <input name="message"> - 新預設配配置 - </input> - <button name="OK" text="確定"/> - <button name="Cancel" text="取消"/> - </form> - </notification> - <notification name="ExistsSkyPresetAlert"> - Preset already exists! + <notification name="EnvCannotDeleteLastDayCycleKey"> + 無法刪除此日循環的最後一組設定,日循環不得為空白。 你應該修改最後一組資料,不要試圖刪除,然後再建立新的。 + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="NewWaterPreset"> - Give me a name for the new water preset. - <form name="form"> - <input name="message"> - New Preset - </input> - <button name="OK" text="確定"/> - <button name="Cancel" text="取消"/> - </form> + <notification name="DayCycleTooManyKeyframes"> + 你無法新增更多的 keyframe 到這個日循環。 [SCOPE] 範圍的日循環最多允許 [MAX] 個 keyframe。 + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="ExistsWaterPresetAlert"> - Preset already exists! + <notification name="EnvUpdateRate"> + 你至多只能每 [WAIT] 秒更新一次地區的環境設定。 請等到這段時間過去了再試一次。 + <usetemplate name="okbutton" yestext="確定"/> </notification> - <notification name="WaterNoEditDefault"> - You cannot edit or delete a default preset. + <notification name="PPSaveEffectAlert"> + PostProcess 效果已經存在。 你是否仍要把它覆寫掉? + <usetemplate name="okcancelbuttons" notext="否" yestext="是"/> </notification> <notification name="ChatterBoxSessionStartError"> 無法開始一個與 [RECIPIENT] 他的新聊天會話。 @@ -2056,10 +2190,10 @@ Link to this from a web page to give others easy access to this location, or try <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="Cannot_Purchase_an_Attachment"> - You can't buy an object while it is attached. + 你不能購買已附著的物件。 </notification> - <notification label="About Requests for the Debit Permission" name="DebitPermissionDetails"> - Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object. + <notification label="關於借記權限要求" name="DebitPermissionDetails"> + 若你同意這要求,將允許腳本從你的帳戶中重覆取走林登幣(L$)。 物件所有人必須刪除該物件,或重設物件裡的腳本,才能撤銷這一權限。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AutoWearNewClothing"> @@ -2067,25 +2201,23 @@ Link to this from a web page to give others easy access to this location, or try <usetemplate ignoretext="編輯外觀時能穿上我所創造的服裝" name="okcancelignore" notext="否" yestext="是"/> </notification> <notification name="NotAgeVerified"> - You must be age-verified to visit this area. Do you want to go to the [SECOND_LIFE] website and verify your age? - -[_URL] - <url name="url"> - https://secondlife.com/account/verification.php - </url> - <usetemplate ignoretext="I have not verified my age" name="okcancelignore" notext="否" yestext="是"/> + 你所欲前往的地點設限給年滿 18 歲的居民進入。 + <usetemplate ignoretext="我年齡不滿規定,無法進入有年齡限制的區域。" name="okignore" yestext="確定"/> + </notification> + <notification name="NotAgeVerified_Notify"> + 此地點限制為年滿 18 歲。 </notification> <notification name="Cannot enter parcel: no payment info on file"> - You must have payment information on file to visit this area. Do you want to go to the [SECOND_LIFE] website and set this up? + 你必須提供付款資料才能進入這區域。 你是否要前往 [SECOND_LIFE] 網站設定付款資料? [_URL] <url name="url"> https://secondlife.com/account/ </url> - <usetemplate ignoretext="I lack payment information on file" name="okcancelignore" notext="否" yestext="是"/> + <usetemplate ignoretext="我沒有預留付款資料。" name="okcancelignore" notext="否" yestext="是"/> </notification> <notification name="MissingString"> - The string [STRING_NAME] is missing from strings.xml + strings.xml 中找不到字串 [STRING_NAME] </notification> <notification name="SystemMessageTip"> [MESSAGE] @@ -2103,38 +2235,38 @@ Link to this from a web page to give others easy access to this location, or try 取消貼上 </notification> <notification name="ReplacedMissingWearable"> - Replaced missing clothing/body part with default. + 已用預設值補足空缺的衣服/身體部位。 </notification> <notification name="GroupNotice"> - Topic: [SUBJECT], Message: [MESSAGE] + 主旨:[SUBJECT],訊息:[MESSAGE] </notification> <notification name="FriendOnline"> - <nolink>[NAME]</nolink> 上線 + <nolink>[NAME]</nolink> 目前在線上 </notification> <notification name="FriendOffline"> - <nolink>[NAME]</nolink> 離線 + <nolink>[NAME]</nolink> 目前離線 </notification> <notification name="AddSelfFriend"> - Although you're very nice, you can't add yourself as a friend. + 雖然你人很好,你還是不能把自己加為朋友。 </notification> <notification name="UploadingAuctionSnapshot"> - Uploading in-world and web site snapshots... -(Takes about 5 minutes.) + 正在上傳虛擬世界和網站快照… +(需時約 5 分鐘。) </notification> <notification name="UploadPayment"> 你支付 L$[AMOUNT] 上傳。 </notification> <notification name="UploadWebSnapshotDone"> - Web site snapshot upload done. + 網站快照上傳完成。 </notification> <notification name="UploadSnapshotDone"> - In-world snapshot upload done + 虛擬世界快照上傳完成。 </notification> <notification name="TerrainDownloaded"> 地形 .raw 檔已下載 </notification> <notification name="GestureMissing"> - 嗯,姿勢 [NAME] 在資料庫中遺失。 + 姿勢 [NAME] 在資料庫中遺失。 </notification> <notification name="UnableToLoadGesture"> 無法載入姿勢 [NAME]。 @@ -2143,7 +2275,7 @@ Link to this from a web page to give others easy access to this location, or try 資料庫中的地標遺失。 </notification> <notification name="UnableToLoadLandmark"> - 無法載入地標,請再試一次。 + 無法載入地標。 請再試一次。 </notification> <notification name="CapsKeyOn"> 你的大寫鍵已啟用。 @@ -2158,6 +2290,12 @@ Link to this from a web page to give others easy access to this location, or try <notification name="RezItemNoPermissions"> 產生物件時發生權限衝突。 </notification> + <notification name="IMAcrossParentEstates"> + 無法對不同的母領地發出即時訊息。 + </notification> + <notification name="TransferInventoryAcrossParentEstates"> + 收納區無法轉移到不同的母領地。 + </notification> <notification name="UnableToLoadNotecard"> 無法載入記事卡。 請再試一次。 @@ -2169,28 +2307,28 @@ Link to this from a web page to give others easy access to this location, or try 察看腳本時發生權限衝突。 </notification> <notification name="UnableToLoadScript"> - 無法載入腳本。請再試一次。 + 無法載入腳本。 請再試一次。 </notification> <notification name="IncompleteInventory"> - The complete contents you are offering are not yet locally available. Please try offering those items again in a minute. + 你所提供的完整內容在本地還無法取得。 請幾分鐘後再試著提供這些物項。 </notification> <notification name="CannotModifyProtectedCategories"> - You cannot modify protected categories. + 你不能修改受保護的類別。 </notification> <notification name="CannotRemoveProtectedCategories"> - You cannot remove protected categories. + 你不能移除受保護的類別。 </notification> <notification name="UnableToBuyWhileDownloading"> - Unable to buy while downloading object data. -Please try again. + 正在下載物件資料,無法購買。 +請再試一次。 </notification> <notification name="UnableToLinkWhileDownloading"> - Unable to link while downloading object data. -Please try again. + 正在下載物件資料,無法聯結。 +請再試一次。 </notification> <notification name="CannotBuyObjectsFromDifferentOwners"> - You can only buy objects from one owner at a time. -Please select a single object. + 你一次只能向一位物主購買物件。 +請選擇一個單一物件。 </notification> <notification name="ObjectNotForSale"> 這物件不出售。 @@ -2211,7 +2349,7 @@ Please select a single object. [NAME] 謝絕你提供的收納區物品。 </notification> <notification name="ObjectMessage"> - [NAME]: [MESSAGE] + [NAME]:[MESSAGE] </notification> <notification name="CallingCardAccepted"> 你的名片已被接受。 @@ -2220,24 +2358,25 @@ Please select a single object. 你的名片已被拒絕。 </notification> <notification name="TeleportToLandmark"> - You can teleport to locations like '[NAME]' by opening the Places panel on the right side of your screen, and then select the Landmarks tab. -Click on any landmark to select it, then click 'Teleport' at the bottom of the panel. -(You can also double-click on the landmark, or right-click it and choose 'Teleport'.) + 要瞬間傳送到「[NAME]」等地點,請點按「地點」按鈕, + 然後在開啟的視窗裡,選擇「地標」頁籤。 點按任何 + 地標加以選擇,再點按視窗底下的「瞬間傳送」按鈕。 + (你還可以直接按兩下那個地標,或按滑鼠右鍵,選擇「瞬間傳送」。) </notification> <notification name="TeleportToPerson"> - You can contact Residents like '[NAME]' by opening the People panel on the right side of your screen. -Select the Resident from the list, then click 'IM' at the bottom of the panel. -(You can also double-click on their name in the list, or right-click and choose 'IM'). + 要聯絡如「[NAME]」的任何一位居民,請點按「人群」按鈕,從打開的視窗中選擇一位居民,再點按視窗底下的「IM」。 + + (你還可以從清單直接按兩下名字,或按滑鼠右鍵,選擇「IM」。) </notification> <notification name="CantSelectLandFromMultipleRegions"> - Can't select land across server boundaries. -Try selecting a smaller piece of land. + 無法選擇超出伺服器邊界的土地。 +請試著縮小所選的土地。 </notification> <notification name="SearchWordBanned"> - Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. + 根據「社群準則」所明訂的內容限制,已排除你所搜尋的某些字眼。 </notification> <notification name="NoContentToSearch"> - Please select at least one type of content to search (General, Moderate, or Adult). + 請至少選擇一種要搜索的內容分級(一般普級、適度成人、完全成人)。 </notification> <notification name="SystemMessage"> [MESSAGE] @@ -2248,6 +2387,9 @@ Try selecting a smaller piece of land. <notification name="PaymentSent"> [MESSAGE] </notification> + <notification name="PaymentFailure"> + [MESSAGE] + </notification> <notification name="EventNotification"> 活動通知: @@ -2259,179 +2401,205 @@ Try selecting a smaller piece of land. </form> </notification> <notification name="TransferObjectsHighlighted"> - All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted. + 這地段上,所有將轉移給地段購買人的物件,現已呈高亮顯示。 -* Trees and grasses that will transfer are not highlighted. +* 即將轉移的樹和草不會以高亮顯示。 <form name="form"> - <button name="Done" text="Done"/> + <button name="Done" text="完成"/> </form> </notification> <notification name="DeactivatedGesturesTrigger"> - Deactivated gestures with same trigger: + 以同一觸發停用的姿勢: [NAMES] </notification> <notification name="NoQuickTime"> - Apple's QuickTime software does not appear to be installed on your system. -If you want to view streaming media on parcels that support it you should go to the [http://www.apple.com/quicktime QuickTime site] and install the QuickTime Player. + 你的系統似乎未安裝 Apple 的 QuickTime 軟體。 +如果你要在支援串流媒體的地段上觀看這類媒體,請到[http://www.apple.com/quicktime QuickTime 網站]安裝 QuickTime 播放器。 </notification> <notification name="NoPlugin"> - No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable. + 找不到媒體插件來處理「[MIME_TYPE]」mine 類型。 這類媒體將無法使用。 </notification> <notification name="MediaPluginFailed"> - The following Media Plugin has failed: + 以下的媒體插件失靈: [PLUGIN] -Please re-install the plugin or contact the vendor if you continue to experience problems. +如果你繼續出現這狀況,請重新安裝插件,或聯絡其提供廠家。 <form name="form"> - <ignore name="ignore" text="A Media Plugin fails to run"/> + <ignore name="ignore" text="有一個媒體插件無法執行"/> </form> </notification> <notification name="OwnedObjectsReturned"> - The objects you own on the selected parcel of land have been returned back to your inventory. + 你在所選地段上所擁有的物件已被送返你的收納區。 </notification> <notification name="OtherObjectsReturned"> - The objects on the selected parcel of land that is owned by [NAME] have been returned to his or her inventory. + 在所選地段上由 [NAME] 所擁有的物件已被送返其收納區。 </notification> <notification name="OtherObjectsReturned2"> - The objects on the selected parcel of land owned by the Resident '[NAME]' have been returned to their owner. + 在所選地段上由居民 '[NAME]' 所擁有的物件已被送返其收納區。 </notification> <notification name="GroupObjectsReturned"> - The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner's inventory. -Transferable deeded objects have been returned to their previous owners. -Non-transferable objects that are deeded to the group have been deleted. + 在所選地段上和群組 '[GROUPNAME]' 分享的物件已被送返其所有人的收納區。 +可轉讓的已讓渡物件已送返給前物主。 +讓渡給這個群組的不可轉讓物件已被刪除。 </notification> <notification name="UnOwnedObjectsReturned"> - The objects on the selected parcel that are NOT owned by you have been returned to their owners. + 在所選地段上不是你擁有的物件已送返給其所有人。 </notification> <notification name="ServerObjectMessage"> - Message from [NAME]: + 來自 [NAME] 的訊息: <nolink>[MSG]</nolink> </notification> <notification name="NotSafe"> - This land has damage enabled. -You can be hurt here. If you die, you will be teleported to your home location. + 這塊土地允許傷害。 +在這裡你可能會受傷害。 你如果死亡,會被瞬間傳送回你的家。 </notification> <notification name="NoFly"> - 這區域關閉並禁止飛行。 + 這區域禁止飛行。 你不能在此處飛行。 </notification> <notification name="PushRestricted"> - This area does not allow pushing. You can't push others here unless you own the land. + 這區域不允許推撞。 除非你擁有這塊土地,否則你不能推撞別人。 </notification> <notification name="NoVoice"> - This area has voice chat disabled. You won't be able to hear anyone talking. + 這區域禁止語音聊天。 你將不會聽到任何人說話。 </notification> <notification name="NoBuild"> - This area has building disabled. You can't build or rez objects here. + 這區域禁止建造物件。 你不能在此建造或產生物件。 + </notification> + <notification name="PathfindingDirty"> + 這地區的尋徑功能有所變更,待儲存。 如果你有建製權,你可以點按「重新產出地區」按鈕重新產出地區。 + </notification> + <notification name="DynamicPathfindingDisabled"> + 這地區並未啟用動態尋徑。 使用尋徑 LSL 呼叫的帶腳本物件,在此地區可能無法正常運作。 + </notification> + <notification name="PathfindingRebakeNavmesh"> + 更改本地區的某些物件將導致其他移動物件的運作發生問題。 要使移動物件正常運作,請點按「重新產出地區」按鈕。 欲獲知詳情請選擇「幫助」。 + <url name="url"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </url> + <usetemplate helptext="幫助" ignoretext="更改本地區的某些物件將導致其他移動物件的運作發生問題。" name="okhelpignore" yestext="確定"/> + </notification> + <notification name="PathfindingCannotRebakeNavmesh"> + 發生錯誤。 問題可能出在網路或伺服器,也可能因為你無權建製物件。 有時,只要登出再登入即能解決這類問題。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SeeAvatars"> + 本地段隱藏其內的化身和聊天文字,其他地段看不到。 你看不見地段外的居民,他們也看不見你。 頻道 0 的聊天文字也被封鎖。 </notification> <notification name="ScriptsStopped"> - An administrator has temporarily stopped scripts in this region. + 某管理員已暫時停止區域裡的腳本。 </notification> <notification name="ScriptsNotRunning"> - This region is not running any scripts. + 這區域沒有執行任何腳本。 </notification> <notification name="NoOutsideScripts"> - This land has outside scripts disabled. + 這塊土地禁用外來腳本。 -No scripts will work here except those belonging to the land owner. +只有屬於土地所有人的腳本在此可以正常執行。 </notification> <notification name="ClaimPublicLand"> - You can only claim public land in the Region you're in. + 你只能在你所處的區域收取公共土地。 </notification> <notification name="RegionTPAccessBlocked"> - You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. - -Please go to the Knowledge Base for details on accessing areas with this maturity Rating. + 你所欲前往的地區含有超過你目前偏好的分級的內容。 你可以到「我自己 > 偏好設定 > 一般設定」變更你的偏好設定。 </notification> <notification name="URBannedFromRegion"> - You are banned from the region. + 這個區域禁止你進入。 </notification> <notification name="NoTeenGridAccess"> - Your account cannot connect to this teen grid region. + 你的帳戶不可連接到這個青少年網格區域。 </notification> <notification name="ImproperPaymentStatus"> - You do not have proper payment status to enter this region. + 你沒有適當的付款狀態,不能進入這區域。 </notification> - <notification name="MustGetAgeRgion"> - 你必須通過年齡認證以進入這地區。 + <notification name="MustGetAgeRegion"> + 你必須年滿 18 歲才可進入這地區。 </notification> <notification name="MustGetAgeParcel"> - 你必須通過年齡驗證以進入這地段。 + 你必須年滿 18 歲才可進入這地段。 </notification> <notification name="NoDestRegion"> - 無目的地地區發現。 + 找不到目的地地區。 </notification> <notification name="NotAllowedInDest"> - You are not allowed into the destination. + 你不准前往目的地。 </notification> <notification name="RegionParcelBan"> - Cannot region cross into banned parcel. Try another way. + 無法跨出地區進入禁止你的地段。 請換一個方式。 </notification> <notification name="TelehubRedirect"> - You have been redirected to a telehub. + 你已被重新導往一個瞬間傳送中心。 </notification> <notification name="CouldntTPCloser"> - Could not teleport closer to destination. + 無法瞬間傳送到更接近目的地的地點。 </notification> <notification name="TPCancelled"> 瞬間傳送已取消。 </notification> <notification name="FullRegionTryAgain"> - The region you are attempting to enter is currently full. -Please try again in a few moments. + 你試圖進入的地區目前人滿。 +請稍待一會兒再試。 </notification> <notification name="GeneralFailure"> 一般故障。 </notification> <notification name="RoutedWrongRegion"> - 路由導向到錯誤地區。請再試一次。 + 被繞往錯誤的地區。 請再試一次。 </notification> <notification name="NoValidAgentID"> - No valid agent id. + 沒有有效的化身編號。 </notification> <notification name="NoValidSession"> - No valid session id. + 沒有有效的時域編號。 </notification> <notification name="NoValidCircuit"> - No valid circuit code. + 沒有有效的線路碼。 </notification> <notification name="NoValidTimestamp"> - No valid timestamp. + 沒有有效的時間戳記。 </notification> <notification name="NoPendingConnection"> - Unable to create pending connection. + 無法建立待通的連線。 </notification> <notification name="InternalUsherError"> - Internal error attempting to connect agent usher. + 試圖連接用戶引導時發生內部錯誤。 </notification> <notification name="NoGoodTPDestination"> - Unable to find a good teleport destination in this region. + 在這地區找不到合適的瞬間傳送目的地。 </notification> <notification name="InternalErrorRegionResolver"> - Internal error attempting to activate region resolver. + 試圖啟動區域解析器時發生內部錯誤。 </notification> <notification name="NoValidLanding"> - A valid landing point could not be found. + 找不到有效的登陸地點。 </notification> <notification name="NoValidParcel"> - No valid parcel could be found. + 找不到有效的地段。 </notification> <notification name="ObjectGiveItem"> - An object named <nolink>[OBJECTFROMNAME]</nolink> owned by [NAME_SLURL] has given you this [OBJECTTYPE]: -[ITEM_SLURL] + 名為 <nolink>[OBJECTFROMNAME]</nolink>、由 [NAME_SLURL] 擁有的物件給了你這個 [OBJECTTYPE]: +<nolink>[ITEM_SLURL]</nolink> + <form name="form"> + <button name="Keep" text="保留"/> + <button name="Discard" text="丟棄"/> + <button name="Mute" text="封鎖所有人"/> + </form> + </notification> + <notification name="OwnObjectGiveItem"> + 你名為 <nolink>[OBJECTFROMNAME]</nolink> 的物件給了你這個 [OBJECTTYPE]: +<nolink>[ITEM_SLURL]</nolink> <form name="form"> - <button name="Keep" text="Keep"/> - <button name="Discard" text="Discard"/> - <button name="Mute" text="Block"/> + <button name="Keep" text="保留"/> + <button name="Discard" text="丟棄"/> </form> </notification> <notification name="UserGiveItem"> - [NAME_SLURL] has given you this [OBJECTTYPE]: + [NAME_SLURL] 給了你這個 [OBJECTTYPE]: [ITEM_SLURL] <form name="form"> - <button name="Show" text="Show"/> - <button name="Discard" text="Discard"/> - <button name="Mute" text="Block"/> + <button name="Show" text="顯示"/> + <button name="Discard" text="丟棄"/> + <button name="Mute" text="封鎖"/> </form> </notification> <notification name="GodMessage"> @@ -2448,16 +2616,37 @@ Please try again in a few moments. </form> </notification> <notification name="TeleportOffered"> - [NAME_SLURL] has offered to teleport you to their location: + [NAME_SLURL] 想要瞬間傳送你到他的地點: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <form name="form"> <button name="Teleport" text="瞬間傳送"/> <button name="Cancel" text="取消"/> </form> </notification> + <notification name="TeleportOffered_MaturityExceeded"> + [NAME_SLURL] 想要瞬間傳送你到他的地點: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +此地區包含 [REGION_CONTENT_MATURITY] 的分級內容,可是你目前的偏好設定排除了 [REGION_CONTENT_MATURITY] 的分級內容。 我們可以變更你的偏好設定好讓你繼續瞬間傳送,你也可取消這動作。 + <form name="form"> + <button name="Teleport" text="變更後繼續"/> + <button name="Cancel" text="取消"/> + </form> + </notification> + <notification name="TeleportOffered_MaturityBlocked"> + [NAME_SLURL] 想要瞬間傳送你到他的地點: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +可是,此地區含有僅限成人的內容。 + </notification> <notification name="TeleportOfferSent"> - Teleport offer sent to [TO_NAME] + 已向 [TO_NAME] 發出瞬間傳送邀請 </notification> <notification name="GotoURL"> [MESSAGE] @@ -2468,33 +2657,33 @@ Please try again in a few moments. </form> </notification> <notification name="OfferFriendship"> - [NAME_SLURL] is offering friendship. + [NAME_SLURL] 想成為你的朋友。 [MESSAGE] -(By default, you will be able to see each other's online status.) +(根據預設設定,你們將可看到彼此的線上狀態。) <form name="form"> <button name="Accept" text="接受"/> <button name="Decline" text="謝絕"/> </form> </notification> <notification name="FriendshipOffered"> - You have offered friendship to [TO_NAME] + 已經邀請 [TO_NAME] 成為朋友 </notification> <notification name="OfferFriendshipNoMessage"> - [NAME_SLURL] is offering friendship. + [NAME_SLURL] 想成為你的朋友。 -(By default, you will be able to see each other's online status.) +(根據預設設定,你們將可看到彼此的線上狀態。) <form name="form"> <button name="Accept" text="接受"/> <button name="Decline" text="謝絕"/> </form> </notification> <notification name="FriendshipAccepted"> - <nolink>[NAME]</nolink> accepted your friendship offer. + <nolink>[NAME]</nolink> 接受了你的交友邀請。 </notification> <notification name="FriendshipDeclined"> - <nolink>[NAME]</nolink> 謝絕你的交友邀請。 + <nolink>[NAME]</nolink> 婉拒了你的交友邀請。 </notification> <notification name="FriendshipAcceptedByMe"> 交友邀請被接受。 @@ -2503,208 +2692,206 @@ Please try again in a few moments. 交友邀請被謝絕。 </notification> <notification name="OfferCallingCard"> - [NAME] is offering their calling card. -This will add a bookmark in your inventory so you can quickly IM this Resident. + [NAME] 送給你他的名片。 +這將在你的收納區新增一個書籤,方便你和這位居民互傳即時訊息。 <form name="form"> <button name="Accept" text="接受"/> <button name="Decline" text="謝絕"/> </form> </notification> <notification name="RegionRestartMinutes"> - This region will restart in [MINUTES] minutes. -If you stay in this region you will be logged out. + 本地區將在 [MINUTES] 分鐘後重新啟動。 +如果你繼續留在這地區,你將會被登出。 </notification> <notification name="RegionRestartSeconds"> - This region will restart in [SECONDS] seconds. -If you stay in this region you will be logged out. + 本地區將在 [SECONDS] 秒後重新啟動。 +如果你繼續留在這地區,你將會被登出。 </notification> <notification name="LoadWebPage"> 載入網頁 [URL]? [MESSAGE] -From object: <nolink>[OBJECTNAME]</nolink>, owner: [NAME]? +來源物件:<nolink>[OBJECTNAME]</nolink>(所有人是 [NAME])? <form name="form"> <button name="Gotopage" text="前往頁面"/> <button name="Cancel" text="取消"/> </form> </notification> <notification name="FailedToFindWearableUnnamed"> - Failed to find [TYPE] in database. + 資料庫找不到 [TYPE]。 </notification> <notification name="FailedToFindWearable"> - Failed to find [TYPE] named [DESC] in database. + 資料庫找不到名為 [DESC] 的 [TYPE]。 </notification> <notification name="InvalidWearable"> - The item you are trying to wear uses a feature that your Viewer can't read. Please upgrade your version of [APP_NAME] to wear this item. + 你想要穿著的物項帶有一個不是你目前 Viewer 版本能夠讀取的特性。 請更新你的 [APP_NAME] 版本再穿著該物項。 </notification> <notification name="ScriptQuestion"> - '<nolink>[OBJECTNAME]</nolink>', an object owned by '[NAME]', would like to: + '<nolink>[OBJECTNAME]</nolink>',一個由 '[NAME]' 擁有的物件,想要: [QUESTIONS] -Is this OK? +是否同意? <form name="form"> <button name="Yes" text="是"/> <button name="No" text="否"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="封鎖"/> </form> </notification> <notification name="ScriptQuestionCaution"> - An object named '<nolink>[OBJECTNAME]</nolink>', owned by '[NAME]' would like to: - -[QUESTIONS] -If you do not trust this object and its creator, you should deny the request. - -Grant this request? + 警告:物件 '<nolink>[OBJECTNAME]</nolink>' 要求全權存取你的林登幣帳戶。 你如果允許存取帳戶,它將可在任何時候從你帳戶取走資金,或完全加以清空,或定期取走部分資金,且不會發出警告。 + +這很可能是種不當的要求。 如果你不完全瞭解它為何要求存取你的帳戶,請勿允准。 <form name="form"> - <button name="Grant" text="Grant"/> - <button name="Deny" text="Deny"/> - <button name="Details" text="細節..."/> + <button name="Grant" text="允許全權存取"/> + <button name="Deny" text="拒絕"/> </form> </notification> <notification name="ScriptDialog"> - [NAME]'s '<nolink>[TITLE]</nolink>' + [NAME] 的 '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> - <button name="Ignore" text="忽視"/> + <button name="Client_Side_Mute" text="封鎖"/> + <button name="Client_Side_Ignore" text="忽視"/> </form> </notification> <notification name="ScriptDialogGroup"> - [GROUPNAME]'s '<nolink>[TITLE]</nolink>' + [GROUPNAME] 的 '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> - <button name="Ignore" text="忽視"/> + <button name="Client_Side_Mute" text="封鎖"/> + <button name="Client_Side_Ignore" text="忽視"/> </form> </notification> <notification name="BuyLindenDollarSuccess"> - Thank you for your payment! + 感謝你付款! -Your L$ balance will be updated when processing completes. If processing takes more than 20 mins, your transaction may be cancelled. In that case, the purchase amount will be credited to your US$ balance. +處理完成後,你的 L$ 餘額將會更新。 如果處理過程超過 20 分鐘,你的交易可能被取消。 在這狀況下,購買金額將退回給你的 US$ 餘額。 -The status of your payment can be checked on your Transaction History page on your [http://secondlife.com/account/ Dashboard] +你可以到你的[http://secondlife.com/account/ 塗鴉牆]上的交易歷史記錄頁面,察看付款狀態。 </notification> <notification name="FirstOverrideKeys"> - Your movement keys are now being handled by an object. -Try the arrow keys or AWSD to see what they do. -Some objects (like guns) require you to go into mouselook to use them. -Press 'M' to do this. + 你的方向鍵現在由一個物件主控。 +請試試方向鍵或 AWSD 鍵看有什麼反應。 +有些物件(例如槍枝)需要你切換成第一人稱視角才有作用。 +請按 M 鍵做切換。 </notification> <notification name="FirstSandbox"> - This is a sandbox area, and is meant to help Residents learn how to build. + 這個一個沙盤區,旨在幫助居民學習如何建製物件。 -Things you build here will be deleted after you leave, so don't forget to right-click and choose 'Take' to move your creation to your Inventory. +你在這裡建製的物件,在你離開後將被刪除。別忘了按滑鼠右鍵,選擇「拿取」,將你的建製物送到你的收納區。 </notification> <notification name="MaxListSelectMessage"> - You may only select up to [MAX_SELECT] items from this list. + 你最多只能從這清單中選取 [MAX_SELECT] 個物項。 </notification> <notification name="VoiceInviteP2P"> - [NAME] is inviting you to a Voice Chat call. -Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + [NAME] 正邀請你加入語音聊天。 +點按「接受」加入通話,或「謝絕」邀請。 點按「封鎖」便可封鎖這個發話人。 <form name="form"> <button name="Accept" text="接受"/> <button name="Decline" text="謝絕"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="封鎖"/> </form> </notification> <notification name="AutoUnmuteByIM"> - [NAME] was sent an instant message and has been automatically unblocked. + [NAME] 已收到一則即時訊息,並已被自動解除封鎖。 </notification> <notification name="AutoUnmuteByMoney"> - [NAME] was given money and has been automatically unblocked. + [NAME] 已收到錢,並已被自動解除封鎖。 </notification> <notification name="AutoUnmuteByInventory"> - [NAME] was offered inventory and has been automatically unblocked. + [NAME] 已得知你要贈送收納物件,並已被自動解除封鎖。 </notification> <notification name="VoiceInviteGroup"> - [NAME] has joined a Voice Chat call with the group [GROUP]. -Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + [NAME] 已加入和群組 [GROUP] 的語音聊天通話。 +點按「接受」加入通話,或「謝絕」邀請。 點按「封鎖」便可封鎖這個發話人。 <form name="form"> <button name="Accept" text="接受"/> <button name="Decline" text="謝絕"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="封鎖"/> </form> </notification> <notification name="VoiceInviteAdHoc"> - [NAME] has joined a voice chat call with a conference chat. -Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + [NAME] 已加入多方語音通話。 +點按「接受」加入通話,或「謝絕」邀請。 點按「封鎖」便可封鎖這個發話人。 <form name="form"> <button name="Accept" text="接受"/> <button name="Decline" text="謝絕"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="封鎖"/> </form> </notification> <notification name="InviteAdHoc"> - [NAME] is inviting you to a conference chat. -Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller. + [NAME] 正邀請你加入多方通話。 +點按「接受」加入通話,或「謝絕」邀請。 點按「封鎖」便可封鎖這個發話人。 <form name="form"> <button name="Accept" text="接受"/> <button name="Decline" text="謝絕"/> - <button name="Mute" text="Block"/> + <button name="Mute" text="封鎖"/> </form> </notification> <notification name="VoiceChannelFull"> - The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later. + 你試圖加入 [VOICE_CHANNEL_NAME] 語音通話,不過它已達負載上限。 請稍候再試一次。 </notification> <notification name="ProximalVoiceChannelFull"> - We're sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area. + 很抱歉。 這區域已達語音通話的負載上限。 請到另一個區域使用語音。 </notification> <notification name="VoiceChannelDisconnected"> - You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to Nearby Voice Chat. + 你的 [VOICE_CHANNEL_NAME] 通話已經中斷。 現在你將重新連通到附近的語音聊天。 </notification> <notification name="VoiceChannelDisconnectedP2P"> - [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to Nearby Voice Chat. + [VOICE_CHANNEL_NAME] 語音通話已結束。 現在你將重新連通到附近的語音聊天。 </notification> <notification name="P2PCallDeclined"> - [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to Nearby Voice Chat. + [VOICE_CHANNEL_NAME] 拒絕你加入語音通話。 現在你將重新連通到附近的語音聊天。 </notification> <notification name="P2PCallNoAnswer"> - [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to Nearby Voice Chat. + [VOICE_CHANNEL_NAME] 無法接通你的通話。 現在你將重新連通到附近的語音聊天。 </notification> <notification name="VoiceChannelJoinFailed"> - Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to Nearby Voice Chat. + 無法連通 [VOICE_CHANNEL_NAME],,請稍候再試。 現在你將重新連通到附近的語音聊天。 </notification> <notification name="VoiceLoginRetry"> - We are creating a voice channel for you. This may take up to one minute. + 我們正為你建立語音頻道。 這至多可能需時一分鐘。 </notification> <notification name="VoiceEffectsExpired"> - One or more of your subscribed Voice Morphs has expired. -[[URL] Click here] to renew your subscription. + 至少一個你訂用的變聲效果已經過期。 +[[URL] 點按這裡] 繼續訂用。 </notification> <notification name="VoiceEffectsExpiredInUse"> - The active Voice Morph has expired, your normal voice settings have been applied. -[[URL] Click here] to renew your subscription. + 使用中的變聲效果已經過期,已用你平時的聲音設定取代。 +[[URL] 點按這裡] 繼續訂用。 </notification> <notification name="VoiceEffectsWillExpire"> - One or more of your Voice Morphs will expire in less than [INTERVAL] days. -[[URL] Click here] to renew your subscription. + 至少一個你訂用的變聲效果將在 [INTERVAL] 天後到期。 +[[URL] 點按這裡] 繼續訂用。 </notification> <notification name="VoiceEffectsNew"> - New Voice Morphs are available! + 新的變聲效果上市了! </notification> <notification name="Cannot enter parcel: not a group member"> - Only members of a certain group can visit this area. + 只有某特定群組的成員才能進入這區域。 </notification> <notification name="Cannot enter parcel: banned"> - Cannot enter parcel, you have been banned. + 你已被禁入,因此無法進入這地段。 </notification> <notification name="Cannot enter parcel: not on access list"> - Cannot enter parcel, you are not on the access list. + 無法進入這地段,你不在出入許可名單中。 </notification> <notification name="VoiceNotAllowed"> - You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. + 你無權連通 [VOICE_CHANNEL_NAME] 語音聊天。 </notification> <notification name="VoiceCallGenericError"> - An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later. + 試圖連通 [VOICE_CHANNEL_NAME] 語音聊天時發生錯誤。 請稍候再試一次。 </notification> <notification name="UnsupportedCommandSLURL"> - 你所點擊的 SLurl 位置並不被支援。 + 你所點按的 SLurl 位置並不被支援。 </notification> <notification name="BlockedSLURL"> - A SLurl was received from an untrusted browser and has been blocked for your security. + 從未被信任的瀏覽器接收到一個 SLurl,為了你的安全起見,已將它封鎖。 </notification> <notification name="ThrottledSLURL"> - Multiple SLurls were received from an untrusted browser within a short period. -They will be blocked for a few seconds for your security. + 短時間內從一個不被信任的瀏覽器接收到多個 SLurl。 +為了你的安全起見,它們將被封鎖幾秒鐘。 </notification> <notification name="IMToast"> [MESSAGE] @@ -2713,45 +2900,72 @@ They will be blocked for a few seconds for your security. </form> </notification> <notification name="ConfirmCloseAll"> - 你確定要關閉全部 IMs 對話視窗? + 你確定要關閉所有的 IM? <usetemplate ignoretext="在我關閉全部的 IMs 對話視窗前確認。" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification name="AttachmentSaved"> 附件已儲存。 </notification> <notification name="UnableToFindHelpTopic"> - Unable to find the help topic for this element. + 找不到這個元件的幫助主題。 </notification> <notification name="ObjectMediaFailure"> - Server Error: Media update or get failed. + 伺服器錯誤:媒體更新或取得失敗。 '[ERROR]' <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="TextChatIsMutedByModerator"> - Your text chat has been muted by moderator. + 主持人已設定忽略你的文字聊天內容。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="VoiceIsMutedByModerator"> - Your voice has been muted by moderator. + 主持人已將你的語音消音。 <usetemplate name="okbutton" yestext="確定"/> </notification> + <notification name="UploadCostConfirmation"> + 上傳將花費 L$[PRICE],是否繼續? + <usetemplate name="okcancelbuttons" notext="取消" yestext="上傳"/> + </notification> <notification name="ConfirmClearTeleportHistory"> - Are you sure you want to delete your teleport history? + 確定清除你的瞬間傳送歷史記錄? <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> </notification> <notification name="BottomTrayButtonCanNotBeShown"> - Selected button can not be shown right now. -The button will be shown when there is enough space for it. + 所選按鈕目前無法顯示。 +等到空間足夠,按鈕將會顯示出來。 </notification> <notification name="ShareNotification"> - Select residents to share with. + 選取要分享的居民。 + </notification> + <notification name="MeshUploadError"> + [LABEL] 上傳失敗:[MESSAGE] [IDENTIFIER] + +詳見記錄檔。 + </notification> + <notification name="MeshUploadPermError"> + 請求網面上傳權限時出錯。 + </notification> + <notification name="RegionCapabilityRequestError"> + 無法取得地區能力 '[CAPABILITY]'。 </notification> <notification name="ShareItemsConfirmation"> - Are you sure you want to share the following items: + 請確定你要和居民分享這些物項: + +<nolink>[ITEMS]</nolink> + +居民: + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> + </notification> + <notification name="ShareFolderConfirmation"> + 一次只能分享一個資料夾。 + +請確定你要和居民分享這些物項: <nolink>[ITEMS]</nolink> -With the following Residents: +居民: [RESIDENTS] <usetemplate name="okcancelbuttons" notext="取消" yestext="確定"/> @@ -2762,117 +2976,140 @@ With the following Residents: <notification name="DeedToGroupFail"> 讓渡給群組失敗。 </notification> + <notification name="ReleaseLandThrottled"> + 目前無法遺棄 [PARCEL_NAME] 地段。 + </notification> + <notification name="ReleasedLandWithReclaim"> + [AREA] 平方公尺的地段「[PARCEL_NAME]」已釋出。 + +你須在 [RECLAIM_PERIOD] 小時內領回(花費 L$0),否則將開放出售給任何人。 + </notification> + <notification name="ReleasedLandNoReclaim"> + [AREA] 平方公尺的地段「[PARCEL_NAME]」已釋出。 + +現已開放出售給任何人。 + </notification> <notification name="AvatarRezNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' declouded after [TIME] seconds. + (存續 [EXISTENCE] 秒鐘) +化身 '[NAME]' 在 [TIME] 秒內完全呈現。 </notification> <notification name="AvatarRezSelfBakedDoneNotification"> - ( [EXISTENCE] seconds alive ) -You finished baking your outfit after [TIME] seconds. + (存續 [EXISTENCE] 秒鐘) +你的裝扮在 [TIME] 秒內定貌。 </notification> <notification name="AvatarRezSelfBakedUpdateNotification"> - ( [EXISTENCE] seconds alive ) -You sent out an update of your appearance after [TIME] seconds. + (存續 [EXISTENCE] 秒鐘) +你在 [TIME] 秒後送出更新外觀請求。 [STATUS] </notification> <notification name="AvatarRezCloudNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' became cloud. + (存續 [EXISTENCE] 秒鐘) +化身 '[NAME]' 已雲化。 </notification> <notification name="AvatarRezArrivedNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' appeared. + (存續 [EXISTENCE] 秒鐘) +化身 '[NAME]' 已出現。 </notification> <notification name="AvatarRezLeftCloudNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' left after [TIME] seconds as cloud. + (存續 [EXISTENCE] 秒鐘) +化身 '[NAME]' 在雲化 [TIME] 秒後離開。 </notification> <notification name="AvatarRezEnteredAppearanceNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' entered appearance mode. + (存續 [EXISTENCE] 秒鐘) +化身 '[NAME]' 進入外觀模式。 </notification> <notification name="AvatarRezLeftAppearanceNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' left appearance mode. + (存續 [EXISTENCE] 秒鐘) +化身 '[NAME]' 離開外觀模式。 </notification> <notification name="NoConnect"> - We're having trouble connecting using [PROTOCOL] [HOSTID]. -Please check your network and firewall setup. + 使用 [PROTOCOL] [HOSTID] 連線時出了問題。 +請檢查你的網路和防火牆設定。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="NoVoiceConnect"> - We're having trouble connecting to your voice server: + 試圖連接語音伺服器時出了問題: [HOSTID] -Voice communications will not be available. -Please check your network and firewall setup. +將無法用語音溝通。 +請檢查你的網路和防火牆設定。 <usetemplate name="okbutton" yestext="確定"/> </notification> <notification name="AvatarRezLeftNotification"> - ( [EXISTENCE] seconds alive ) -Avatar '[NAME]' left as fully loaded. + (存續 [EXISTENCE] 秒鐘) +化身 '[NAME]' 在完全載入狀況下離開。 </notification> <notification name="AvatarRezSelfBakedTextureUploadNotification"> - ( [EXISTENCE] seconds alive ) -You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. + (存續 [EXISTENCE] 秒鐘) +你在 [TIME] 秒鐘後為 '[BODYREGION]' 上傳了一個 [RESOLUTION] 的定貌材質。 </notification> <notification name="AvatarRezSelfBakedTextureUpdateNotification"> - ( [EXISTENCE] seconds alive ) -You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. + (存續 [EXISTENCE] 秒鐘) +你在 [TIME] 秒鐘後在本地為 '[BODYREGION]' 更新了一個 [RESOLUTION] 的定貌材質。 + </notification> + <notification name="LivePreviewUnavailable"> + 我們無法顯示這個材質的預覽,因為它設為「禁止複製」且 / 或「禁止轉移」。 + <usetemplate ignoretext="「禁止複製」和「禁止轉移」的材質若不能使用實時預覽模式,請給我警示。" name="okignore" yestext="確定"/> </notification> <notification name="ConfirmLeaveCall"> 你確定要離開這段通話? <usetemplate ignoretext="我結束通話前進行確認" name="okcancelignore" notext="否" yestext="是"/> </notification> <notification name="ConfirmMuteAll"> - You have selected to mute all participants in a group call. -This will also cause all residents that later join the call to be -muted, even after you have left the call. + 你已選擇要將所有參與群組通話的人消音。 +這將導致後來加入通話的所有居民同樣被 +消音,即使在你離開通話後也一樣。 -Mute everyone? +把所有人消音? <usetemplate ignoretext="在我對所有群組通話的參與者予以靜音前確認" name="okcancelignore" notext="取消" yestext="確定"/> </notification> <notification label="聊天" name="HintChat"> - To join the conversation, type into the chat field below. + 若要加入對話,請在下方的聊天欄裡打字。 </notification> - <notification label="Stand" name="HintSit"> - To stand up and exit the sitting position, click the Stand button. + <notification label="站立" name="HintSit"> + 若要中止坐姿站起身來,請按「站立」按鈕。 </notification> - <notification label="Speak" name="HintSpeak"> - Click the Speak button to turn your microphone on and off. + <notification label="說話" name="HintSpeak"> + 點按「說話」按鈕來打開或關閉麥克風。 -Click on the up arrow to see the voice control panel. +點按向上箭頭鍵,可顯示聲音控制面板。 -Hiding the Speak button will disable the voice feature. +隱藏「說話」按鈕將停用語音功能。 </notification> <notification label="探索世界" name="HintDestinationGuide"> - The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring. + 目的地指南包含上千個值得探索的新地點。 選擇一個地點,然後「瞬間傳送」前往,開始你的探索! </notification> <notification label="側邊欄" name="HintSidePanel"> - Get quick access to your inventory, outfits, profiles and more in the side panel. + 你可以從側邊欄進入收納區、裝扮、個人檔案等,方便又迅速。 </notification> <notification label="移動" name="HintMove"> - To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard. + 若想行走或跑步,請打開「移動」面板,使用方向箭頭來移動。 也可以使用鍵盤上的方向鍵。 </notification> <notification label="" name="HintMoveClick"> - 1. Click to Walk -Click anywhere on the ground to walk to that spot. + 1. 點按一下就可行走 +點按地面上任何一點,就可以走到那裡。 -2. Click and Drag to Rotate View -Click and drag anywhere on the world to rotate your view +2. 按住並拖曳,可以旋轉視野 +在虛擬世界裡按住並拖曳任何一點,就可旋轉你的視野 </notification> <notification label="顯示名稱" name="HintDisplayName"> - Set your customizable display name here. This is in addition to your unique username, which can't be changed. You can change how you see other people's names in your preferences. + 在這裡自訂你的顯示名稱。 顯示名稱和使用者名稱有別,後者獨一無二而且不能變更。 你可以在偏好設定裡,變更要如何察看別人的名稱。 </notification> - <notification label="View" name="HintView"> - To change your camera view, use the Orbit and Pan controls. Reset your view by pressing Escape or walking. + <notification label="視角" name="HintView"> + 要改變攝影機視角,請用「環繞」和「平移」控制。 按 Escape 鍵,或走動一下,便可重設你的視野。 </notification> <notification label="收納區" name="HintInventory"> - Check your inventory to find items. Newest items can be easily found in the Recent tab. + 到收納區找尋物項。 在「新近」頁籤裡可立刻看到新近的物項。 </notification> <notification label="你得到林登幣!" name="HintLindenDollar"> - Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars. + 這裡顯示你目前的 L$ 餘額。 點按「購買 L$」可添購林登幣。 + </notification> + <notification name="LowMemory"> + 你的可用記憶體很小。 第二人生部分功能將停用,以免當機。 請關閉其他應用程式。 這狀況若持續,請重啟第二人生。 + </notification> + <notification name="ForceQuitDueToLowMemory"> + 記憶體不足,第二人生將於 30 秒後關閉離開。 </notification> <notification name="PopupAttempt"> 一個突顯式視窗開啟時被阻擋。 @@ -2881,54 +3118,171 @@ Click and drag anywhere on the world to rotate your view <button name="open" text="開啟突顯式視窗"/> </form> </notification> + <notification name="SOCKS_NOT_PERMITTED"> + SOCKS 5 代理伺服器 "[HOST]:[PORT]" 拒絕連通,規則集不允許。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_CONNECT_ERROR"> + SOCKS 5 代理伺服器 "[HOST]:[PORT]" 拒絕連通,無法打開 TCP 頻道。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_NOT_ACCEPTABLE"> + SOCKS 5 代理伺服器 "[HOST]:[PORT]" 拒絕所選的鑒認方法。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_AUTH_FAIL"> + SOCKS 5 代理伺服器 "[HOST]:[PORT]" 回報:你的鑒認資料無效。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_UDP_FWD_NOT_GRANTED"> + SOCKS 5 代理伺服器 "[HOST]:[PORT]" 拒絕 UDP 聯結請求。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_HOST_CONNECT_FAILED"> + 無法連通 SOCKS 5 代理伺服器 "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_UNKNOWN_STATUS"> + 伺服器 "[HOST]:[PORT]" 發生不明的代理伺服器錯誤。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_INVALID_HOST"> + 無效的 SOCKS 代理伺服器位址或埠號 "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="SOCKS_BAD_CREDS"> + 無效的 SOCKS 5 使用者名稱或密碼。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="PROXY_INVALID_HTTP_HOST"> + 無效的 HTTP 代理伺服器位址或埠號 "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="PROXY_INVALID_SOCKS_HOST"> + 無效的 SOCKS 代理伺服器位址或埠號 "[HOST]:[PORT]"。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="ChangeProxySettings"> + 重新啟動 [APP_NAME] 後將採用新的代理伺服器設定。 + <usetemplate name="okbutton" yestext="確定"/> + </notification> <notification name="AuthRequest"> - The site at '<nolink>[HOST_NAME]</nolink>' in realm '[REALM]' requires a user name and password. + '[REALM]' 領域的 '<nolink>[HOST_NAME]</nolink>' 站點需要使用者名稱和密碼。 <form name="form"> - <input name="username" text="User Name"/> - <input name="password" text="Password"/> - <button name="ok" text="Submit"/> + <input name="username" text="使用者名稱"/> + <input name="password" text="密碼"/> + <button name="ok" text="提交"/> <button name="cancel" text="取消"/> </form> </notification> - <notification label="" name="ModeChange"> - 改變劉覽器模式要求你必須結束退出並重新啟動。 - <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> - </notification> <notification label="" name="NoClassifieds"> - Creation and editing of Classifieds is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + 只有進階模式才能新建或編輯個人廣告。 你是否想要結束離開,以便變更模式? 你可在登入畫面選擇想要的模式。 <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> </notification> <notification label="" name="NoGroupInfo"> - Creation and editing of Groups is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + 只有進階模式才能新建或編輯群組。 你是否想要結束離開,以便變更模式? 你可在登入畫面選擇想要的模式。 + <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> + </notification> + <notification label="" name="NoPlaceInfo"> + 只有進階模式才能察看地點檔案。 你是否想要結束離開,以便變更模式? 你可在登入畫面選擇想要的模式。 <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> </notification> <notification label="" name="NoPicks"> - Creation and editing of Picks is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + 只有進階模式才能新建或編輯精選地點。 你是否想要結束離開,以便變更模式? 你可在登入畫面選擇想要的模式。 <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> </notification> <notification label="" name="NoWorldMap"> - Viewing of the world map is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + 只有進階模式才能察看世界地圖。 你是否想要結束離開,以便變更模式? 你可在登入畫面選擇想要的模式。 <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> </notification> <notification label="" name="NoVoiceCall"> - Voice calls are only available in Advanced mode. Would you like to logout and change modes? + 只有進階模式才能使用語音通話。 你是否要登出並且變更模式? <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> </notification> <notification label="" name="NoAvatarShare"> - Sharing is only available in Advanced mode. Would you like to logout and change modes? + 只有進階模式才能使用分享功能。 你是否要登出並且變更模式? <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> </notification> <notification label="" name="NoAvatarPay"> - Paying other residents is only available in Advanced mode. Would you like to logout and change modes? + 只有進階模式才能付費給其他居民。 你是否要登出並且變更模式? <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> </notification> - <global name="UnsupportedCPU"> - - 你的 CPU 運算速度未達到系統最低配備要求。 - </global> + <notification label="" name="NoInventory"> + 只有進階模式才能察看收納區。 你是否要登出並且變更模式? + <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> + </notification> + <notification label="" name="NoAppearance"> + 只有進階模式才能使用外觀編輯器。 你是否要登出並且變更模式? + <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> + </notification> + <notification label="" name="NoSearch"> + 只有進階模式才能搜尋。 你是否要登出並且變更模式? + <usetemplate name="okcancelbuttons" notext="不要結束退出" yestext="結束退出"/> + </notification> + <notification label="" name="ConfirmHideUI"> + 這將會隱藏所有選單內容和按鈕。 要恢復原狀,再點按 [SHORTCUT] 一次。 + <usetemplate ignoretext="隱藏使用者介面前先確認" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom"> + 所選的一些聯結集的幻影旗標將被切換。 + +你確定要繼續嗎? + <usetemplate ignoretext="所選的一些聯結集的幻影旗標將被切換。" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted"> + 所選某些聯結集因權限問題,無法設定為 '[REQUESTED_TYPE]'。 這些聯結集將被設為 '[RESTRICTED_TYPE]'。 + +你確定要繼續嗎? + <usetemplate ignoretext="所選某些聯結集因權限問題,無法設定。" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnVolume"> + 所選某些聯結集無法設為 '[REQUESTED_TYPE]',因為形狀屬於非凸面。 + +你確定要繼續嗎? + <usetemplate ignoretext="所選某些聯結集因為形狀屬於非凸面,無法設定" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"> + 所選的一些聯結集的幻影旗標將被切換。 + +所選某些聯結集因權限問題,無法設定為 '[REQUESTED_TYPE]'。 這些聯結集將被設為 '[RESTRICTED_TYPE]'。 + +你確定要繼續嗎? + <usetemplate ignoretext="所選的一些聯結集的幻影旗標可成功切換,其他的則因權限問題而無法設定。" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"> + 所選的一些聯結集的幻影旗標將被切換。 + +所選某些聯結集無法設為 '[REQUESTED_TYPE]',因為形狀屬於非凸面。 + +你確定要繼續嗎? + <usetemplate ignoretext="所選的一些聯結集的幻影旗標可成功切換,其他的則因形狀屬於非凸面而無法設定" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"> + 所選某些聯結集因權限問題,無法設定為 '[REQUESTED_TYPE]'。 這些聯結集將被設為 '[RESTRICTED_TYPE]'。 + +所選某些聯結集無法設為 '[REQUESTED_TYPE]',因為形狀屬於非凸面。 這些聯結集的使用類型將維持不變。 + +你確定要繼續嗎? + <usetemplate ignoretext="所選某些聯結集因權限不足,且形狀屬於非凸面,因此無法設定。" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"> + 所選的一些聯結集的幻影旗標將被切換。 + +所選某些聯結集因權限問題,無法設定為 '[REQUESTED_TYPE]'。 這些聯結集將被設為 '[RESTRICTED_TYPE]'。 + +所選某些聯結集無法設為 '[REQUESTED_TYPE]',因為形狀屬於非凸面。 這些聯結集的使用類型將維持不變。 + +你確定要繼續嗎? + <usetemplate ignoretext="所選的一些聯結集的幻影旗標將被切換,其他則因權限不足且形狀屬於非凸面,因此無法設定。" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> + <notification name="PathfindingLinksets_ChangeToFlexiblePath"> + 所選的物件會影響導航網面。 將它改為彈性路徑,將使它從導航網面中被移除。 + <usetemplate ignoretext="所選的物件會影響導航網面。 將它改為彈性路徑,將使它從導航網面中被移除。" name="okcancelignore" notext="取消" yestext="確定"/> + </notification> <global name="UnsupportedGLRequirements"> - You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. + 你的硬體設備似乎不符 [APP_NAME] 的要求。 [APP_NAME] 需要可以支援多材質的 OpenGL 顯像卡。 在這狀況下,請確定你的顯像卡安裝了最新的驅動程式,作業系統也安裝了最新的服務包和嵌補程式。 -If you continue to have problems, please visit the [SUPPORT_SITE]. +如果你繼續遇到問題,請前往 [SUPPORT_SITE] 求助。 </global> <global name="UnsupportedCPUAmount"> 796 @@ -2944,9 +3298,29 @@ If you continue to have problems, please visit the [SUPPORT_SITE]. </global> <global name="You can only set your 'Home Location' on your land or at a mainland Infohub."> 若你擁有一塊土地,你可以標記它成為你的家的位置。 -或者,你可以察看地圖尋找標記為 "資訊中心" 的地方。 +或者,你可以察看地圖,尋找標記為「資訊中心」的地方。 </global> <global name="You died and have been teleported to your home location"> 你已經死亡並且被瞬間傳送回你的家的位置。 </global> + <notification name="LocalBitmapsUpdateFileNotFound"> + [FNAME] 無法更新,找不到該檔案。 +未來將不再更新該檔案。 + </notification> + <notification name="LocalBitmapsUpdateFailedFinal"> + [FNAME] 無法開啟或解碼,已嘗試 [NRETRIES] 次,該檔案已被認定為毀壞。 +未來將不再更新該檔案。 + </notification> + <notification name="LocalBitmapsVerifyFail"> + 試圖新增一個無效或無法讀取的圖像檔 [FNAME],該檔無法開啟或解碼。 +已取消這一嘗試。 + </notification> + <notification name="PathfindingReturnMultipleItems"> + 你正退回 [NUM_ITEMS] 個物項。 你確定你要繼續? + <usetemplate ignoretext="確定退回多個物項?" name="okcancelignore" notext="否" yestext="是"/> + </notification> + <notification name="PathfindingDeleteMultipleItems"> + 你正在刪除 [NUM_ITEMS] 個物項。 你確定你要繼續? + <usetemplate ignoretext="確定要刪除多個物項?" name="okcancelignore" notext="否" yestext="是"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml index eccb938f15..1c8b56b3d6 100644 --- a/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="avatar_list_item"> <string name="FormatSeconds"> - [COUNT]s + [COUNT] 秒 </string> <string name="FormatMinutes"> - [COUNT]m + [COUNT] 分 </string> <string name="FormatHours"> - [COUNT]h + [COUNT] 時 </string> <string name="FormatDays"> - [COUNT]d + [COUNT] 日 </string> <string name="FormatWeeks"> - [COUNT]w + [COUNT] 週 </string> <string name="FormatMonths"> - [COUNT]mon + [COUNT] 月 </string> <string name="FormatYears"> - [COUNT]y + [COUNT] 年 </string> - <text name="avatar_name" value="(載入)"/> - <text name="last_interaction" value="0s"/> + <text name="avatar_name" value="(載入中)"/> + <text name="last_interaction" value="0 秒"/> <icon name="permission_edit_theirs_icon" tool_tip="你不能編輯這位朋友的物件"/> <icon name="permission_edit_mine_icon" tool_tip="這位朋友能編輯、刪除或取得你的物件"/> <icon name="permission_map_icon" tool_tip="這位朋友能在地圖上找到你的位置"/> diff --git a/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml index 550868e5e5..fef692c1c5 100644 --- a/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml +++ b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="wearable_item"> <text name="item_name" value="..."/> - <panel name="btn_lock" tool_tip="你並沒有權限進行編輯"/> + <panel name="btn_lock" tool_tip="你沒有編輯權"/> <panel name="btn_edit_panel"> <button name="btn_edit" tool_tip="編輯這個體形"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml index 5e269fcd09..e4e7a661a7 100644 --- a/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="clothing_list_button_bar_panel"> - <button label="Switch" name="switch_btn"/> + <button label="切換" name="switch_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_bottomtray.xml b/indra/newview/skins/default/xui/zh/panel_bottomtray.xml deleted file mode 100644 index 734b83e6cc..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_bottomtray.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="bottom_tray"> - <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> - <string name="SpeakBtnToolTip" value="Turns microphone on/off"/> - <string name="VoiceControlBtnToolTip" value="顯示 / 隱藏 語音控制板"/> - <layout_stack name="toolbar_stack"> - <layout_panel name="speak_panel"> - <talk_button name="talk"> - <speak_button label="Speak" label_selected="Speak" name="speak_btn"/> - </talk_button> - </layout_panel> - <layout_panel name="gesture_panel"> - <gesture_combo_list label="姿勢" name="Gesture" tool_tip="顯示 / 隱藏 姿勢"/> - </layout_panel> - <layout_panel name="movement_panel"> - <bottomtray_button label="移動" name="movement_btn" tool_tip="顯示 / 隱藏 移動控制"/> - </layout_panel> - <layout_panel name="cam_panel"> - <bottomtray_button label="視角" name="camera_btn" tool_tip="顯示 / 隱藏 攝影機控制"/> - </layout_panel> - <layout_panel name="snapshot_panel"> - <bottomtray_button name="snapshots" tool_tip="拍攝快照"/> - </layout_panel> - <layout_panel name="build_btn_panel"> - <bottomtray_button label="建造" name="build_btn" tool_tip="顯示 / 隱藏 建造工具"/> - </layout_panel> - <layout_panel name="search_btn_panel"> - <bottomtray_button label="搜尋" name="search_btn" tool_tip="顯示 / 隱藏 搜尋"/> - </layout_panel> - <layout_panel name="world_map_btn_panel"> - <bottomtray_button label="地圖" name="world_map_btn" tool_tip="顯示 / 隱藏 世界地圖"/> - </layout_panel> - <layout_panel name="mini_map_btn_panel"> - <bottomtray_button label="迷你地圖" name="mini_map_btn" tool_tip="顯示 / 隱藏 迷你地圖"/> - </layout_panel> - <layout_panel name="im_well_panel"> - <chiclet_im_well name="im_well"> - <button name="Unread IM messages" tool_tip="Conversations"/> - </chiclet_im_well> - </layout_panel> - <layout_panel name="notification_well_panel"> - <chiclet_notification name="notification_well"> - <button name="Unread" tool_tip="通知"/> - </chiclet_notification> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml new file mode 100644 index 0000000000..69340349bc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="chiclet_bar"> + <layout_stack name="toolbar_stack"> + <layout_panel name="im_well_panel"> + <chiclet_im_well name="im_well"> + <button name="Unread IM messages" tool_tip="交談"/> + </chiclet_im_well> + </layout_panel> + <layout_panel name="notification_well_panel"> + <chiclet_notification name="notification_well"> + <button name="Unread" tool_tip="通知"/> + </chiclet_notification> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_classified_info.xml b/indra/newview/skins/default/xui/zh/panel_classified_info.xml index cf3113ef1c..6f2dd89318 100644 --- a/indra/newview/skins/default/xui/zh/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/zh/panel_classified_info.xml @@ -16,33 +16,33 @@ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] </panel.string> <panel.string name="auto_renew_on"> - Enabled + 已啟用 </panel.string> <panel.string name="auto_renew_off"> - Disabled + 已停用 </panel.string> - <text name="title" value="Classified Info"/> + <text name="title" value="個人廣告資訊"/> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> <text_editor name="classified_name" value="[name]"/> <text name="classified_location_label" value="位置:"/> <text_editor name="classified_location" value="[loading...]"/> - <text name="content_type_label" value="Content Type:"/> + <text name="content_type_label" value="內容類型:"/> <text_editor name="content_type" value="[content type]"/> - <text name="category_label" value="Category:"/> + <text name="category_label" value="分類:"/> <text_editor name="category" value="[category]"/> - <text name="creation_date_label" value="Creation date:"/> - <text_editor name="creation_date" tool_tip="Creation date" value="[date]"/> - <text name="price_for_listing_label" value="Price for listing:"/> - <text_editor name="price_for_listing" tool_tip="Price for listing." value="[price]"/> + <text name="creation_date_label" value="建立日期:"/> + <text_editor name="creation_date" tool_tip="建立日期" value="[date]"/> + <text name="price_for_listing_label" value="刊登費:"/> + <text_editor name="price_for_listing" tool_tip="刊登費。" value="[price]"/> <layout_stack name="descr_stack"> <layout_panel name="clickthrough_layout_panel"> - <text name="click_through_label" value="Clicks:"/> - <text_editor name="click_through_text" tool_tip="Click through data" value="[clicks]"/> + <text name="click_through_label" value="點按:"/> + <text_editor name="click_through_text" tool_tip="點進資料" value="[clicks]"/> </layout_panel> <layout_panel name="price_layout_panel"> - <text name="auto_renew_label" value="Auto renew:"/> - <text name="auto_renew" value="Enabled"/> + <text name="auto_renew_label" value="自動續訂:"/> + <text name="auto_renew" value="已啟用"/> </layout_panel> <layout_panel name="descr_layout_panel"> <text name="classified_desc_label" value="描述:"/> diff --git a/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml index 1185336a2d..55e72f5347 100644 --- a/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml @@ -2,8 +2,8 @@ <panel name="wearable_item"> <button name="btn_delete" tool_tip="由裝扮移除"/> <text name="item_name" value="..."/> - <panel name="btn_lock" tool_tip="你並沒有權限去編輯"/> + <panel name="btn_lock" tool_tip="你沒有編輯權"/> <panel name="btn_edit_panel"> - <button name="btn_edit" tool_tip="Edit this wearable"/> + <button name="btn_edit" tool_tip="編輯這可穿裝扮"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml index 309ab1c0d4..c074abb568 100644 --- a/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml @@ -2,7 +2,7 @@ <panel name="cof_wearables"> <accordion name="cof_wearables_accordion"> <accordion_tab name="tab_clothing" title="服裝"/> - <accordion_tab name="tab_attachments" title="Attachments"/> + <accordion_tab name="tab_attachments" title="附件"/> <accordion_tab name="tab_body_parts" title="身體部位"/> </accordion> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml index eda4e99a13..32765a3e16 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml @@ -2,11 +2,11 @@ <panel name="edit_alpha_panel"> <scroll_container name="avatar_alpha_color_panel_scroll"> <panel name="avatar_alpha_color_panel"> - <texture_picker label="下半身半透明" name="Lower Alpha" tool_tip="點擊以挑選圖像"/> - <texture_picker label="上半身半透明" name="Upper Alpha" tool_tip="點擊以挑選圖像"/> - <texture_picker label="頭部半透明" name="Head Alpha" tool_tip="點擊以挑選圖像"/> - <texture_picker label="眼睛半透明" name="Eye Alpha" tool_tip="點擊以挑選圖像"/> - <texture_picker label="頭髮半透明" name="Hair Alpha" tool_tip="點擊以挑選圖像"/> + <texture_picker label="下半身半透明" name="Lower Alpha" tool_tip="點按以挑選圖片"/> + <texture_picker label="上半身半透明" name="Upper Alpha" tool_tip="點按以挑選圖片"/> + <texture_picker label="頭部半透明" name="Head Alpha" tool_tip="點按以挑選圖片"/> + <texture_picker label="眼睛半透明" name="Eye Alpha" tool_tip="點按以挑選圖片"/> + <texture_picker label="頭髮半透明" name="Hair Alpha" tool_tip="點按以挑選圖片"/> </panel> </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml index f12701c981..b06ece02ad 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml @@ -1,24 +1,24 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Edit Classified" name="panel_edit_classified"> +<panel label="編輯個人廣告" name="panel_edit_classified"> <panel.string name="location_notice"> (儲存後將會更新) </panel.string> <string name="publish_label"> - Publish + 發布 </string> <string name="save_label"> 儲存 </string> <text name="title"> - Edit Classified + 編輯個人廣告 </text> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> <panel name="snapshot_panel"> - <icon label="" name="edit_icon" tool_tip="點擊以選擇圖像"/> + <icon label="" name="edit_icon" tool_tip="點按以選擇圖像"/> </panel> <text name="Name:"> - Title: + 標題: </text> <text name="description_label"> 描述: @@ -29,16 +29,16 @@ <text name="classified_location"> 載入中... </text> - <button label="Set to Current Location" name="set_to_curr_location_btn"/> - <text name="category_label" value="Category:"/> - <text name="content_type_label" value="Content type:"/> + <button label="設定為目前位置" name="set_to_curr_location_btn"/> + <text name="category_label" value="分類:"/> + <text name="content_type_label" value="內容類型:"/> <icons_combo_box label="一般普級內容" name="content_type"> - <icons_combo_box.item label="適度成人內容" name="mature_ci" value="Mature"/> - <icons_combo_box.item label="一般普級內容" name="pg_ci" value="PG"/> + <icons_combo_box.item label="適度成人內容" name="mature_ci" value="適度成人"/> + <icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/> </icons_combo_box> - <check_box label="Auto renew each week" name="auto_renew"/> - <text name="price_for_listing_label" value="Price for listing:"/> - <spinner label="L$" name="price_for_listing" tool_tip="Price for listing." value="50"/> + <check_box label="每星期自動續訂" name="auto_renew"/> + <text name="price_for_listing_label" value="刊登費:"/> + <spinner label="L$" name="price_for_listing" tool_tip="刊登費。" value="50"/> </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml index 40dd61971a..f44d411908 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_eyes_panel"> <panel name="avatar_eye_color_panel"> - <texture_picker label="Iris" name="Iris" tool_tip="點擊以挑選圖像"/> + <texture_picker label="虹膜" name="Iris" tool_tip="點按以挑選圖片"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml index 7b39e33a9b..d107eea553 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_gloves_panel"> <panel name="avatar_gloves_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_hair.xml b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml index a7440093bc..65f78f9273 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_hair.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_hair_panel"> <panel name="avatar_hair_color_panel"> - <texture_picker label="材質" name="Texture" tool_tip="點擊以挑選圖像"/> + <texture_picker label="材質" name="Texture" tool_tip="點按以挑選圖片"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> <accordion_tab name="hair_color_tab" title="顏色"/> - <accordion_tab name="hair_style_tab" title="Style"/> - <accordion_tab name="hair_eyebrows_tab" title="Eyebrows"/> - <accordion_tab name="hair_facial_tab" title="Facial"/> + <accordion_tab name="hair_style_tab" title="風格"/> + <accordion_tab name="hair_eyebrows_tab" title="眉毛"/> + <accordion_tab name="hair_facial_tab" title="顏面"/> </accordion> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml index dcef070e2e..61e45f911e 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_jacket_panel"> <panel name="avatar_jacket_color_panel"> - <texture_picker label="上半身材質" name="Upper Fabric" tool_tip="點擊以挑選圖像"/> - <texture_picker label="下半身材質" name="Lower Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + <texture_picker label="上半身材質" name="Upper Fabric" tool_tip="點按以挑選圖片"/> + <texture_picker label="下半身材質" name="Lower Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pants.xml b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml index 01b875f1bd..846ed72961 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_pants.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_pants_panel"> <panel name="avatar_pants_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟顏色挑選器"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pick.xml b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml index 6ac7226185..faee42fd0e 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="編輯精選地點" name="panel_edit_pick"> <panel.string name="location_notice"> - (將在儲存後更新) + (儲存後將會更新) </panel.string> <text name="title"> 編輯精選地點 </text> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> - <icon label="" name="edit_icon" tool_tip="點擊以選擇圖像"/> + <icon label="" name="edit_icon" tool_tip="點按以選擇圖像"/> <text name="Name:"> 標題: </text> @@ -29,7 +29,7 @@ <layout_panel name="layout_panel1"> <button label="儲存精選地點" name="save_changes_btn"/> </layout_panel> - <layout_panel name="layout_panel1"> + <layout_panel name="layout_panel2"> <button label="取消" name="cancel_btn"/> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_profile.xml b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml index 7734c3a417..849b82c71a 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml @@ -7,15 +7,15 @@ <string name="RegisterDateFormat"> [REG_DATE] ([AGE]) </string> - <string name="AcctTypeResident" value="Resident"/> - <string name="AcctTypeTrial" value="Trial"/> - <string name="AcctTypeCharterMember" value="Charter Member"/> - <string name="AcctTypeEmployee" value="Linden Lab Employee"/> - <string name="PaymentInfoUsed" value="Payment Info Used"/> - <string name="PaymentInfoOnFile" value="Payment Info On File"/> - <string name="NoPaymentInfoOnFile" value="No Payment Info On File"/> - <string name="AgeVerified" value="Age-verified"/> - <string name="NotAgeVerified" value="Not Age-verified"/> + <string name="AcctTypeResident" value="居民"/> + <string name="AcctTypeTrial" value="試用"/> + <string name="AcctTypeCharterMember" value="老牌 Charter 成員"/> + <string name="AcctTypeEmployee" value="林登實驗室員工"/> + <string name="PaymentInfoUsed" value="使用的付款資料"/> + <string name="PaymentInfoOnFile" value="預留付款資料"/> + <string name="NoPaymentInfoOnFile" value="未預留付款資料"/> + <string name="AgeVerified" value="通過年齡驗證"/> + <string name="NotAgeVerified" value="未通過年齡驗證"/> <string name="partner_edit_link_url"> http://www.secondlife.com/account/partners.php?lang=en </string> @@ -34,22 +34,22 @@ <panel name="second_life_image_panel"> <text name="second_life_photo_title_text" value="[SECOND_LIFE]:"/> </panel> - <icon label="" name="2nd_life_edit_icon" tool_tip="點擊以選擇圖像"/> + <icon label="" name="2nd_life_edit_icon" tool_tip="點按以選擇圖像"/> </panel> <panel name="first_life_image_panel"> <text name="real_world_photo_title_text" value="真實世界:"/> </panel> - <icon label="" name="real_world_edit_icon" tool_tip="點擊以選擇圖像"/> + <icon label="" name="real_world_edit_icon" tool_tip="點按以選擇圖像"/> <text name="title_homepage_text"> 首頁: </text> <line_editor name="homepage_edit" value="http://"/> <text name="title_acc_status_text" value="我的帳戶:"/> - <text_editor name="acc_status_text" value="Resident. No payment info on file."/> + <text_editor name="acc_status_text" value="居民。 未預留付款資料。"/> <text name="my_account_link" value="[[URL] 前往我的塗鴉牆]"/> <text name="title_partner_text" value="我的配偶:"/> <panel name="partner_data_panel"> - <text initial_value="(retrieving)" name="partner_text"/> + <text initial_value="(檢索中)" name="partner_text"/> </panel> <text name="partner_edit_link" value="[[URL] 編輯]"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml index f8ff76aa9b..bc69f2ffc4 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_shirt_panel"> <panel name="avatar_shirt_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟顏色挑選器"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml index 97e43f5753..e190bb5bd8 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_shoes_panel"> <panel name="avatar_shoes_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點擊以開啟顏色挑選器"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skin.xml b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml index fdd6d05ca5..d8552f52f0 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_skin.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_skin_panel"> <panel name="avatar_skin_color_panel"> - <texture_picker label="Head Tattoos" name="Head Tattoos" tool_tip="點擊以挑選圖像"/> - <texture_picker label="Upper Tattoos" name="Upper Tattoos" tool_tip="點擊以挑選圖像"/> - <texture_picker label="Lower Tattoos" name="Lower Tattoos" tool_tip="點擊以挑選圖像"/> + <texture_picker label="頭部" name="Head" tool_tip="點按以挑選圖片"/> + <texture_picker label="上半身" name="Upper Body" tool_tip="點按以挑選圖片"/> + <texture_picker label="下半身" name="Lower Body" tool_tip="點按以挑選圖片"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> - <accordion_tab name="skin_color_tab" title="Skin Color"/> - <accordion_tab name="skin_face_tab" title="Face Detail"/> - <accordion_tab name="skin_makeup_tab" title="Makeup"/> - <accordion_tab name="skin_body_tab" title="Body Detail"/> + <accordion_tab name="skin_color_tab" title="膚色"/> + <accordion_tab name="skin_face_tab" title="臉部細節"/> + <accordion_tab name="skin_makeup_tab" title="化妝"/> + <accordion_tab name="skin_body_tab" title="身體細節"/> </accordion> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml index 10432c16b1..34319fcc01 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_skirt_panel"> <panel name="avatar_skirt_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟顏色挑選器"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_socks.xml b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml index 6727781740..8e19fb5692 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_socks.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_socks_panel"> <panel name="avatar_socks_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟顏色挑選器"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml index 1b34a0e0ee..f5111d629a 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_tattoo_panel"> <panel name="avatar_tattoo_color_panel"> - <texture_picker label="頭部刺青" name="Head Tattoo" tool_tip="點擊以挑選圖像"/> - <texture_picker label="上半身刺青" name="Upper Tattoo" tool_tip="點擊以挑選照片"/> - <texture_picker label="下半身刺青" name="Lower Tattoo" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟顏色挑選器"/> + <texture_picker label="頭部刺青" name="Head Tattoo" tool_tip="點按以挑選圖片"/> + <texture_picker label="上半身刺青" name="Upper Tattoo" tool_tip="點按以挑選圖片"/> + <texture_picker label="下半身刺青" name="Lower Tattoo" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml index 15cae8d233..5ead7c9004 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_underpants_panel"> <panel name="avatar_underpants_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml index 486175eb64..e497e285c9 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="edit_undershirt_panel"> <panel name="avatar_undershirt_color_panel"> - <texture_picker label="材質" name="Fabric" tool_tip="點擊以挑選圖像"/> - <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open Color Picker"/> + <texture_picker label="材質" name="Fabric" tool_tip="點按以挑選圖片"/> + <color_swatch label="顏色/色調" name="Color/Tint" tool_tip="點按以開啟顏色挑選器"/> </panel> <panel name="accordion_panel"> <accordion name="wearable_accordion"> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml index 066b1fd389..4dd7ea6d93 100644 --- a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml @@ -1,43 +1,43 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Wearable" name="panel_edit_wearable"> +<panel label="可穿裝扮" name="panel_edit_wearable"> <string name="edit_shape_title"> - Editing Shape + 體形編輯中 </string> <string name="edit_skin_title"> - Editing Skin + 編輯皮膚 </string> <string name="edit_hair_title"> - Editing Hair + 編輯頭髮 </string> <string name="edit_eyes_title"> - Editing Eyes + 編輯眼睛 </string> <string name="edit_shirt_title"> - Editing Shirt + 編輯襯衫 </string> <string name="edit_pants_title"> - Editing Pants + 編輯褲子 </string> <string name="edit_shoes_title"> - Editing Shoes + 編輯鞋子 </string> <string name="edit_socks_title"> - Editing Socks + 編輯襪子 </string> <string name="edit_jacket_title"> - Editing Jacket + 編輯外套 </string> <string name="edit_skirt_title"> - Editing Skirt + 編輯裙子 </string> <string name="edit_gloves_title"> - Editing Gloves + 編輯手套 </string> <string name="edit_undershirt_title"> - Editing Undershirt + 編輯內衣 </string> <string name="edit_underpants_title"> - Editing Underpants + 編輯內褲 </string> <string name="edit_alpha_title"> 半透明遮罩編輯中 @@ -110,7 +110,7 @@ <panel name="button_panel"> <layout_stack name="button_panel_ls"> <layout_panel name="save_as_btn_lp"> - <button label="另存" name="save_as_button"/> + <button label="另存為" name="save_as_button"/> </layout_panel> <layout_panel name="revert_btn_lp"> <button label="復原變更" name="revert_button"/> diff --git a/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml index 3915e80d43..f468aba514 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml @@ -8,7 +8,7 @@ <button label="群組通話" name="call_btn"/> </layout_panel> <layout_panel name="end_call_btn_panel"> - <button label="結束通話" name="end_call_btn"/> + <button label="離開通話" name="end_call_btn"/> </layout_panel> <layout_panel name="voice_ctrls_btn_panel"> <button label="開啟語音控制" name="voice_ctrls_btn"/> diff --git a/indra/newview/skins/default/xui/zh/panel_group_general.xml b/indra/newview/skins/default/xui/zh/panel_group_general.xml index 55cbf5a617..2b16b61dd1 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_general.xml @@ -1,18 +1,18 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="一般" name="general_tab"> +<panel label="基本資料" name="general_tab"> <panel.string name="help_text"> - The General tab contains general information about this group, a list of members, general Group Preferences and member options. + 基本資料頁籤包含關於群組的基本資訊、成員名單、群組偏好設定和成員選項。 -Hover your mouse over the options for more help. +將滑鼠停懸到選項上,可獲取更多幫助。 </panel.string> <panel.string name="group_info_unchanged"> - 一般群組資訊已經被變更 + 基本群組資訊已經被變更 </panel.string> <panel.string name="incomplete_member_data_str"> - Retrieving member data + 正在擷取成員資料 </panel.string> <panel name="group_info_top"> - <texture_picker label="" name="insignia" tool_tip="點擊以挑選圖像"/> + <texture_picker label="" name="insignia" tool_tip="點按以挑選圖片"/> <text name="prepend_founded_by"> 創辦人: </text> @@ -30,22 +30,22 @@ Hover your mouse over the options for more help. <name_list.columns label="狀態" name="status"/> </name_list> <text name="my_group_settngs_label"> - 自己 + 我自己 </text> <text name="active_title_label"> 我的頭銜: </text> - <combo_box name="active_title" tool_tip="Sets the title that appears in your avatar's name tag when this group is active."/> - <check_box label="接受群組通知" name="receive_notices" tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you."/> - <check_box label="顯示在我的檔案中" name="list_groups_in_profile" tool_tip="Sets whether you want to show this group in your profile"/> + <combo_box name="active_title" tool_tip="這將設定當群組有效時,顯示於你化身名稱標籤的頭銜。"/> + <check_box label="接受群組通知" name="receive_notices" tool_tip="設定你是否要接收來自這群組的通知。 如果該群組對你送出太多垃圾資訊,你可以不要勾選此項目。"/> + <check_box label="顯示在我的檔案中" name="list_groups_in_profile" tool_tip="設定你是否要在你個人檔案上顯示這個群組"/> <panel name="preferences_container"> <text name="group_settngs_label"> 群組 </text> - <check_box label="任何人都可以加入" name="open_enrollement" tool_tip="Sets whether this group allows new members to join without being invited."/> - <check_box label="加入費用" name="check_enrollment_fee" tool_tip="Sets whether to require an enrollment fee to join the group"/> - <spinner label="L$" name="spin_enrollment_fee" tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked."/> - <combo_box name="group_mature_check" tool_tip="Sets whether your group contains information rated as Moderate"> + <check_box label="任何人都可以加入" name="open_enrollement" tool_tip="設定這個群組是否允許新成員未受邀請自行加入。"/> + <check_box label="加入費用" name="check_enrollment_fee" tool_tip="設定是否要徵收群組加入費"/> + <spinner label="L$" name="spin_enrollment_fee" tool_tip="若勾選加入費,新成員必須支付這筆費用才能加入群組。"/> + <combo_box name="group_mature_check" tool_tip="設定你的群組是否含有被訂為適度成人分級的資訊"> <combo_item name="select_mature"> - 選擇內容分級 - </combo_item> diff --git a/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml index db01edcdb3..f979a4c53e 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml @@ -19,7 +19,7 @@ <layout_stack name="layout"> <layout_panel name="group_accordions"> <accordion name="groups_accordion"> - <accordion_tab name="group_general_tab" title="一般"/> + <accordion_tab name="group_general_tab" title="基本資料"/> <accordion_tab name="group_roles_tab" title="角色"/> <accordion_tab name="group_notices_tab" title="通知"/> <accordion_tab name="group_land_tab" title="土地 / 資產"/> diff --git a/indra/newview/skins/default/xui/zh/panel_group_invite.xml b/indra/newview/skins/default/xui/zh/panel_group_invite.xml index 07dcb2303e..8921978b20 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_invite.xml @@ -1,24 +1,27 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="邀請一個成員" name="invite_panel"> <panel.string name="confirm_invite_owner_str"> - Are you sure you want to invite new owner(s)? This action is permanent! + 確定邀請新的所有人? 這動作一旦完成,不能取消! </panel.string> <panel.string name="loading"> (載入中...) </panel.string> <panel.string name="already_in_group"> - Some Residents you chose are already in the group, and so were not sent an invitation. + 你所選的居民有些已經在群組裡,所以不會再對他們發送邀請。 + </panel.string> + <panel.string name="invite_selection_too_large"> + 未送出群組邀請:所選的居民人數太多。 群組邀請每次以 100 人為上限。 </panel.string> <text name="help_text"> - You can select multiple Residents to invite to your group. Click 'Open Resident Chooser' to start. + 你可以選擇邀請多位居民到你的群組來。 點按「開啟居民選擇工具」開始選擇。 </text> - <button label="開啟居民選擇視窗" name="add_button"/> - <name_list name="invitee_list" tool_tip="Hold the Ctrl key and click Resident names to multi-select"/> - <button label="Remove Selected from List" name="remove_button" tool_tip="Removes the Residents selected above from the invite list"/> + <button label="開啟居民選擇工具" name="add_button"/> + <name_list name="invitee_list" tool_tip="按下 Ctrl 鍵同時點選居民的名字,即可選取多個人"/> + <button label="將所選的從名單移除" name="remove_button" tool_tip="將上面所選居民從邀請名單中移除"/> <text name="role_text"> - Choose what Role to assign them to: + 選擇指派給他們的角色: </text> - <combo_box name="role_name" tool_tip="Choose from the list of Roles you are allowed to assign members to"/> + <combo_box name="role_name" tool_tip="從角色清單選擇你有權指派給成員的角色:"/> <button label="送出邀請" name="ok_button"/> <button label="取消" name="cancel_button"/> <string name="GroupInvitation"> diff --git a/indra/newview/skins/default/xui/zh/panel_group_land_money.xml b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml index 5ac7410c8b..81d5573e1c 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Land & L$" name="land_money_tab"> +<panel label="土地和 L$" name="land_money_tab"> <panel.string name="help_text"> - A warning appears until the Total Land in Use is less than or = to the Total Contribution. + 將持續出現警示,直到使用中總土地小於或等於總貢獻面積為止。 </panel.string> <panel.string name="cant_view_group_land_text"> - You don't have permission to view group owned land + 你無權察看群組所有地。 </panel.string> <panel.string name="epmty_view_group_land_text"> 沒有項目 </panel.string> <panel.string name="cant_view_group_accounting_text"> - You don't have permission to view the group's accounting information. + 你無權察看該群組的帳目資料。 </panel.string> <panel.string name="loading_txt"> 載入中... @@ -27,42 +27,42 @@ <scroll_list.columns label="隱藏" name="hidden"/> </scroll_list> <text name="total_contributed_land_label"> - Total contribution: + 總貢獻: </text> <text name="total_contributed_land_value"> - [AREA] m² + [AREA] 平方公尺 </text> <button label="地圖" label_selected="地圖" name="map_button"/> <text name="total_land_in_use_label"> - Total land in use: + 使用中土地總面積: </text> <text name="total_land_in_use_value"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="land_available_label"> - Land available: + 可用土地: </text> <text name="land_available_value"> - [AREA] m² + [AREA] 平方公尺 </text> <text name="your_contribution_label"> 你的捐獻: </text> <text name="your_contribution_units"> - m² + 平方公尺 </text> <text name="your_contribution_max_value"> ([AMOUNT] 最大) </text> <text name="group_over_limit_text"> - More land credits are needed to support land in use + 使用中土地需要更大的土地額度 </text> <text name="group_money_heading"> 群組 L$ </text> </panel> <tab_container name="group_money_tab_container"> - <panel label="PLANNING" name="group_money_planning_tab"> + <panel label="策劃" name="group_money_planning_tab"> <text_editor name="group_money_planning_text"> 載入中... </text_editor> @@ -71,15 +71,15 @@ <text_editor name="group_money_details_text"> 載入中... </text_editor> - <button name="earlier_details_button" tool_tip="Back"/> - <button name="later_details_button" tool_tip="Next"/> + <button name="earlier_details_button" tool_tip="返回"/> + <button name="later_details_button" tool_tip="下一個"/> </panel> <panel label="銷售" name="group_money_sales_tab"> <text_editor name="group_money_sales_text"> 載入中... </text_editor> - <button name="earlier_sales_button" tool_tip="Back"/> - <button name="later_sales_button" tool_tip="Next"/> + <button name="earlier_sales_button" tool_tip="返回"/> + <button name="later_sales_button" tool_tip="下一個"/> </panel> </tab_container> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_notices.xml b/indra/newview/skins/default/xui/zh/panel_group_notices.xml index 26273dd9ce..ba5f4f1bba 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_notices.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="通知" name="notices_tab"> <panel.string name="help_text"> - Notices let you send a message and an optionally attached item. -Notices only go to group members in Roles with the ability to receive Notices. -You can turn off Notices on the General tab. + 通知可讓你傳送訊息並選擇性地附上一個附件。 +通知僅能傳給可接收通知的角色的群組成員。 +你可到基本資料頁籤停用通知功能。 </panel.string> <panel.string name="no_notices_text"> 沒有過去的通知 @@ -21,7 +21,7 @@ You can turn off Notices on the General tab. 沒發現。 </text> <button label="新通知" name="create_new_notice" tool_tip="建立一個新通知"/> - <button name="refresh_notices" tool_tip="Refresh list of notices"/> + <button name="refresh_notices" tool_tip="刷新通知清單。"/> <panel label="建立新通知" name="panel_create_new_notice"> <text name="lbl"> 建立一個通知 @@ -36,19 +36,19 @@ You can turn off Notices on the General tab. 附件: </text> <text name="string"> - 將物品拖曳並丟於此處以添加為附件: + 拖曳並置放物品到這裡,即可添加為附件: </text> <button label="收納區" name="open_inventory" tool_tip="開啟收納區"/> <button name="remove_attachment" tool_tip="由你的通知移除附件"/> <button label="送出" label_selected="送出" name="send_notice"/> - <group_drop_target name="drop_target" tool_tip="Drag an inventory item onto this target box to send it with this notice. You must have permission to copy and transfer the item in order to attach it."/> + <group_drop_target name="drop_target" tool_tip="將一個收納區物項拖曳到這個目標箱框,便可隨通知送出該物項。 你必須有權複製並轉移此物項,才可以附加它。"/> </panel> <panel label="察看過去的通知" name="panel_view_past_notice"> <text name="lbl"> 存檔的通知 </text> <text name="lbl2"> - 要送出一個新通知,點擊 + 按鈕 + 要送出一個新通知,點按 + 按鈕 </text> <text name="lbl3"> 主旨: diff --git a/indra/newview/skins/default/xui/zh/panel_group_notify.xml b/indra/newview/skins/default/xui/zh/panel_group_notify.xml index 00462d8b0b..08a8c94876 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_notify.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_notify.xml @@ -3,10 +3,10 @@ <string name="message_max_lines_count" value="7"/> <string name="subject_font" value="SANSSERIF_BIG"/> <string name="date_font" value="SANSSERIF"/> - <panel label="header" name="header"> - <text name="title" value="Sender Name / Group Name"/> + <panel label="表頭" name="header"> + <text name="title" value="發件者名/群組名"/> </panel> <text_editor name="message" value="訊息"/> - <text name="attachment" value="Attachment"/> + <text name="attachment" value="附件"/> <button label="確定" name="btn_ok"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_roles.xml b/indra/newview/skins/default/xui/zh/panel_group_roles.xml index cf5fc26d14..59086c3de2 100644 --- a/indra/newview/skins/default/xui/zh/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/zh/panel_group_roles.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="成員與角色" name="roles_tab"> <panel.string name="default_needs_apply_text"> - 未儲存的設定 + 變更未儲存 </panel.string> <panel.string name="want_apply_text"> 你要儲存你的變更嗎? @@ -11,10 +11,10 @@ <panel.string name="help_text"> 你可以添加或移除一個角色指派給成員。 選責多個成員時同時按著 Ctrl 鍵且 -使用滑鼠左鍵點擊他們的名字。 +使用滑鼠左鍵點按他們的名字。 </panel.string> <panel.string name="donation_area"> - [AREA] m² + [AREA] 平方公尺 </panel.string> <filter_editor label="成員過濾器" name="filter_input"/> <name_list name="member_list"> @@ -27,13 +27,12 @@ </panel> <panel label="角色" name="roles_sub_tab"> <panel.string name="help_text"> - Roles have a title and an allowed list of Abilities -that Members can perform. Members can belong to -one or more Roles. A group can have up to 10 Roles, -including the Everyone and Owner Roles. + 一個角色具備職稱和該角色可使用的能力。 +一位成員可有一到多個角色。 +一個群組至多可有 10 個角色,包括「任何人」和「所有人」。 </panel.string> <panel.string name="cant_delete_role"> - The 'Everyone' and 'Owners' Roles are special and can't be deleted. + 「任何人」和「所有人」是特設角色,不得刪除。 </panel.string> <filter_editor label="角色過濾器" name="filter_input"/> <scroll_list name="role_list"> @@ -44,13 +43,13 @@ including the Everyone and Owner Roles. <button label="新角色" name="role_create"/> <button label="刪除角色" name="role_delete"/> </panel> - <panel label="能力" name="actions_sub_tab" tool_tip="You can view an Ability's Description and which Roles and Members can execute the Ability."> + <panel label="能力" name="actions_sub_tab" tool_tip="你可察看關於某一能力的說明,並得知哪些角色和成員擁有該能力。"> <panel.string name="help_text"> - Abilities allow Members in Roles to do specific -things in this group. There's a broad variety of Abilities. + 「能力」可讓群組的成員透過角色行使一定的職權。 +能力的種類繁多。 </panel.string> <filter_editor label="能力過濾器" name="filter_input"/> - <scroll_list name="action_list" tool_tip="Select an Ability to view more details"/> + <scroll_list name="action_list" tool_tip="請選取一個能力以察看詳情。"/> </panel> </tab_container> <panel name="members_footer"> @@ -60,7 +59,7 @@ things in this group. There's a broad variety of Abilities. <text name="static2"> 允許的能力 </text> - <scroll_list name="member_allowed_actions" tool_tip="想瞭解有關於允許的能力的細節請查閱能力頁籤"/> + <scroll_list name="member_allowed_actions" tool_tip="想瞭解每一項允許的能力的詳情請查閱能力頁籤。"/> </panel> <panel name="roles_footer"> <text name="static"> @@ -75,15 +74,15 @@ things in this group. There's a broad variety of Abilities. <text name="static4"> 指派角色 </text> - <check_box label="Reveal members" name="role_visible_in_list" tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."/> + <check_box label="顯示成員" name="role_visible_in_list" tool_tip="設定是否讓群組外的人在「一般」頁籤上察看到此角色的成員。"/> <text name="static5"> 允許的能力 </text> - <scroll_list name="role_allowed_actions" tool_tip="想瞭解有關於每一項允許的能力的細節請查閱能力頁籤"/> + <scroll_list name="role_allowed_actions" tool_tip="想瞭解每一項允許的能力的詳情請查閱能力頁籤。"/> </panel> <panel name="actions_footer"> <text_editor name="action_description"> - This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner. + 這個能力可「將會員自本群組踢出」。 必須是所有人才可踢出另一位所有人。 </text_editor> <text name="static2"> 有此能力的角色 diff --git a/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml index 703182e04d..e937368a2b 100644 --- a/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml @@ -8,7 +8,7 @@ <button label="加為朋友" name="add_friend_btn"/> </layout_panel> <layout_panel name="teleport_btn_panel"> - <button label="瞬間傳送" name="teleport_btn" tool_tip="Offer to teleport this person"/> + <button label="瞬間傳送" name="teleport_btn" tool_tip="發出瞬間傳送邀請給此人"/> </layout_panel> <layout_panel name="share_btn_panel"> <button label="分享" name="share_btn"/> diff --git a/indra/newview/skins/default/xui/zh/panel_landmark_info.xml b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml index d86ba7bc7c..b50aa24d3f 100644 --- a/indra/newview/skins/default/xui/zh/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml @@ -3,22 +3,22 @@ <string name="title_create_landmark" value="創造地標"/> <string name="title_edit_landmark" value="編輯地標"/> <string name="title_landmark" value="地標"/> - <string name="not_available" value="(N\A)"/> + <string name="not_available" value="(不適用)"/> <string name="unknown" value="(未知)"/> <string name="public" value="(公開)"/> <string name="server_update_text"> - Place information not available without server update. + 地點資訊因無伺服器更新故無法提供。 </string> <string name="server_error_text"> - Information about this location is unavailable at this time, please try again later. + 目前無法取得此位置的訊息,請稍候再試。 </string> <string name="server_forbidden_text"> - Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner. + 權限不足,無法取得此位置的資訊。 請向地段所有人查詢你的權限。 </string> <string name="acquired_date"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] </string> - <button name="back_btn" tool_tip="Back"/> + <button name="back_btn" tool_tip="返回"/> <text name="title" value="地點檔案"/> <scroll_container name="place_scroll"> <panel name="scrolling_panel"> @@ -27,13 +27,13 @@ <expandable_text name="description" value="Du waltz die spritz"/> <text name="maturity_value" value="未知"/> <panel name="landmark_info_panel"> - <text name="owner_label" value="擁有者:"/> + <text name="owner_label" value="所有人:"/> <text name="creator_label" value="創造者:"/> <text name="created_label" value="創造於:"/> </panel> <panel name="landmark_edit_panel"> - <text name="title_label" value="Title:"/> - <text name="notes_label" value="My notes:"/> + <text name="title_label" value="標題:"/> + <text name="notes_label" value="我的記事:"/> <text name="folder_label" value="地標位置:"/> </panel> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_login.xml b/indra/newview/skins/default/xui/zh/panel_login.xml index b227fbcfc8..672d9bb1a2 100644 --- a/indra/newview/skins/default/xui/zh/panel_login.xml +++ b/indra/newview/skins/default/xui/zh/panel_login.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_login"> - <panel.string name="create_account_url"> - http://join.secondlife.com/ - </panel.string> <panel.string name="forgot_password_url"> http://secondlife.com/account/request.php </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> + <text name="log_in_text"> + 登入 + </text> <text name="username_text"> 使用者名稱: </text> @@ -15,34 +15,32 @@ <text name="password_text"> 密碼: </text> - <check_box label="記住密碼:" name="remember_check"/> - <button label="登入" name="connect_btn"/> - <text name="mode_selection_text"> - 模式: - </text> - <combo_box name="mode_combo" tool_tip="請選擇你的模式。選用基本模式可以快速、簡單地探索與聊天;選用進階模式則可以使用更多功能。"> - <combo_box.item label="基本" name="Basic"/> - <combo_box.item label="進階" name="Advanced"/> - </combo_box> + </layout_panel> + <layout_panel name="start_location_panel"> <text name="start_location_text"> 開始地點: </text> <combo_box name="start_location_combo"> <combo_box.item label="我上一次位置" name="MyLastLocation"/> <combo_box.item label="我的家" name="MyHome"/> - <combo_box.item label="< 請輸入地區名稱 >" name="Typeregionname"/> + <combo_box.item label="<請輸入地區名稱>" name="Typeregionname"/> </combo_box> </layout_panel> - <layout_panel name="links"> - <text name="create_new_account_text"> - 註冊 + <layout_panel name="links_login_panel"> + <text name="login_help"> + 登入時需要幫助? </text> <text name="forgot_password_text"> 忘記你的使用者名稱或密碼? </text> - <text name="login_help"> - 登入時需要幫助? + <button label="登入" name="connect_btn"/> + <check_box label="記住密碼:" name="remember_check"/> + </layout_panel> + <layout_panel name="links"> + <text name="create_account_text"> + 建立你的帳號 </text> + <button label="現在就開始" name="create_new_account_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml index 53ecf3eb19..0ad3d8506d 100644 --- a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="事物" name="main inventory panel"> <panel.string name="ItemcountFetching"> - Fetching [ITEM_COUNT] Items... [FILTER] + 正在擷取 [ITEM_COUNT] 個物項… [FILTER] </panel.string> <panel.string name="ItemcountCompleted"> [ITEM_COUNT] 物品 [FILTER] diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml index a236dfc17a..aad1348e46 100644 --- a/indra/newview/skins/default/xui/zh/panel_me.xml +++ b/indra/newview/skins/default/xui/zh/panel_me.xml @@ -1,7 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="我的檔案" name="panel_me"> - <tab_container name="tabs"> - <panel label="我的檔案" name="panel_profile"/> - <panel label="我的精選地點" name="panel_picks"/> - </tab_container> +<panel label="我的個人檔案" name="panel_me"> + <panel label="我的精選地點" name="panel_picks"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml index 321c003acd..0c11befcf5 100644 --- a/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="一般" name="Media Settings General"> +<panel label="基本設定" name="Media Settings General"> <text name="home_label"> 首頁: </text> <text name="home_fails_whitelist_label"> - (This page does not pass the specified whitelist) + (這頁面未通過所指定的許可清單) </text> - <line_editor name="home_url" tool_tip="The home page for this media source"/> + <line_editor name="home_url" tool_tip="這個媒體來源的首頁"/> <text name="preview_label"> 預覽 </text> <text name="current_url_label"> 目前頁面: </text> - <text name="current_url" tool_tip="The current page for this media source" value=""/> + <text name="current_url" tool_tip="這個媒體來源目前的頁面" value=""/> <button label="重設" name="current_url_reset_btn"/> - <check_box initial_value="false" label="Auto Loop" name="auto_loop"/> - <check_box initial_value="false" label="First Click Interacts" name="first_click_interact"/> + <check_box initial_value="false" label="自動連續播放" name="auto_loop"/> + <check_box initial_value="false" label="第一次點擊將進行互動" name="first_click_interact"/> <check_box initial_value="false" label="自動縮放" name="auto_zoom"/> <check_box initial_value="false" label="自動播放媒體" name="auto_play"/> <text name="media_setting_note"> - Note: Residents can override this setting + 注意:居民可以否定這項設定 </text> - <check_box initial_value="false" label="Auto Scale Media on Face of Object" name="auto_scale"/> + <check_box initial_value="false" label="物件臉部媒體自動調整比例" name="auto_scale"/> <text name="size_label"> 尺寸: </text> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml index 173edc76f6..4a1eaef3a1 100644 --- a/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml @@ -12,7 +12,7 @@ </combo_item> </combo_box> <text name="owner_label"> - 擁有者 + 所有人 </text> <check_box initial_value="false" label="允許導航與互動" name="perms_owner_interact"/> <check_box initial_value="false" label="顯示控制列" name="perms_owner_control"/> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml index aaaf6bfb94..da84d6fe02 100644 --- a/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Security" name="Media Settings Security"> - <check_box initial_value="false" label="Only Allow Access to Specified URL patterns" name="whitelist_enable"/> +<panel label="安全" name="Media Settings Security"> + <check_box initial_value="false" label="只允許進入符合特定形態的 URL 目標" name="whitelist_enable"/> <text name="home_url_fails_some_items_in_whitelist"> - Entries that the home page fails against are marked: + 被首頁視為出錯的物項已標示: </text> <button label="添加" name="whitelist_add"/> <button label="刪除" name="whitelist_del"/> <text name="home_url_fails_whitelist"> - Warning: the home page specified in the General tab fails to pass this whitelist. It has been disabled until a valid entry has been added. + 警告:在基本資料頁籤裡指定的首頁,未能通過這一許可清單。 它已被停用,請設定有效的資料。 </text> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml index 60a5767d09..7a11aa961b 100644 --- a/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml @@ -1,18 +1,23 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="navigation_bar"> - <panel name="navigation_panel"> - <pull_button name="back_btn" tool_tip="前往上一個位置"/> - <pull_button name="forward_btn" tool_tip="前往下一個位置"/> - <button name="home_btn" tool_tip="瞬間傳送到我家的位置"/> - <location_input label="位置" name="location_combo"/> - <search_combo_box label="搜尋" name="search_combo_box" tool_tip="搜尋"> - <combo_editor label="搜尋 [SECOND_LIFE]" name="search_combo_editor"/> - </search_combo_box> - </panel> - <favorites_bar name="favorite" tool_tip="拖曳傳送地標到此以便讓你在第二人生中能快速傳送到你最愛的地點!!"> - <label name="favorites_bar_label" tool_tip="拖曳傳送地標到此以便讓你在第二人生中能快速傳送到你最愛的地點!!"> - 最愛列 - </label> - <chevron_button name=">>" tool_tip="顯示更多我的最愛"/> - </favorites_bar> + <layout_stack name="nvp_stack"> + <layout_panel name="navigation_layout_panel"> + <panel name="navigation_panel"> + <pull_button name="back_btn" tool_tip="前往上一個位置"/> + <pull_button name="forward_btn" tool_tip="前往下一個位置"/> + <button name="home_btn" tool_tip="瞬間返回我的家"/> + <location_input label="位置" name="location_combo"/> + </panel> + </layout_panel> + <layout_panel name="favorites_layout_panel"> + <favorites_bar name="favorite" tool_tip="拖曳傳送地標到此以便讓你在第二人生中能快速傳送到你最愛的地點!!"> + <label name="favorites_bar_label" tool_tip="拖曳傳送地標到此以便讓你在第二人生中能快速傳送到你最愛的地點!!"> + 最愛列 + </label> + <more_button name=">>" tool_tip="顯示更多我的最愛"> + 詳情 ▼ + </more_button> + </favorites_bar> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml new file mode 100644 index 0000000000..bb52c13a11 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_navmesh_rebake"> + <button label="重新產出地區" name="navmesh_btn" tool_tip="點按即可重新產出該地區的導航網面。"/> + <button label="正在請求重新產出" name="navmesh_btn_sending" tool_tip="正向伺服器發送重新產出請求。"/> + <button label="地區正在重新產出" name="navmesh_btn_baking" tool_tip="地區正在重新產出。 完成後,這個按鈕將會消失。"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml new file mode 100644 index 0000000000..fc52168bb7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="nearby_chat"> + <layout_stack name="stack"> + <layout_panel name="translate_chat_checkbox_lp"> + <check_box label="翻譯聊天內容" name="translate_chat_checkbox"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml index 3cabfcfaba..4361b588d8 100644 --- a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="chat_bar"> - <line_editor label="點擊此處開始聊天。" name="chat_box" tool_tip="按下 Enter 鍵來說或按下 Ctrl+Enter 來喊叫"/> + <line_editor label="點按此處開始聊天。" name="chat_box" tool_tip="按下 Enter 鍵來說或按下 Ctrl+Enter 來喊叫"/> <button name="show_nearby_chat" tool_tip="顯示 / 隱藏 附近的聊天紀錄"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_media.xml b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml index 6a4b5fcf35..c11a7a088b 100644 --- a/indra/newview/skins/default/xui/zh/panel_nearby_media.xml +++ b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="nearby_media"> <string name="media_item_count_format"> - (%ld media items) + (%ld 項媒體物件) </string> <string name="empty_item_text"> - <empty> + <空白> </string> <string name="parcel_media_name"> 地段串流媒體 @@ -18,8 +18,8 @@ <panel name="minimized_controls"> <button label="全部停止" name="all_nearby_media_disable_btn" tool_tip="關閉附近全部的媒體"/> <button label="全部開始" name="all_nearby_media_enable_btn" tool_tip="開啟附近全部的媒體"/> - <button name="open_prefs_btn" tool_tip="Bring up media prefs"/> - <button label="更多 >>" label_selected="<< 更少" name="more_btn" tool_tip="進階控制"/> + <button name="open_prefs_btn" tool_tip="打開媒體偏好設定"/> + <button label="細節>>" label_selected="<<基本" name="more_btn" tool_tip="進階控制"/> </panel> <panel name="nearby_media_panel"> <text name="nearby_media_title"> @@ -35,9 +35,9 @@ <combo_box.item label="在其他化身身上" name="OnOthers"/> </combo_box> <scroll_list name="media_list"> - <scroll_list.columns label="Proximity" name="media_proximity"/> - <scroll_list.columns label="Visible" name="media_visibility"/> - <scroll_list.columns label="Class" name="media_class"/> + <scroll_list.columns label="鄰近" name="media_proximity"/> + <scroll_list.columns label="可看到" name="media_visibility"/> + <scroll_list.columns label="類型" name="media_class"/> <scroll_list.columns label="名稱" name="media_name"/> <scroll_list.columns label="除錯" name="media_debug"/> </scroll_list> @@ -59,10 +59,10 @@ <button name="mute_btn" tool_tip="靜音所選擇的媒體音頻"/> </layout_panel> <layout_panel name="zoom"> - <button name="zoom_btn" tool_tip="Zoom into selected media"/> + <button name="zoom_btn" tool_tip="以所選媒體為中心放大"/> </layout_panel> <layout_panel name="unzoom"> - <button name="unzoom_btn" tool_tip="Zoom back from selected media"/> + <button name="unzoom_btn" tool_tip="縮小遠離所選媒體"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml new file mode 100644 index 0000000000..8de0bb0e4d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<outbox_inventory_panel name="inventory_outbox" tool_tip="將物項拖曳並置放到這裡,準備在你的商店出售"/> diff --git a/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml index 263106d13a..a698da0ab1 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml @@ -5,7 +5,7 @@ <string name="unsaved_changes" value="變更未儲存"/> <string name="now_editing" value="現在編輯中"/> <panel.string name="not_available"> - (N\A) + (不適用) </panel.string> <panel.string name="unknown"> (未知) @@ -15,7 +15,7 @@ <string name="Filter.Objects" value="物件"/> <string name="Filter.Clothing" value="服裝"/> <string name="Filter.Bodyparts" value="身體部位"/> - <string name="replace_body_part" value="點擊以取代你現存的體形"/> + <string name="replace_body_part" value="點按以取代你現存的體形"/> <text name="title" value="編輯裝扮"/> <panel name="header_panel"> <panel name="outfit_name_and_status"> @@ -39,10 +39,10 @@ </layout_panel> </layout_stack> <panel name="no_add_wearables_button_bar"> - <button name="shop_btn_1" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/> + <button name="shop_btn_1" tool_tip="前往第二人生購物市集。 你也可選擇你穿著中的一個物件,再點按這裡察看其他同類物件。"/> </panel> <panel name="add_wearables_button_bar"> - <button name="shop_btn_2" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/> + <button name="shop_btn_2" tool_tip="前往第二人生購物市集。 你也可選擇你穿著中的一個物件,再點按這裡察看其他同類物件。"/> </panel> <panel name="save_revert_button_bar"> <layout_stack name="button_bar_ls"> @@ -50,7 +50,7 @@ <button label="儲存" name="save_btn"/> </layout_panel> <layout_panel name="revert_btn_lp"> - <button label="復原變更" name="revert_btn" tool_tip="Revert to last saved version"/> + <button label="復原變更" name="revert_btn" tool_tip="恢復上一個已儲存版本"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml index d9718d8294..8dd93543c0 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml @@ -4,19 +4,19 @@ 穿上所選擇的裝扮 </panel.string> <panel.string name="wear_items_tooltip"> - Wear selected items + 穿上所選擇的物件 </panel.string> <tab_container name="appearance_tabs"> <panel label="我的裝扮" name="outfitslist_tab"/> - <panel label="WEARING" name="cof_tab"/> + <panel label="目前穿著" name="cof_tab"/> </tab_container> <panel name="bottom_panel"> <layout_stack name="bottom_panel_ls"> <layout_panel name="save_btn_lp"> - <button label="另存" name="save_btn"/> + <button label="另存為" name="save_btn"/> </layout_panel> <layout_panel name="wear_btn_lp"> - <button label="Wear" name="wear_btn"/> + <button label="穿上" name="wear_btn"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_list.xml b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml index a4b041469b..cfb0180f9c 100644 --- a/indra/newview/skins/default/xui/zh/panel_outfits_list.xml +++ b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml @@ -1,5 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Outfits"> + <accordion name="outfits_accordion"> + <no_matched_tabs_text name="no_matched_outfits_msg" value="找不到你要找的嗎? 請試試 [secondlife:///app/search/places/ 搜尋]。"/> + <no_visible_tabs_text name="no_outfits_msg" value="你還沒有任何裝扮。 請試試[secondlife:///app/search/all/ 搜尋]"/> + </accordion> <panel name="bottom_panel"> <menu_button name="options_gear_btn" tool_tip="顯示額外選項"/> <button name="trash_btn" tool_tip="刪除所選擇的裝扮"/> diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml index 9c265622fa..59ea7b70e2 100644 --- a/indra/newview/skins/default/xui/zh/panel_people.xml +++ b/indra/newview/skins/default/xui/zh/panel_people.xml @@ -1,23 +1,23 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Side tray panel --> <panel label="人群" name="people_panel"> - <string name="no_recent_people" value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/> - <string name="no_filtered_recent_people" value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/> - <string name="no_one_near" value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/> - <string name="no_one_filtered_near" value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/> + <string name="no_recent_people" value="沒有最近的人。 想找人見面聊天? 請試試[secondlife:///app/search/people 搜尋]或[secondlife:///app/worldmap 世界地圖]。"/> + <string name="no_filtered_recent_people" value="找不到你要找的嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] 搜尋]。"/> + <string name="no_one_near" value="附近無人。 想找人見面聊天? 請試試[secondlife:///app/search/people 搜尋]或[secondlife:///app/worldmap 世界地圖]。"/> + <string name="no_one_filtered_near" value="找不到你要找的嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] 搜尋]。"/> <string name="no_friends_online" value="無朋友上線"/> <string name="no_friends" value="無朋友"/> <string name="no_friends_msg"> - Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend. -Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map]. + 用 [secondlife:///app/search/people 搜尋] 找朋友,或選擇一位居民,再按右鍵將他加為朋友。 +想找人見面聊天? 請試一試 [secondlife:///app/worldmap 世界地圖]。 </string> <string name="no_filtered_friends_msg"> - Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]. + 找不到你要找的嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] 搜尋]。 </string> <string name="people_filter_label" value="人員過濾器"/> <string name="groups_filter_label" value="群組過濾器"/> - <string name="no_filtered_groups_msg" value="沒有發現你要找的嗎?何不試試 [secondlife:///app/search/groups/[SEARCH_TERM] 搜尋]。"/> - <string name="no_groups_msg" value="想找尋群組加入嗎?何不試試 [secondlife:///app/search/groups 搜尋]。"/> + <string name="no_filtered_groups_msg" value="找不到你要找的嗎? 請試試[secondlife:///app/search/groups/[SEARCH_TERM] 搜尋]。"/> + <string name="no_groups_msg" value="要尋找群組考慮加入嗎? 請試試[secondlife:///app/search/groups 搜尋]。"/> <string name="MiniMapToolTipMsg" value="[REGION](雙擊以開啟地圖,按下 shift 鍵拖曳來平移)"/> <string name="AltMiniMapToolTipMsg" value="[REGION](雙擊以瞬間傳送,按下 shift 鍵拖曳來平移)"/> <filter_editor label="過濾器" name="filter_input"/> @@ -25,7 +25,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M <panel label="附近" name="nearby_panel"> <panel label="bottom_panel" name="bottom_panel"> <menu_button name="nearby_view_sort_btn" tool_tip="選項"/> - <button name="add_friend_btn" tool_tip="添加已選擇的居民到Ad你的朋友清單"/> + <button name="add_friend_btn" tool_tip="添加所選的居民到你的朋友清單"/> </panel> </panel> <panel label="我的朋友" name="friends_panel"> @@ -39,7 +39,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M <menu_button name="friends_viewsort_btn" tool_tip="顯示額外選項"/> </layout_panel> <layout_panel name="add_btn_panel"> - <button name="add_btn" tool_tip="向居民提出加為好友邀請"/> + <button name="add_btn" tool_tip="向居民發出交友邀請"/> </layout_panel> <layout_panel name="trash_btn_panel"> <dnd_button name="del_btn" tool_tip="由你的朋友清單移除所選擇的人"/> @@ -66,17 +66,17 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M <layout_panel name="view_profile_btn_lp"> <button label="檔案" name="view_profile_btn" tool_tip="顯示圖片、群組與其他居民資訊"/> </layout_panel> - <layout_panel name="chat_btn_lp"> + <layout_panel name="im_btn_lp"> <button label="IM" name="im_btn" tool_tip="開啟即時訊息會話"/> </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="通話" name="call_btn" tool_tip="與此居民進行通話"/> + <layout_panel name="call_btn_lp"> + <button label="通話" name="call_btn" tool_tip="和這位居民通話"/> </layout_panel> - <layout_panel name="chat_btn_lp"> + <layout_panel name="share_btn_lp"> <button label="分享" name="share_btn" tool_tip="分享一個收納區物品"/> </layout_panel> - <layout_panel name="chat_btn_lp"> - <button label="瞬間傳送" name="teleport_btn" tool_tip="發給瞬間傳送請求"/> + <layout_panel name="teleport_btn_lp"> + <button label="瞬間傳送" name="teleport_btn" tool_tip="發出瞬間傳送邀請"/> </layout_panel> </layout_stack> <layout_stack name="bottom_bar_ls1"> diff --git a/indra/newview/skins/default/xui/zh/panel_picks.xml b/indra/newview/skins/default/xui/zh/panel_picks.xml index 15733b71b0..98d36eaea0 100644 --- a/indra/newview/skins/default/xui/zh/panel_picks.xml +++ b/indra/newview/skins/default/xui/zh/panel_picks.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="精選地點" name="panel_picks"> <string name="no_picks" value="無精選地點"/> - <string name="no_classifieds" value="No Classifieds"/> + <string name="no_classifieds" value="禁止個人廣告"/> <accordion name="accordion"> <accordion_tab name="tab_picks" title="精選地點"/> - <accordion_tab name="tab_classifieds" title="Classifieds"/> + <accordion_tab name="tab_classifieds" title="個人廣告"/> </accordion> <panel label="bottom_panel" name="edit_panel"> <layout_stack name="edit_panel_ls"> diff --git a/indra/newview/skins/default/xui/zh/panel_place_profile.xml b/indra/newview/skins/default/xui/zh/panel_place_profile.xml index 1772b65434..a364f732d8 100644 --- a/indra/newview/skins/default/xui/zh/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/zh/panel_place_profile.xml @@ -1,20 +1,20 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="place_profile"> - <string name="on" value="On"/> - <string name="off" value="Off"/> - <string name="anyone" value="Anyone"/> - <string name="available" value="available"/> + <string name="on" value="啟動"/> + <string name="off" value="關閉"/> + <string name="anyone" value="任何人"/> + <string name="available" value="可用的"/> <string name="allocated" value="已分配"/> <string name="title_place" value="地點檔案"/> <string name="title_teleport_history" value="瞬間傳送歷史紀錄"/> - <string name="not_available" value="(N\A)"/> + <string name="not_available" value="(不適用)"/> <string name="unknown" value="(未知)"/> <string name="public" value="(公開)"/> <string name="none_text" value="(無)"/> <string name="sale_pending_text" value="(擱置銷售)"/> - <string name="group_owned_text" value="(群組所擁有)"/> + <string name="group_owned_text" value="(由群組所擁有)"/> <string name="price_text" value="L$"/> - <string name="area_text" value="m²"/> + <string name="area_text" value="平方公尺"/> <string name="all_residents_text" value="全部居民"/> <string name="group_text" value="群組"/> <string name="can_resell"> @@ -33,10 +33,10 @@ 地點資訊因無伺服器更新故無法提供。 </string> <string name="server_error_text"> - Information about this location is unavailable at this time, please try again later. + 目前無法取得此位置的訊息,請稍候再試。 </string> <string name="server_forbidden_text"> - Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner. + 權限不足,無法取得此位置的資訊。 請向地段所有人查詢你的權限。 </string> <string name="acquired_date"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -48,7 +48,7 @@ <text name="region_title" value="SampleRegion"/> <text name="parcel_title" value="SampleParcel, Name Long (145, 228, 26)"/> <expandable_text name="description" value="Du waltz die spritz"/> - <text name="owner_label" value="擁有者:"/> + <text name="owner_label" value="所有人:"/> <text name="owner_value" value="Alex Superduperlongenamenton"/> <text name="maturity_value" value="未知"/> <accordion name="advanced_info_accordion"> @@ -57,18 +57,20 @@ <text name="rating_label" value="分級:"/> <text name="rating_value" value="未知"/> <text name="voice_label" value="語音:"/> - <text name="voice_value" value="On"/> + <text name="voice_value" value="啟動"/> <text name="fly_label" value="飛行:"/> - <text name="fly_value" value="On"/> + <text name="fly_value" value="啟動"/> <text name="push_label" value="推撞:"/> - <text name="push_value" value="Off"/> + <text name="push_value" value="關閉"/> <text name="build_label" value="建造:"/> - <text name="build_value" value="On"/> + <text name="build_value" value="啟動"/> <text name="scripts_label" value="腳本:"/> - <text name="scripts_value" value="On"/> + <text name="scripts_value" value="啟動"/> <text name="damage_label" value="傷害:"/> - <text name="damage_value" value="Off"/> - <button label="關於土地" name="about_land_btn"/> + <text name="damage_value" value="關閉"/> + <text name="see_avatars_label" value="察看化身:"/> + <text name="see_avatars_value" value="關閉"/> + <button label="土地資料" name="about_land_btn"/> </panel> </accordion_tab> <accordion_tab name="region_information_tab" title="地區"> @@ -79,21 +81,21 @@ <text name="region_type" value="Moose"/> <text name="region_rating_label" value="分級:"/> <text name="region_rating" value="完全成人"/> - <text name="region_owner_label" value="擁有者:"/> + <text name="region_owner_label" value="所有人:"/> <text name="region_owner" value="moose Van Moose extra long name moose"/> <text name="region_group_label" value="群組:"/> <text name="region_group"> The Mighty Moose of mooseville soundvillemoose </text> - <button label="地區 / 領地" name="region_info_btn"/> + <button label="地區/領地" name="region_info_btn"/> </panel> </accordion_tab> <accordion_tab name="estate_information_tab" title="領地"> <panel name="estate_information_panel"> <text name="estate_name_label" value="領地:"/> <text name="estate_rating_label" value="分級:"/> - <text name="estate_owner_label" value="擁有者:"/> - <text name="estate_owner" value="Testing owner name length with long name"/> + <text name="estate_owner_label" value="所有人:"/> + <text name="estate_owner" value="正在測試名稱很長很長很長的所有人名稱…"/> <text name="covenant_label" value="契約:"/> </panel> </accordion_tab> diff --git a/indra/newview/skins/default/xui/zh/panel_places.xml b/indra/newview/skins/default/xui/zh/panel_places.xml index 8ac464271e..08cae610f6 100644 --- a/indra/newview/skins/default/xui/zh/panel_places.xml +++ b/indra/newview/skins/default/xui/zh/panel_places.xml @@ -8,7 +8,7 @@ <layout_panel name="lp1"> <layout_stack name="bottom_bar_ls1"> <layout_panel name="teleport_btn_lp"> - <button label="瞬間傳送" name="teleport_btn" tool_tip="瞬間傳送到所選擇的區域"/> + <button label="瞬間傳送" name="teleport_btn" tool_tip="瞬間傳送到所選的區域"/> </layout_panel> <layout_panel name="chat_btn_lp"> <button label="地圖" name="map_btn" tool_tip="在世界地圖上顯示相對應的區域"/> @@ -24,7 +24,7 @@ <menu_button name="overflow_btn" tool_tip="顯示額外選項"/> </layout_panel> </layout_stack> - <layout_stack name="bottom_bar_ls3"> + <layout_stack name="bottom_bar_profile_ls"> <layout_panel name="profile_btn_lp"> <button label="檔案" name="profile_btn" tool_tip="顯示地點檔案"/> </layout_panel> diff --git a/indra/newview/skins/default/xui/zh/floater_postcard.xml b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml index 6f6b75f468..563c4fca3c 100644 --- a/indra/newview/skins/default/xui/zh/floater_postcard.xml +++ b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml @@ -1,33 +1,21 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="EMAIL SNAPSHOT"> - <floater.string name="default_subject"> - Postcard from [SECOND_LIFE]. - </floater.string> - <floater.string name="default_message"> - Check this out! - </floater.string> - <floater.string name="upload_message"> - 傳送中... - </floater.string> +<panel name="panel_postcard_message"> <text name="to_label"> - 收件人電子郵件地址: - </text> - <text name="from_label"> - 你的電子郵件地址: + 收件人: </text> <text name="name_label"> - 你的名稱: + 發件人: </text> <text name="subject_label"> 主旨: </text> <line_editor label="在此輸入你的主旨。" name="subject_form"/> <text name="msg_label"> - 訓息: + 訊息: </text> <text_editor name="msg_form"> 在此輸入你的訊息。 </text_editor> <button label="取消" name="cancel_btn"/> <button label="送出" name="send_btn"/> -</floater> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml b/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml new file mode 100644 index 0000000000..900ab3a54e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_postcard_settings"> + <combo_box label="解析度" name="postcard_size_combo"> + <combo_box.item label="目前視窗" name="CurrentWindow"/> + <combo_box.item label="640x480" name="640x480"/> + <combo_box.item label="800x600" name="800x600"/> + <combo_box.item label="1024x768" name="1024x768"/> + <combo_box.item label="自訂" name="Custom"/> + </combo_box> + <layout_stack name="postcard_image_params_ls"> + <layout_panel name="postcard_image_size_lp"> + <spinner label="寬" name="postcard_snapshot_width"/> + <spinner label="高度" name="postcard_snapshot_height"/> + <check_box label="鎖住比例" name="postcard_keep_aspect_check"/> + </layout_panel> + <layout_panel name="postcard_image_format_quality_lp"> + <slider label="圖像品質" name="image_quality_slider"/> + <text name="image_quality_level"> + ([QLVL]) + </text> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml index c5dce10d63..3a7d79e04b 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml @@ -3,6 +3,19 @@ <panel.string name="aspect_ratio_text"> [NUM]:[DEN] </panel.string> + <text name="Cache:"> + 快取: + </text> + <spinner label="快取大小 (64 - 9984MB)" name="cachesizespinner"/> + <text name="text_box5"> + MB + </text> + <button label="清除快取" label_selected="清除快取" name="clear_cache"/> + <text name="Cache location"> + 快取位置: + </text> + <button label="瀏覽" label_selected="瀏覽" name="set_cache"/> + <button label="預設位置" label_selected="預設位置" name="default_cache_location"/> <text name="UI Size:"> 使用者界面尺寸: </text> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml index 738c77fd08..cf2f81d313 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml @@ -27,31 +27,9 @@ </text> <check_box label="群組聊天" name="EnableGroupChatPopups" tool_tip="當群組聊天訊息抵達時查看突顯式視窗"/> <check_box label="IM 聊天" name="EnableIMChatPopups" tool_tip="當即時訊息抵達時查看突顯式視窗"/> - <spinner label="Nearby chat toasts life time:" name="nearby_toasts_lifetime"/> - <spinner label="Nearby chat toasts fading time:" name="nearby_toasts_fadingtime"/> - <text name="translate_chb_label"> - 聊天時使用機器自動進行翻譯 - </text> - <text name="translate_language_text"> - 聊天翻譯為: - </text> - <combo_box name="translate_language_combobox"> - <combo_box.item label="系統預設" name="System Default Language"/> - <combo_box.item label="English" name="English"/> - <combo_box.item label="Dansk (Danish)" name="Danish"/> - <combo_box.item label="Deutsch (German)" name="German"/> - <combo_box.item label="Español (Spanish)" name="Spanish"/> - <combo_box.item label="Français (French)" name="French"/> - <combo_box.item label="Italiano (Italian)" name="Italian"/> - <combo_box.item label="Magyar (Hungarian)" name="Hungarian"/> - <combo_box.item label="Nederlands (Dutch)" name="Dutch"/> - <combo_box.item label="Polski (Polish)" name="Polish"/> - <combo_box.item label="Português (Portuguese)" name="Portugese"/> - <combo_box.item label="Русский (Russian)" name="Russian"/> - <combo_box.item label="Türkçe (Turkish)" name="Turkish"/> - <combo_box.item label="Українська (Ukrainian)" name="Ukrainian"/> - <combo_box.item label="中文 (正體) (Chinese)" name="Chinese"/> - <combo_box.item label="日本語 (Japanese)" name="Japanese"/> - <combo_box.item label="한국어 (Korean)" name="Korean"/> - </combo_box> + <spinner label="附近聊天內容提示框停駐時間:" name="nearby_toasts_lifetime"/> + <spinner label="附近聊天內容提示框消退時間:" name="nearby_toasts_fadingtime"/> + <button label="翻譯…" name="ok_btn"/> + <button label="自動取代…" name="autoreplace_showgui"/> + <button label="拼字檢查…" name="spellcheck_showgui"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml index 8d92eadd20..6af4bb8970 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml @@ -3,12 +3,12 @@ <text name="effects_color_textbox"> 我的效果(選擇指標): </text> - <color_swatch name="effect_color_swatch" tool_tip="點擊以開啟顏色挑選器"/> + <color_swatch name="effect_color_swatch" tool_tip="點按以開啟顏色挑選器"/> <text name="font_colors"> 聊天字型顏色: </text> <text name="text_box1"> - 自己 + 我自己 </text> <text name="text_box2"> 其他人 @@ -22,11 +22,14 @@ <text name="text_box5"> 錯誤 </text> + <text name="text_box10"> + 直接 + </text> <text name="text_box7"> - 擁有者 + 所有人 </text> <text name="text_box9"> - URLs + URL </text> <text name="bubble_chat"> 名稱標籤背景色(亦會影響聊天泡泡): diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml index 6827fab6e6..7e67a0d02d 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml @@ -1,19 +1,22 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="一般" name="general_panel"> +<panel label="基本設定" name="general_panel"> <text name="language_textbox"> 語言: </text> <combo_box name="language_combobox"> <combo_box.item label="系統預設" name="System Default Language"/> - <combo_box.item label="English (英語)" name="English"/> - <combo_box.item label="Dansk (丹麥語) - Beta" name="Danish"/> - <combo_box.item label="Deutsch (德語) - Beta" name="Deutsch(German)"/> - <combo_box.item label="Español (西班牙語) - Beta" name="Spanish"/> - <combo_box.item label="Français (法語) - Beta" name="French"/> - <combo_box.item label="Italiano (義大利語) - Beta" name="Italian"/> - <combo_box.item label="Polski (波蘭語) - Beta" name="Polish"/> - <combo_box.item label="Português (葡萄牙語) - Beta" name="Portugese"/> - <combo_box.item label="日本語 (日語) - Beta" name="(Japanese)"/> + <combo_box.item label="英語" name="English"/> + <combo_box.item label="Dansk(丹麥語)- 試用版" name="Danish"/> + <combo_box.item label="Deutsch(德語)- 試用版" name="Deutsch(German)"/> + <combo_box.item label="Español(西班牙語)- 試用版" name="Spanish"/> + <combo_box.item label="Français(法語)- 試用版" name="French"/> + <combo_box.item label="Italiano(義大利語)- 試用版" name="Italian"/> + <combo_box.item label="Polski(波蘭語)- 試用版" name="Polish"/> + <combo_box.item label="Português(葡萄牙語)- 試用版" name="Portugese"/> + <combo_box.item label="Русский(俄羅斯語)- 測試版" name="Russian"/> + <combo_box.item label="Türkçe(土耳其語)- 試用版" name="Turkish"/> + <combo_box.item label="日本語(日語)- 試用版" name="(Japanese)"/> + <combo_box.item label="正體中文 - 測試版" name="Traditional Chinese"/> </combo_box> <text name="language_textbox2"> (須重新啟動) @@ -38,15 +41,15 @@ 名稱標籤: </text> <radio_group name="Name_Tag_Preference"> - <radio_item label="Off" name="radio" value="0"/> - <radio_item label="On" name="radio2" value="1"/> + <radio_item label="關閉" name="radio" value="0"/> + <radio_item label="啟動" name="radio2" value="1"/> <radio_item label="簡短顯示" name="radio3" value="2"/> </radio_group> <check_box label="我的名字" name="show_my_name_checkbox1"/> <check_box label="使用者名稱" name="show_slids" tool_tip="顯示使用者名稱,就像 bobsmith123 這類的"/> - <check_box label="群組頭銜" name="show_all_title_checkbox1" tool_tip="顯示群組頭銜,像是 Officer 或成員"/> + <check_box label="群組頭銜" name="show_all_title_checkbox1" tool_tip="顯示群組頭銜,如職員或成員"/> <check_box label="高亮標示朋友" name="show_friends" tool_tip="高亮顯示你朋友的名稱標籤"/> - <check_box label="察看顯示名稱" name="display_names_check" tool_tip="Check to use display names in chat, IM, name tags, etc."/> + <check_box label="察看顯示名稱" name="display_names_check" tool_tip="若勾選,將在聊天、IM 和名稱標籤等處使用顯示名稱。"/> <text name="inworld_typing_rg_label"> 按下字母鍵: </text> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml index 874fb6b218..3948a48992 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="圖形" name="Display panel"> +<panel label="顯像" name="Display panel"> <text name="QualitySpeed"> 品質與速度: </text> @@ -27,8 +27,20 @@ </text> <check_box initial_value="true" label="清澈透明的水" name="TransparentWater"/> <check_box initial_value="true" label="凹凸映射與光澤效果" name="BumpShiny"/> + <check_box initial_value="true" label="本地光線" name="LocalLights"/> <check_box initial_value="true" label="基本著色" name="BasicShaders" tool_tip="關閉此一選項可能避免部分顯示卡驅動程式損毀當機"/> <check_box initial_value="true" label="大氣著色" name="WindLightUseAtmosShaders"/> + <check_box initial_value="true" label="光線和陰影" name="UseLightShaders"/> + <check_box initial_value="true" label="環境光遮蔽" name="UseSSAO"/> + <check_box initial_value="true" label="景深" name="UseDoF"/> + <text name="shadows_label"> + 陰影: + </text> + <combo_box name="ShadowDetail"> + <combo_box.item label="無" name="0"/> + <combo_box.item label="日 / 月" name="1"/> + <combo_box.item label="日 / 月 + 投影物" name="2"/> + </combo_box> <text name="reflection_label"> 水文反射: </text> @@ -45,11 +57,11 @@ </text> <slider label="描繪距離:" name="DrawDistance"/> <text name="DrawDistanceMeterText2"> - m + 公尺 </text> <slider label="最大粒子效果數量:" name="MaxParticleCount"/> - <slider label="Max. # of non-impostor avatars:" name="MaxNumberAvatarDrawn"/> - <slider label="後製品質:" name="RenderPostProcess"/> + <slider label="非假冒化身上限:" name="MaxNumberAvatarDrawn"/> + <slider label="後處理品質:" name="RenderPostProcess"/> <text name="MeshDetailText"> 網面細節: </text> @@ -81,10 +93,10 @@ 低 </text> <text name="AvatarRenderingText"> - Avatar Rendering: + 化身呈像: </text> - <check_box initial_value="true" label="Avatar impostors" name="AvatarImpostors"/> - <check_box initial_value="true" label="Hardware skinning" name="AvatarVertexProgram"/> + <check_box initial_value="true" label="化身假冒者" name="AvatarImpostors"/> + <check_box initial_value="true" label="硬體換膚" name="AvatarVertexProgram"/> <check_box initial_value="true" label="化身衣服" name="AvatarCloth"/> <text name="TerrainDetailText"> 地形細節: diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_move.xml b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml index ce176b1e3c..3a27477885 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml @@ -7,18 +7,33 @@ </text> <check_box label="建造 / 編輯" name="edit_camera_movement" tool_tip="使用進入或離開編輯模式時自動調整攝影機位置功能"/> <check_box label="編輯外觀" name="appearance_camera_movement" tool_tip="使用編輯模式時自動調整攝影機位置功能"/> - <check_box initial_value="true" label="側邊欄" name="appearance_sidebar_positioning" tool_tip="使用開啟側邊欄時自動調整攝影機位置功能"/> + <text name="keyboard_lbl"> + 鍵盤: + </text> + <check_box label="總是使用方向鍵移動" name="arrow_keys_move_avatar_check"/> + <check_box label="連點按住後跑步" name="tap_tap_hold_to_run"/> + <text name="mouse_lbl"> + 滑鼠: + </text> <check_box label="將我顯示於第一人稱視角中" name="first_person_avatar_visible"/> <text name=" Mouse Sensitivity"> 第一人稱視角滑鼠敏感度: </text> <check_box label="反轉" name="invert_mouse"/> - <check_box label="總是使用方向鍵移動" name="arrow_keys_move_avatar_check"/> - <check_box label="連點按住後跑步" name="tap_tap_hold_to_run"/> - <check_box label="雙擊以:" name="double_click_chkbox"/> - <radio_group name="double_click_action"> - <radio_item label="瞬間傳送" name="radio_teleport"/> - <radio_item label="自動導航駕駛" name="radio_autopilot"/> - </radio_group> + <text name="single_click_action_lbl"> + 在土地上點按一下: + </text> + <combo_box name="single_click_action_combo"> + <combo_box.item label="無動作" name="0"/> + <combo_box.item label="移動至點按的地點" name="1"/> + </combo_box> + <text name="double_click_action_lbl"> + 在土地上點按兩下: + </text> + <combo_box name="double_click_action_combo"> + <combo_box.item label="無動作" name="0"/> + <combo_box.item label="移動至點按的地點" name="1"/> + <combo_box.item label="瞬間傳送至點按的地點" name="2"/> + </combo_box> <button label="其他設備" name="joystick_setup_button"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml index efefb92df6..a607a7c33b 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml @@ -11,34 +11,17 @@ </text> <check_box label="自訂埠" name="connection_port_enabled"/> <spinner label="埠號:" name="connection_port"/> - <text name="cache_size_label_l"> - 快取尺寸 - </text> - <text name="text_box5"> - MB - </text> - <text name="Cache location"> - 快取位置: - </text> - <button label="瀏覽" label_selected="瀏覽" name="set_cache"/> - <button label="" label_selected="重設" name="reset_cache"/> <text name="Web:"> 網頁: </text> <radio_group name="use_external_browser"> - <radio_item label="使用我的網頁瀏覽器(例如 IE, Firefox, Safari)" name="external" tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." value="1"/> - <radio_item label="使用內建網頁瀏覽器" name="internal" tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]." value=""/> + <radio_item label="使用我的網頁瀏覽器(例如 IE, Firefox, Safari)" name="external" tool_tip="使用系統預設的瀏覽器瀏覽幫助,開啟網頁。全螢幕模式下不建議這麼做。" value="1"/> + <radio_item label="使用內建網頁瀏覽器" name="internal" tool_tip="使用內建的瀏覽器瀏覽幫助,開啟網頁。該瀏覽器將透過 [APP_NAME] 開啟新視窗。" value=""/> </radio_group> <check_box initial_value="true" label="啟用外掛" name="browser_plugins_enabled"/> <check_box initial_value="true" label="接受 cookies" name="cookies_enabled"/> <check_box initial_value="true" label="啟用 Javascript" name="browser_javascript_enabled"/> <check_box initial_value="false" label="啟用媒體瀏覽的突顯式視窗" name="media_popup_enabled"/> - <check_box initial_value="false" label="啟用網頁代理伺服器" name="web_proxy_enabled"/> - <text name="Proxy location"> - 代理伺服器位置: - </text> - <line_editor name="web_proxy_editor" tool_tip="The name or IP address of the proxy you would like to use"/> - <spinner label="埠號:" name="web_proxy_port"/> <text name="Software updates:"> 軟體更新: </text> @@ -46,4 +29,8 @@ <combo_box.item label="自動安裝" name="Install_automatically"/> <combo_box.item label="手動下載及安裝" name="Install_manual"/> </combo_box> + <text name="Proxy Settings:"> + 代理伺服器設定: + </text> + <button label="調整代理伺服器設定" label_selected="瀏覽" name="set_proxy"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml index 3280b9357b..e57f08fd74 100644 --- a/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="聲音" name="Preference Media panel"> <panel.string name="middle_mouse"> - Middle Mouse + 滑鼠中鍵 </panel.string> <slider label="主音量" name="System Volume"/> <check_box initial_value="true" name="mute_when_minimized"/> @@ -18,7 +18,8 @@ <slider label="語音聊天" name="Voice Volume"/> <check_box label="已啟用" name="enable_voice_check"/> <check_box label="允許媒體自動播放" name="media_auto_play_btn" tool_tip="若你想要,可以勾選這個允許媒體自動播放" value="true"/> - <check_box label="播放附加到其他化身身上的媒體" name="media_show_on_others_btn" tool_tip="Uncheck this to hide media attached to other avatars nearby" value="true"/> + <check_box label="播放附加到其他化身身上的媒體" name="media_show_on_others_btn" tool_tip="若未勾選,將隱藏附著於附近其他化身身上的媒體" value="true"/> + <check_box label="播放來自姿勢的聲音" name="gesture_audio_play_btn" tool_tip="勾選即可聽到來自姿勢的聲音" value="true"/> <text name="voice_chat_settings"> 語音聊天設定 </text> @@ -30,33 +31,10 @@ <radio_item label="化身位置" name="1"/> </radio_group> <check_box label="說話時同步移動化身嘴唇" name="enable_lip_sync"/> - <check_box label="Toggle speak on/off when I press:" name="push_to_talk_toggle_check" tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."/> - <line_editor label="Push-to-Speak trigger" name="modifier_combo"/> + <check_box label="切換說話 / 靜音,當我按下:" name="push_to_talk_toggle_check" tool_tip="在切換模式下,按下再放開啟動鍵一次,即可打開或關閉麥克風。 不在切換狀態時,麥克風只有在啟動鍵被按下時才會放送你的聲音。"/> + <line_editor label="「按下後說話」啟動鍵" name="modifier_combo"/> <button label="設定按鍵" name="set_voice_hotkey_button"/> <button name="set_voice_middlemouse_button" tool_tip="重設滑鼠中鍵按鈕"/> <button label="輸入 / 輸出設備" name="device_settings_btn"/> - <panel label="設備設定" name="device_settings_panel"> - <panel.string name="default_text"> - 預設 - </panel.string> - <panel.string name="default system device"> - 預設系統設備 - </panel.string> - <panel.string name="no device"> - 無設備 - </panel.string> - <text name="Input"> - 輸入 - </text> - <text name="My volume label"> - 我的音量: - </text> - <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Change the volume using this slider"/> - <text name="wait_text"> - 請稍候 - </text> - <text name="Output"> - 輸出 - </text> - </panel> + <panel label="設備設定" name="device_settings_panel"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml index df1a1b73a1..09043311da 100644 --- a/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml @@ -26,15 +26,15 @@ </string> <layout_stack name="progress_indicator_area"> <layout_panel name="media_progress_indicator"> - <progress_bar name="media_progress_bar" tool_tip="Media is Loading"/> + <progress_bar name="media_progress_bar" tool_tip="媒體載入中"/> </layout_panel> </layout_stack> <layout_stack name="media_controls"> <layout_panel name="back"> - <button name="back_btn" tool_tip="Navigate back"/> + <button name="back_btn" tool_tip="向後導覽"/> </layout_panel> <layout_panel name="fwd"> - <button name="fwd_btn" tool_tip="Navigate forward"/> + <button name="fwd_btn" tool_tip="向前導覽"/> </layout_panel> <layout_panel name="home"> <button name="home_btn" tool_tip="首頁"/> @@ -61,31 +61,31 @@ <icon name="media_whitelist_flag" tool_tip="白名單已啟用"/> </layout_panel> <layout_panel> - <icon name="media_secure_lock_flag" tool_tip="Secured Browsing"/> + <icon name="media_secure_lock_flag" tool_tip="加密的瀏覽"/> </layout_panel> </layout_stack> </layout_panel> <layout_panel name="media_play_position"> - <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Movie play progress"/> + <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="影片播放進度"/> </layout_panel> <layout_panel name="skip_back"> - <button name="skip_back_btn" tool_tip="Step back"/> + <button name="skip_back_btn" tool_tip="倒轉"/> </layout_panel> <layout_panel name="skip_forward"> - <button name="skip_forward_btn" tool_tip="Step forward"/> + <button name="skip_forward_btn" tool_tip="快轉"/> </layout_panel> <layout_panel name="media_volume"> - <button name="media_mute_button" tool_tip="Mute This Media"/> - <slider name="volume_slider" tool_tip="Media Volume"/> + <button name="media_mute_button" tool_tip="把這個媒體消音"/> + <slider name="volume_slider" tool_tip="媒體音量"/> </layout_panel> <layout_panel name="zoom_frame"> - <button name="zoom_frame_btn" tool_tip="Zoom into media"/> + <button name="zoom_frame_btn" tool_tip="以媒體為中心放大"/> </layout_panel> <layout_panel name="close"> - <button name="close_btn" tool_tip="Zoom Back"/> + <button name="close_btn" tool_tip="縮小"/> </layout_panel> <layout_panel name="new_window"> - <button name="new_window_btn" tool_tip="Open URL in browser"/> + <button name="new_window_btn" tool_tip="用瀏覽器開啟 URL"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_covenant.xml b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml index ad94c4c7e9..d5dd337795 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="契約" name="Covenant"> <panel.string name="can_resell"> - Purchased land in this region may be resold. + 購買這地區的土地允許轉售。 </panel.string> <panel.string name="can_not_resell"> - Purchased land in this region may not be resold. + 購買這地區的土地不允許轉售。 </panel.string> <panel.string name="can_change"> - Purchased land in this region may be joined or subdivided. + 購買這地區的土地允許進行合併或分割。 </panel.string> <panel.string name="can_not_change"> - Purchased land in this region may not be joined or subdivided. + 購買這地區的土地不允許進行合併或分割。 </panel.string> <text name="estate_section_lbl"> 領地 @@ -19,10 +19,10 @@ 名稱: </text> <text name="estate_name_text"> - mainland + 大陸 </text> <text name="estate_owner_lbl"> - 擁有者: + 所有人: </text> <text name="estate_owner_text"> (無) @@ -31,17 +31,17 @@ 契約: </text> <text name="covenant_timestamp_text"> - Last Modified Wed Dec 31 16:00:00 1969 + 上次修改於 Wed Dec 31 16:00:00 1969 </text> <text_editor name="covenant_editor"> - There is no Covenant provided for this Estate. + 此領地沒有任何契約要求。 </text_editor> <button label="重設" name="reset_covenant"/> <text name="covenant_help_text"> - Changes to the covenant will show on all parcels in the estate. + 契約修訂內容將顯示於領地裡所有地段。 </text> <text name="covenant_instructions"> - Drag and drop a notecard to change the Covenant for this estate. + 拖曳並置放一張記事卡,即可修訂領地契約。 </text> <text name="region_section_lbl"> 地區 @@ -56,7 +56,7 @@ 類型: </text> <text name="region_landtype_text"> - Mainland / Homestead + 大陸 / 家園 </text> <text name="region_maturity_lbl"> 分級: diff --git a/indra/newview/skins/default/xui/zh/panel_region_debug.xml b/indra/newview/skins/default/xui/zh/panel_region_debug.xml index ed5e6e9d2c..e5d5e6eaf7 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_debug.xml @@ -7,7 +7,7 @@ 未知 </text> <check_box label="關閉腳本" name="disable_scripts_check" tool_tip="關閉這個地區現在的全部腳本"/> - <check_box label="關閉碰撞" name="disable_collisions_check" tool_tip="關閉這個地區現在的非化身碰撞"/> + <check_box label="禁止碰撞" name="disable_collisions_check" tool_tip="關閉這個地區現在的非化身碰撞"/> <check_box label="關閉物理" name="disable_physics_check" tool_tip="關閉這個地區現在的全部物理"/> <button label="套用" name="apply_btn"/> <text name="objret_text_lbl"> @@ -28,7 +28,7 @@ <check_box label="於這個領地內的每一個地區" name="return_estate_wide" tool_tip="退回這個領地內全部地區中標記為他的物件"/> <button label="退回" name="return_btn"/> <button label="取得最常碰撞的物件..." name="top_colliders_btn" tool_tip="條列出目前運作中最常碰撞的物件清單"/> - <button label="取得最耗能腳本..." name="top_scripts_btn" tool_tip="條列出目前運作中最耗能的腳本清單"/> + <button label="取得最耗能腳本..." name="top_scripts_btn" tool_tip="條列���目前運作中最耗能的腳本清單"/> <button label="地區重新啟動" name="restart_btn" tool_tip="給予兩分鐘倒數計時並重新啟動"/> - <button label="延遲重新啟動" name="cancel_restart_btn" tool_tip="延遲地區重新啟動一小時"/> + <button label="取消重新啟動" name="cancel_restart_btn" tool_tip="取消地區重新啟動"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_environment.xml b/indra/newview/skins/default/xui/zh/panel_region_environment.xml new file mode 100644 index 0000000000..8f466af39e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_environment.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="環境" name="panel_env_info"> + <text name="water_settings_title"> + 選擇你希望到你地區的訪客所能看到的水和天空 / 日循環設定。 詳情 + </text> + <radio_group name="region_settings_radio_group"> + <radio_item label="使用第二人生預設值" name="use_sl_default_settings"/> + <radio_item label="使用以下設定" name="use_my_settings"/> + </radio_group> + <panel name="user_environment_settings"> + <text name="water_settings_title"> + 水的設定 + </text> + <combo_box name="water_settings_preset_combo"> + <combo_box.item label="-選擇一個自訂配置-" name="item0"/> + </combo_box> + <text name="sky_dayc_settings_title"> + 天空 / 日循環 + </text> + <radio_group name="sky_dayc_settings_radio_group"> + <radio_item label="固定天空" name="my_sky_settings"/> + <radio_item label="日循環" name="my_dayc_settings"/> + </radio_group> + <combo_box name="sky_settings_preset_combo"> + <combo_box.item label="-選擇一個自訂配置-" name="item0"/> + </combo_box> + <combo_box name="dayc_settings_preset_combo"> + <combo_box.item label="-選擇一個自訂配置-" name="item0"/> + </combo_box> + </panel> + <button label="套用" name="apply_btn"/> + <button label="取消" name="cancel_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_estate.xml b/indra/newview/skins/default/xui/zh/panel_region_estate.xml index efa3be2f51..f3c1c85379 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_estate.xml @@ -10,20 +10,20 @@ (未知) </text> <text name="owner_text"> - 領地擁有者: + 領地所有人: </text> <text name="estate_owner"> (未知) </text> - <check_box label="Use Global Time" name="use_global_time_check"/> + <check_box label="使用全域時間" name="use_global_time_check"/> <check_box label="固定太陽" name="fixed_sun_check"/> - <slider label="Phase" name="sun_hour_slider"/> + <slider label="相位" name="sun_hour_slider"/> <check_box label="允許公開出入" name="externally_visible_check"/> <text name="Only Allow"> - Restrict Access to accounts verified by: + 僅允許符合以下條件的居民進入: </text> - <check_box label="Payment Information on File" name="limit_payment" tool_tip="Ban unidentified Residents"/> - <check_box label="年齡驗證" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/> + <check_box label="已經預留付款資料" name="limit_payment" tool_tip="居民必須提供付款資料才能進入這領地。 參閱 [SUPPORT_SITE] 獲取進一步資訊。"/> + <check_box label="已年滿 18 歲" name="limit_age_verified" tool_tip="居民必須年滿 18 歲才能進入這領地。 參閱 [SUPPORT_SITE] 獲取進一步資訊。"/> <check_box label="允許語音聊天" name="voice_chat_check"/> <check_box label="允許直接瞬間傳送" name="allow_direct_teleport"/> <button label="套用" name="apply_btn"/> diff --git a/indra/newview/skins/default/xui/zh/panel_region_general.xml b/indra/newview/skins/default/xui/zh/panel_region_general.xml index a441b8898d..f6b2c46354 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_general.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_general.xml @@ -18,16 +18,17 @@ <text name="region_type"> 未知 </text> - <check_box label="阻止變形" name="block_terraform_check"/> + <check_box label="阻止土地變形" name="block_terraform_check"/> <check_box label="阻止飛行" name="block_fly_check"/> <check_box label="允許傷害" name="allow_damage_check"/> <check_box label="限制推撞" name="restrict_pushobject"/> <check_box label="允許土地轉售" name="allow_land_resell_check"/> <check_box label="允許土地 合併/分割" name="allow_parcel_changes_check"/> <check_box label="阻擋土地顯示於搜尋中" name="block_parcel_search_check" tool_tip="讓其他人可以在搜尋結果中看到這個地區與其中的地段"/> + <check_box label="允許網面物件" name="mesh_rez_enabled_check" tool_tip="允許大家在此地區產生網面物件"/> <spinner label="人數上限" name="agent_limit_spin"/> - <spinner label="Object Bonus" name="object_bonus_spin"/> - <text label="Maturity" name="access_text"> + <spinner label="物件紅利" name="object_bonus_spin"/> + <text label="分級" name="access_text"> 分級: </text> <icons_combo_box label="適度成人" name="access_combo"> @@ -36,8 +37,8 @@ <icons_combo_box.item label="一般普級" name="PG" value="13"/> </icons_combo_box> <button label="套用" name="apply_btn"/> - <button label="強制瞬間傳送一個居民回家..." name="kick_btn"/> - <button label="強制瞬間傳送所有居民回家..." name="kick_all_btn"/> - <button label="送出訊息到地區..." name="im_btn"/> + <button label="瞬間傳送一位居民回家..." name="kick_btn"/> + <button label="瞬間傳送所有居民回家..." name="kick_all_btn"/> + <button label="向地區發出訊息..." name="im_btn"/> <button label="管理瞬間傳送中心..." name="manage_telehub_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml index 7cae8fe8cf..85e759e445 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml @@ -9,11 +9,52 @@ <spinner label="水文高度" name="water_height_spin"/> <spinner label="地形提升限制" name="terrain_raise_spin"/> <spinner label="地形降低限制" name="terrain_lower_spin"/> - <check_box label="使用領地的太陽設定" name="use_estate_sun_check"/> - <check_box label="固定太陽" name="fixed_sun_check"/> - <slider label="Phase" name="sun_hour_slider"/> + <text name="detail_texture_text"> + 地形材質(須 512x512,24 位元 .tga 檔格式) + </text> + <text name="height_text_lbl"> + 1(低) + </text> + <text name="height_text_lbl2"> + 2 + </text> + <text name="height_text_lbl3"> + 3 + </text> + <text name="height_text_lbl4"> + 4(高) + </text> + <text name="height_text_lbl5"> + 材質海拔範圍 + </text> + <text name="height_text_lbl10"> + 這些值代表以上材質的混合範圍。 + </text> + <text name="height_text_lbl11"> + 以公尺為單位,低值是材質 #1 的最大高度,高值是材質 #4 的最小高度。 + </text> + <text name="height_text_lbl6"> + 西北 + </text> + <text name="height_text_lbl7"> + 東北 + </text> + <spinner label="低" name="height_start_spin_1"/> + <spinner label="低" name="height_start_spin_3"/> + <spinner label="高" name="height_range_spin_1"/> + <spinner label="高" name="height_range_spin_3"/> + <text name="height_text_lbl8"> + 西南 + </text> + <text name="height_text_lbl9"> + 東南 + </text> + <spinner label="低" name="height_start_spin_0"/> + <spinner label="低" name="height_start_spin_2"/> + <spinner label="高" name="height_range_spin_0"/> + <spinner label="高" name="height_range_spin_2"/> + <button label="下載 RAW 地形..." name="download_raw_btn" tool_tip="只允許領地所有人而非管理者進行操作"/> + <button label="上傳 RAW 地形檔..." name="upload_raw_btn" tool_tip="只允許領地所有人而非管理者進行操作"/> + <button label="確定地形" name="bake_terrain_btn" tool_tip="將目前地形設為「升高 / 降低」極限的中心值"/> <button label="套用" name="apply_btn"/> - <button label="下載 RAW 地形..." name="download_raw_btn" tool_tip="只允許領地擁有者而非管理者進行操作"/> - <button label="上傳 RAW 地形檔..." name="upload_raw_btn" tool_tip="只允許領地擁有者而非管理者進行操作"/> - <button label="Bake Terrain" name="bake_terrain_btn" tool_tip="Set current terrain as mid-point for raise/lower limits"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_texture.xml b/indra/newview/skins/default/xui/zh/panel_region_texture.xml deleted file mode 100644 index 7b6152121f..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_region_texture.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="地面材質" name="Textures"> - <text name="region_text_lbl"> - 地區: - </text> - <text name="region_text"> - 未知 - </text> - <text name="detail_texture_text"> - 地形材質(須 512x512,24 位元 .tga 檔格式) - </text> - <text name="height_text_lbl"> - 1 (Low) - </text> - <text name="height_text_lbl2"> - 2 - </text> - <text name="height_text_lbl3"> - 3 - </text> - <text name="height_text_lbl4"> - 4 (High) - </text> - <text name="height_text_lbl5"> - Texture Elevation Ranges - </text> - <text name="height_text_lbl6"> - Northwest - </text> - <text name="height_text_lbl7"> - Northeast - </text> - <spinner label="Low" name="height_start_spin_1"/> - <spinner label="Low" name="height_start_spin_3"/> - <spinner label="High" name="height_range_spin_1"/> - <spinner label="High" name="height_range_spin_3"/> - <text name="height_text_lbl8"> - Southwest - </text> - <text name="height_text_lbl9"> - Southeast - </text> - <spinner label="Low" name="height_start_spin_0"/> - <spinner label="Low" name="height_start_spin_2"/> - <spinner label="High" name="height_range_spin_0"/> - <spinner label="High" name="height_range_spin_2"/> - <text name="height_text_lbl10"> - These values represent the blend range for the textures above. - </text> - <text name="height_text_lbl11"> - Measured in meters, the LOW value is the MAXIMUM height of Texture #1, and the HIGH value is the MINIMUM height of Texture #4. - </text> - <button label="套用" name="apply_btn"/> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_ed.xml b/indra/newview/skins/default/xui/zh/panel_script_ed.xml index cc2b0fc673..29e9a35869 100644 --- a/indra/newview/skins/default/xui/zh/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/zh/panel_script_ed.xml @@ -4,7 +4,7 @@ 載入中... </panel.string> <panel.string name="can_not_view"> - 你不能察看或編輯此腳本,自從它被設定為 "no copy" 後。你需要完整權限去察看或編輯有包含腳本在內的物件。 + 你無法察看或編輯這腳本,它被設為「禁止複製」。 你需要完整權限去察看或編輯物件內的腳本。 </panel.string> <panel.string name="public_objects_can_not_run"> 公開物件不能執行腳本 @@ -22,12 +22,14 @@ <menu label="檔案" name="File"> <menu_item_call label="儲存" name="Save"/> <menu_item_call label="還原全部變更" name="Revert All Changes"/> + <menu_item_call label="從檔案載入…" name="LoadFromFile"/> + <menu_item_call label="存入檔案…" name="SaveToFile"/> </menu> <menu label="編輯" name="Edit"> <menu_item_call label="復原" name="Undo"/> <menu_item_call label="重做" name="Redo"/> <menu_item_call label="剪下" name="Cut"/> - <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="恚庨" name="Copy"/> <menu_item_call label="貼上" name="Paste"/> <menu_item_call label="全選" name="Select All"/> <menu_item_call label="取消選擇" name="Deselect"/> diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml index 32cc2f9a5d..eb32d39f78 100644 --- a/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml +++ b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="我的化身" name="script_limits_my_avatar_panel"> <text name="script_memory"> - Avatar Script Usage + 化身腳本使用量 </text> <text name="loading_text"> 載入中... </text> <scroll_list name="scripts_list"> <scroll_list.columns label="尺寸(kb)" name="size"/> - <scroll_list.columns label="URLs" name="urls"/> + <scroll_list.columns label="URL" name="urls"/> <scroll_list.columns label="物件名稱" name="name"/> <scroll_list.columns label="位置" name="location"/> </scroll_list> - <button label="Refresh List" name="refresh_list_btn"/> + <button label="刷新清單" name="refresh_list_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml index 950abbfb4c..40a2dd6926 100644 --- a/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml +++ b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml @@ -8,13 +8,13 @@ </text> <scroll_list name="scripts_list"> <scroll_list.columns label="尺寸(kb)" name="size"/> - <scroll_list.columns label="URLs" name="urls"/> + <scroll_list.columns label="URL" name="urls"/> <scroll_list.columns label="物件名稱" name="name"/> - <scroll_list.columns label="物件擁有者" name="owner"/> + <scroll_list.columns label="物件所有人" name="owner"/> <scroll_list.columns label="地段" name="parcel"/> <scroll_list.columns label="位置" name="location"/> </scroll_list> - <button label="Refresh List" name="refresh_list_btn"/> - <button label="Highlight" name="highlight_btn"/> + <button label="刷新清單" name="refresh_list_btn"/> + <button label="高亮顯示" name="highlight_btn"/> <button label="退回" name="return_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml b/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml new file mode 100644 index 0000000000..a2d0237da0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="script_question_panel" name="panel_script_question_toast"> + <panel label="buttons_panel" name="buttons_panel"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_side_tray.xml b/indra/newview/skins/default/xui/zh/panel_side_tray.xml deleted file mode 100644 index e5c7deb7d6..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_side_tray.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- Side tray cannot show background because it is always - partially on screen to hold tab buttons. --> -<side_tray name="sidebar"> - <sidetray_tab description="側邊欄切換。" name="sidebar_openclose" tab_title="側邊欄切換"/> - <sidetray_tab description="首頁。" name="sidebar_home" tab_title="首頁"> - <panel label="首頁" name="panel_home"/> - </sidetray_tab> - <sidetray_tab description="編輯你的公開檔案及精選地點。" name="sidebar_me" tab_title="我的檔案"> - <panel_container name="panel_container"> - <panel label="自己" name="panel_me"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Find your friends, contacts and people nearby." name="sidebar_people" tab_title="人群"> - <panel_container name="panel_container"> - <panel label="群組檔案" name="panel_group_info_sidetray"/> - <panel label="Blocked Residents & Objects" name="panel_block_list_sidetray"/> - </panel_container> - </sidetray_tab> - <sidetray_tab description="Find places to go and places you've visited before." label="地點" name="sidebar_places" tab_title="地點"> - <panel label="地點" name="panel_places"/> - </sidetray_tab> - <sidetray_tab description="瀏覽你的收納區。" name="sidebar_inventory" tab_title="我的收納區"> - <panel label="編輯收納區" name="sidepanel_inventory"/> - </sidetray_tab> - <sidetray_tab description="變更你的外觀與目前樣貌。" name="sidebar_appearance" tab_title="我的外觀"> - <panel label="編輯外觀" name="sidepanel_appearance"/> - </sidetray_tab> -</side_tray> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml new file mode 100644 index 0000000000..20fb9b494a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_snapshot_inventory"> + <text name="title"> + 儲存到我的收納區 + </text> + <text name="hint_lbl"> + 將圖像儲存到收納區的費用為 L$[UPLOAD_COST]。 若要將圖像存為材質,請選擇一個正方格式。 + </text> + <combo_box label="解析度" name="texture_size_combo"> + <combo_box.item label="目前視窗" name="CurrentWindow"/> + <combo_box.item label="小(128x128)" name="Small(128x128)"/> + <combo_box.item label="中(256x256)" name="Medium(256x256)"/> + <combo_box.item label="大(512x512)" name="Large(512x512)"/> + <combo_box.item label="自訂" name="Custom"/> + </combo_box> + <spinner label="寬" name="inventory_snapshot_width"/> + <spinner label="高度" name="inventory_snapshot_height"/> + <check_box label="鎖住比例" name="inventory_keep_aspect_check"/> + <button label="取消" name="cancel_btn"/> + <button label="儲存" name="save_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_local.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_local.xml new file mode 100644 index 0000000000..a929c9a3fb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_local.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_snapshot_local"> + <text name="title"> + 儲存到電腦上 + </text> + <combo_box label="解析度" name="local_size_combo"> + <combo_box.item label="目前視窗" name="CurrentWindow"/> + <combo_box.item label="320x240" name="320x240"/> + <combo_box.item label="640x480" name="640x480"/> + <combo_box.item label="800x600" name="800x600"/> + <combo_box.item label="1024x768" name="1024x768"/> + <combo_box.item label="1280x1024" name="1280x1024"/> + <combo_box.item label="1600x1200" name="1600x1200"/> + <combo_box.item label="自訂" name="Custom"/> + </combo_box> + <layout_stack name="local_image_params_ls"> + <layout_panel name="local_image_size_lp"> + <spinner label="寬" name="local_snapshot_width"/> + <spinner label="高度" name="local_snapshot_height"/> + <check_box label="鎖住比例" name="local_keep_aspect_check"/> + </layout_panel> + <layout_panel name="local_image_format_quality_lp"> + <combo_box label="格式" name="local_format_combo"> + <combo_box.item label="PNG(零失真)" name="PNG"/> + <combo_box.item label="JPEG" name="JPEG"/> + <combo_box.item label="BMP(零失真)" name="BMP"/> + </combo_box> + <slider label="圖像品質" name="image_quality_slider"/> + <text name="image_quality_level"> + ([QLVL]) + </text> + </layout_panel> + </layout_stack> + <button label="取消" name="cancel_btn"/> + <flyout_button label="儲存" name="save_btn" tool_tip="儲存圖像到檔案"> + <flyout_button.item label="儲存" name="save_item"/> + <flyout_button.item label="另存..." name="saveas_item"/> + </flyout_button> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml new file mode 100644 index 0000000000..82c2b10d8d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_snapshot_options"> + <button label="送至我的檔案訊息發佈" name="save_to_profile_btn"/> + <button label="電郵" name="save_to_email_btn"/> + <button label="儲存到我的收納區(L$[AMOUNT])" name="save_to_inventory_btn"/> + <button label="儲存到電腦上" name="save_to_computer_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml new file mode 100644 index 0000000000..853a856104 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_snapshot_postcard"> + <string name="default_subject"> + 來自 [SECOND_LIFE] 的明信片。 + </string> + <string name="default_message"> + 快來看看這個! + </string> + <string name="upload_message"> + 傳送中... + </string> + <text name="title"> + 電郵 + </text> + <button label="訊息" name="message_btn"/> + <button label="設定" name="settings_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml new file mode 100644 index 0000000000..6f64a4e83c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_snapshot_profile"> + <text name="title"> + 送至我的檔案訊息發佈 + </text> + <combo_box label="解析度" name="profile_size_combo"> + <combo_box.item label="目前視窗" name="CurrentWindow"/> + <combo_box.item label="640x480" name="640x480"/> + <combo_box.item label="800x600" name="800x600"/> + <combo_box.item label="1024x768" name="1024x768"/> + <combo_box.item label="自訂" name="Custom"/> + </combo_box> + <layout_stack name="profile_image_params_ls"> + <layout_panel name="profile_image_size_lp"> + <spinner label="寬" name="profile_snapshot_width"/> + <spinner label="高度" name="profile_snapshot_height"/> + <check_box label="鎖住比例" name="profile_keep_aspect_check"/> + </layout_panel> + <layout_panel name="profile_image_metadata_lp"> + <text name="caption_label"> + 內容敘述: + </text> + <check_box initial_value="true" label="加入所在位置" name="add_location_cb"/> + </layout_panel> + </layout_stack> + <button label="取消" name="cancel_btn"/> + <button label="發佈" name="post_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_sound_devices.xml b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml new file mode 100644 index 0000000000..fa4e24a605 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="設備設定" name="device_settings_panel"> + <panel.string name="default_text"> + 預設 + </panel.string> + <string name="name_no_device"> + 無設備 + </string> + <string name="name_default_system_device"> + 預設系統設備 + </string> + <text name="Input"> + 輸入 + </text> + <text name="Output"> + 輸出 + </text> + <text name="My volume label"> + 我的音量: + </text> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="用這控制條改變音量"/> + <text name="wait_text"> + 請稍候 + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml index 1dd3acef5d..4586d4eca1 100644 --- a/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml +++ b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Width and height of this panel should be synchronized with "panel_modes" in the floater_moveview.xml--> <panel name="panel_stand_stop_flying"> - <button label="站立" name="stand_btn" tool_tip="點擊此處起立。"/> + <button label="站立" name="stand_btn" tool_tip="點按此處起立。"/> <button label="停止飛行" name="stop_fly_btn" tool_tip="停止飛行"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_status_bar.xml b/indra/newview/skins/default/xui/zh/panel_status_bar.xml index 808e14f3c3..b4cdff9d6b 100644 --- a/indra/newview/skins/default/xui/zh/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/zh/panel_status_bar.xml @@ -16,12 +16,13 @@ L$ [AMT] </panel.string> <panel name="balance_bg"> - <text name="balance" tool_tip="點擊以重新更新你的 L$ 帳戶餘額" value="L$20"/> - <button label="購買 L$" name="buyL" tool_tip="點擊以購買更多 L$"/> + <text name="balance" tool_tip="點按以重新更新你的 L$ 帳戶餘額" value="L$20"/> + <button label="購買 L$" name="buyL" tool_tip="點按以購買更多 L$"/> + <button label="購物" name="goShop" tool_tip="打開第二人生購物市集"/> </panel> <text name="TimeText" tool_tip="目前時區(太平洋)"> 24:00 AM PST </text> - <button name="media_toggle_btn" tool_tip="開始 / 停止全部媒體(音樂、影片、網頁)"/> + <button name="media_toggle_btn" tool_tip="開始/停止全部媒體(音樂、影片、網頁)"/> <button name="volume_btn" tool_tip="全域音量控制"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/panel_teleport_history.xml b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml index a2a63db000..44d545a86d 100644 --- a/indra/newview/skins/default/xui/zh/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Teleport History"> <accordion name="history_accordion"> - <no_matched_tabs_text name="no_matched_teleports_msg" value="沒有發現你要找的嗎?試試 [secondlife:///app/search/places/[SEARCH_TERM] 搜尋]。"/> - <no_visible_tabs_text name="no_teleports_msg" value="瞬間傳送紀錄是空白的。試試 [secondlife:///app/search/places/ Search]。"/> + <no_matched_tabs_text name="no_matched_teleports_msg" value="找不到你要找的嗎? 請試試 [secondlife:///app/search/places/[SEARCH_TERM] 搜尋]。"/> + <no_visible_tabs_text name="no_teleports_msg" value="瞬間傳送歷史記錄目前空白。 請試試[secondlife:///app/search/places/ 搜尋]。"/> <accordion_tab name="today" title="今天"/> <accordion_tab name="yesterday" title="昨天"/> <accordion_tab name="2_days_ago" title="前天"/> diff --git a/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml new file mode 100644 index 0000000000..70ec028176 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="volumepulldown_floater"> + <slider label="主控音量" name="System Volume"/> + <slider label="按鍵音" name="UI Volume"/> + <slider label="環境" name="Wind Volume"/> + <slider label="聲音" name="SFX Volume"/> + <check_box name="gesture_audio_play_btn" tool_tip="啟用姿勢聲音"/> + <slider label="音樂" name="Music Volume"/> + <check_box name="enable_music" tool_tip="啟用串流音樂"/> + <slider label="媒體" name="Media Volume"/> + <check_box name="enable_media" tool_tip="啟用串流媒體"/> + <slider label="語音" name="Voice Volume"/> + <check_box name="enable_voice_check" tool_tip="啟用語音聊天"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_world_map.xml b/indra/newview/skins/default/xui/zh/panel_world_map.xml index b5aa659bf0..84018768a1 100644 --- a/indra/newview/skins/default/xui/zh/panel_world_map.xml +++ b/indra/newview/skins/default/xui/zh/panel_world_map.xml @@ -7,57 +7,57 @@ 無效的位置 </panel.string> <panel.string name="world_map_north"> - N + 北 </panel.string> <panel.string name="world_map_east"> E </panel.string> <panel.string name="world_map_west"> - W + 西 </panel.string> <panel.string name="world_map_south"> - S + 南 </panel.string> <panel.string name="world_map_southeast"> - SE + 東南 </panel.string> <panel.string name="world_map_northeast"> - NE + 東北 </panel.string> <panel.string name="world_map_southwest"> - SW + 西南 </panel.string> <panel.string name="world_map_northwest"> - NW + 西北 </panel.string> <panel.string name="world_map_person"> - 1 person + 1 人 </panel.string> <panel.string name="world_map_people"> - [NUMBER] people + [NUMBER] 人 </panel.string> - <text label="N" name="floater_map_north"> - N + <text label="北" name="floater_map_north"> + 北 </text> <text label="E" name="floater_map_east"> E </text> - <text label="W" name="floater_map_west"> - W + <text label="西" name="floater_map_west"> + 西 </text> - <text label="S" name="floater_map_south"> - S + <text label="南" name="floater_map_south"> + 南 </text> - <text label="SE" name="floater_map_southeast"> - SE + <text label="東南" name="floater_map_southeast"> + 東南 </text> - <text label="NE" name="floater_map_northeast"> - NE + <text label="東北" name="floater_map_northeast"> + 東北 </text> - <text label="SW" name="floater_map_southwest"> - SW + <text label="西南" name="floater_map_southwest"> + 西南 </text> - <text label="NW" name="floater_map_northwest"> - NW + <text label="西北" name="floater_map_northwest"> + 西北 </text> </panel> diff --git a/indra/newview/skins/default/xui/zh/role_actions.xml b/indra/newview/skins/default/xui/zh/role_actions.xml index 32bf0d22d8..767bcecde7 100644 --- a/indra/newview/skins/default/xui/zh/role_actions.xml +++ b/indra/newview/skins/default/xui/zh/role_actions.xml @@ -1,73 +1,73 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <role_actions> - <action_set description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation." name="Membership"> - <action description="邀請他人加入這個群組" longdescription="邀請他人加入這個群組,請按下於角色區段中的成員頁籤中的 '邀請' 按鈕。" name="member invite" value="1"/> - <action description="將會員由這個群組中踢出" longdescription="Eject Members from this Group using the 'Eject' button in the Roles section > Members tab. An Owner can eject anyone except another Owner. If you're not an Owner, a Member can be ejected from a group if, and only if, they're only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the 'Remove Members from Roles' Ability." name="member eject" value="2"/> - <action description="Toggle 'Open Enrollment' and change 'Enrollment fee'" longdescription="Toggle 'Open Enrollment' to let new Members join without an invitation, and change the 'Enrollment fee' in the General section." name="member options" value="3"/> + <action_set description="這些能力包括新增或移除群組成員和允許新成員不受邀即可加入群組的等權力。" name="Membership"> + <action description="邀請他人加入這個群組" longdescription="欲邀請他人加入這個群組,請按下角色欄下的成員頁籤中的「邀請」按鈕。" name="member invite" value="1"/> + <action description="將會員由這個群組中踢出" longdescription="欲將成員從群組踢出,請按下角色欄下的成員頁籤中的「踢出」按鈕。 所有人可踢出任何不具所有人角色的人。 如果你不是所有人,一位成員只在他僅屬於「任何人」角色且沒有其他角色的情況下被踢出群組。 欲卸除成員的角色,你必須有「卸除成員角色」的能力。" name="member eject" value="2"/> + <action description="切換「免費自由加入」設定,更改「加入費」。" longdescription="切換「免費自由加入」設定,讓成員不受邀也可加入,並在基本設定欄更改「加入費」。" name="member options" value="3"/> </action_set> - <action_set description="These Abilities include powers to add, remove, and change group Roles, add and remove Members in Roles, and assign Abilities to Roles." name="Roles"> - <action description="創立一個新角色" longdescription="創立一個新角色於角色區段 > 角色頁籤。" name="role create" value="4"/> - <action description="刪除角色" longdescription="Delete Roles in the Roles section > Roles tab." name="role delete" value="5"/> - <action description="Change Role names, titles, descriptions, and whether Role members are publicly revealed" longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles section > Roles tab after selecting a Role." name="role properties" value="6"/> - <action description="Assign Members to Assigner's Roles" longdescription="Assign Members to Roles in the list of Assigned Roles (Roles section > Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in." name="role assign member limited" value="7"/> - <action description="Assign Members to Any Role" longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles section > Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role assign member" value="8"/> - <action description="由角色中移除成員" longdescription="Remove Members from Roles in the list of Assigned Roles (Roles section > Members tab). Owners can't be removed." name="role remove member" value="9"/> - <action description="Assign and Remove Abilities in Roles" longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles section > Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role change actions" value="10"/> + <action_set description="這些能力包括新增、移除、更改群組角色,新增或移除成員的角色,和為角色設定能力等權力。" name="Roles"> + <action description="創立一個新角色" longdescription="到角色欄的角色頁籤,可以建立新角色。" name="role create" value="4"/> + <action description="刪除角色" longdescription="到角色欄的角色頁籤,可以刪除角色。" name="role delete" value="5"/> + <action description="變更角色名稱、頭銜、描述,設定角色的成員名單是否公開" longdescription="變更角色名稱、頭銜、描述,設定角色的成員名單是否公開。 選取一個角色後,可到角色欄底下的角色頁籤完成這動作。" name="role properties" value="6"/> + <action description="賦予成員「指派者」角色" longdescription="從已知的指派角色中選擇若干,賦予給成員(角色欄 > 成員頁籤)。 有這能力的成員,只能把他自己已身負的角色賦予給別的成員。" name="role assign member limited" value="7"/> + <action description="賦予成員「任何人」角色" longdescription="從已知的指派角色中,賦予給成員「任何人」角色(角色欄 > 成員頁籤)。 *警告* 任何身負具這能力的角色的成員,都可以把某些角色賦予自己或任何不是所有人的成員,因此使自己或別人得到比現在更多的權力,最終可能擁有近似「所有人」的權力。 賦予這項能力之前,敬請慎重考慮。" name="role assign member" value="8"/> + <action description="由角色中移除成員" longdescription="從已知的指派角色中選擇,將成員卸除該角色(角色欄 > 成員頁籤)。 所有人角色不得被卸除。" name="role remove member" value="9"/> + <action description="設定或卸除角色能力" longdescription="從允許的能力清單中選擇,為每一角色設定或卸除該能力(角色欄 > 角色頁籤)。 *警告* 任何身負具有這能力的角色的成員,都可以將所有能力賦予自己和任何其他不是所有人的人,因此讓自己或他人提升為近似「所有人」權力的層級。 賦予這項能力之前,敬請慎重考慮。" name="role change actions" value="10"/> </action_set> - <action_set description="These Abilities include powers to modify this group's identity, such as changing public visibility, charter, and insignia." name="Group Identity"> - <action description="Change Charter, Insignia, and 'Show in search'" longdescription="Change Charter, Insignia, and 'Show in search'. This is done in the General section." name="group change identity" value="11"/> + <action_set description="這些能力包括有權修改群組身份,例如更改公開程度、規章和徽章。" name="Group Identity"> + <action description="更改規章、徽章,設定是否「顯示於搜尋結果」。" longdescription="更改規章、徽章,設定是否「顯示於搜尋結果」。 這可在「基本資料」欄設定。" name="group change identity" value="11"/> </action_set> - <action_set description="These Abilities include powers to deed, modify, and sell land in this group's land holdings. To get to the About Land window, right-click the ground and select 'About Land', or click the 'i' icon in the Navigation Bar." name="Parcel Management"> - <action description="讓渡土地或購買土地給群組" longdescription="Deed land and buy land for group. This is done in About Land > General tab." name="land deed" value="12"/> - <action description="Abandon land to Governor Linden" longdescription="Abandon land to Governor Linden. *WARNING* Any Member in a Role with this Ability can abandon group-owned land in About Land > General tab, reverting it to Linden ownership without a sale! Be sure you know what you're doing before assigning this Ability." name="land release" value="13"/> - <action description="Set land for sale info" longdescription="Set land for sale info. *WARNING* Any Member in a Role with this Ability can sell group-owned land in About Land > General tab as they wish! Be sure you know what you're doing before assigning this Ability." name="land set sale info" value="14"/> - <action description="Subdivide and join parcels" longdescription="Subdivide and join parcels. This is done by right-clicking the ground, 'Edit Terrain', and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click 'Subdivide'. To join, select two or more contiguous parcels and click 'Join'." name="land divide join" value="15"/> + <action_set description="這些能力包括有權讓渡、修改或出售本群組擁有的土地。 欲前往「土地資料」視窗,請在地面任一處點按右鍵,選擇「土地資料」,或點按導覽列的「i」圖示。" name="Parcel Management"> + <action description="讓渡土地或購買土地給群組" longdescription="讓渡土地或為群組購地。 這可在「土地資料」> 基本頁籤完成。" name="land deed" value="12"/> + <action description="放棄土地,將所有權轉給 Governor Linden(林登總長)" longdescription="放棄土地,將所有權轉給 Governor Linden(林登總長)。 *警告* 任何身負具有這能力的角色的成員,都可以到「土地資料」> 基本頁籤放棄任何群組所有的土地,不經出售就將所有權轉給 Linden! 賦予這項能力之前,敬請慎重考慮。" name="land release" value="13"/> + <action description="設定待售土地資訊" longdescription="設定待售土地資訊。 *警告* 任何身負具有這能力的角色的成員,都可以到「土地資料」> 基本頁籤任意出售群組所有的土地! 賦予這項能力之前,敬請慎重考慮。" name="land set sale info" value="14"/> + <action description="分割或合併地段" longdescription="分割或合併地段。 欲進行此動作,請在地面任一處點按右鍵,選擇「編輯地形」,並在土地上拖曳滑鼠選取一個範圍。 要進行分割,做好選擇後點按「分割」。 要合併,選取至少兩塊相鄰地段,再點選「合併」。" name="land divide join" value="15"/> </action_set> - <action_set description="These Abilities include powers to change the parcel name and publish settings, Find directory visibility, and landing point & TP routing options." name="Parcel Identity"> - <action description="Toggle 'Show Place in Search' and set category" longdescription="Toggle 'Show Place in Search' and setting a parcel's category in About Land > Options tab." name="land find places" value="17"/> - <action description="Change parcel name, description, and 'Show Place in Search' settings" longdescription="Change parcel name, description, and 'Show Place in Search' settings. This is done in About Land > Options tab." name="land change identity" value="18"/> - <action description="Set landing point and set teleport routing" longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land > Options tab." name="land set landing point" value="19"/> + <action_set description="這些能力包括可更改地段名稱和發佈設定、設定是否公開到搜尋結果、設定登陸地點和瞬間傳送繞路選項。" name="Parcel Identity"> + <action description="切換「將地點顯示在搜尋結果」設定,並選定類別" longdescription="切換「將地點顯示在搜尋結果」設定,並在「土地資料」> 選項頁籤設定地段類別。" name="land find places" value="17"/> + <action description="更改地段名稱、描述,和「將地點顯示在搜尋結果」設定。" longdescription="更改地段名稱、描述,和「將地點顯示在搜尋結果」設定。 這可在「土地資料」> 選項頁籤完成。" name="land change identity" value="18"/> + <action description="設定登陸地點和瞬間傳送繞路設定。" longdescription="在群組所有的地段上,身負具此能力的成員,可以設定人們瞬間傳送進來時的登陸地點,和瞬間傳送的繞路選項。 這可在「土地資料」> 選項頁籤完成。" name="land set landing point" value="19"/> </action_set> - <action_set description="These Abilities include powers which affect parcel options, such as 'Create Objects', 'Edit Terrain', and music & media settings." name="Parcel Settings"> - <action description="Change music & media settings" longdescription="Change streaming music and movie settings in About Land > Media tab." name="land change media" value="20"/> - <action description="Toggle 'Edit Terrain'" longdescription="Toggle 'Edit Terrain'. *WARNING* About Land > Options tab > Edit Terrain allows anyone to terraform your land's shape, and place and move Linden plants. Be sure you know what you're doing before assigning this Ability. Editing terrain is toggled in About Land > Options tab." name="land edit" value="21"/> - <action description="Toggle various About Land > Options settings" longdescription="Toggle 'Safe (no damage)', 'Fly', and allow other Residents to: 'Edit Terrain', 'Build', 'Create Landmarks', and 'Run Scripts' on group-owned land in About Land > Options tab." name="land options" value="22"/> + <action_set description="這些能力包括有權更改地段選項,例如「新建物件」、「編輯地形」,和音樂、媒體設定等。" name="Parcel Settings"> + <action description="更改音樂和媒體設定" longdescription="在「土地資料」> 媒體頁籤更改串流音樂和影片設定。" name="land change media" value="20"/> + <action description="切換「編輯地形」設定" longdescription="切換「編輯地形」設定。 *警告* 「土地資料」> 「選項」頁籤 >「編輯地形」可允許任何人變更你的土地形狀,放置或移動 Linden 植物。 賦予這項能力之前,敬請慎重考慮。 編輯地形可在「土地資料」> 選項頁籤做切換。" name="land edit" value="21"/> + <action description="切換各項「土地資料」> 選項設定" longdescription="在「土地資料」> 選項頁籤切換「安全(無傷害)」設定,並允許其他居民在群組所有土地上「編輯地形」、「建製」、「建立地標」、「執行腳本」。" name="land options" value="22"/> </action_set> - <action_set description="These Abilities include powers which allow Members to bypass restrictions on group-owned parcels." name="Parcel Powers"> - <action description="Always allow 'Edit Terrain'" longdescription="Members in a Role with this Ability can edit terrain on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow edit land" value="23"/> - <action description="Always allow 'Fly'" longdescription="Members in a Role with this Ability can fly on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow fly" value="24"/> - <action description="Always allow 'Create Objects'" longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow create" value="25"/> - <action description="總是允許 '創造地標'" longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow landmark" value="26"/> - <action description="Allow 'Set Home to Here' on group land" longdescription="Members in a Role with this Ability can use World menu > Landmarks > Set Home to Here on a parcel deeded to this group." name="land allow set home" value="28"/> - <action description="Allow 'Event Hosting' on group land" longdescription="Members in a Role with this Ability can select group owned parcels as venus when hosting an event." name="land allow host event" value="41"/> + <action_set description="這些能力包括可允許成員在群組所有地段上規避限制。" name="Parcel Powers"> + <action description="固定允許「編輯地形」" longdescription="身負具此能力的角色的成員可以在群組所有地段上編輯地形,無論這功能在「土地資料」> 選項頁籤裡是否被禁止。" name="land allow edit land" value="23"/> + <action description="固定允許「飛行」" longdescription="身負具此能力的角色的成員可以在群組所有地段上飛行,無論這能力是否在「土地資料」> 選項頁籤裡被禁止。" name="land allow fly" value="24"/> + <action description="固定允許「新建物件」" longdescription="身負具此能力的角色的成員可以在群組所有地段上新建物件,無論這能力是否在「土地資料」> 選項頁籤裡被禁止。" name="land allow create" value="25"/> + <action description="總是允許「新建地標」" longdescription="身負具此能力的角色的成員可以將群組所有的地段設為地標,無論這能力是否在「土地資料」> 選項頁籤裡被禁止。" name="land allow landmark" value="26"/> + <action description="允許在群組所有土地上「將這裡設為我的家」" longdescription="身負具此能力的角色的成員,可以在讓渡給這群組的地段上使用「世界」選單 > 地標 > 「將這裡設為我的家」。" name="land allow set home" value="28"/> + <action description="允許在群組所有土地上「開辦活動」" longdescription="身負具這能力的角色的成員,可以選擇群組所有的地段作為開辦活動的場地。" name="land allow host event" value="41"/> </action_set> - <action_set description="These Abilities include powers to allow or restrict access to group-owned parcels, including freezing and ejecting Residents." name="Parcel Access"> - <action description="Manage parcel Access lists" longdescription="Manage parcel Access lists in About Land > Access tab." name="land manage allowed" value="29"/> - <action description="Manage parcel Ban lists" longdescription="Manage parcel Ban lists in About Land > Access tab." name="land manage banned" value="30"/> - <action description="Change parcel 'Sell passes to' settings" longdescription="Change parcel 'Sell passes to' settings in About Land > Access tab." name="land manage passes" value="31"/> - <action description="將地段內的居民踢出及凍結" longdescription="Members in a Role with this Ability can handle an unwelcome Resident on a group-owned parcel by right-clicking them, then selecting 'Eject' or 'Freeze'." name="land admin" value="32"/> + <action_set description="這些能力包括可允許或限制人們出入群組所有的地段,包括把居民凍結或踢出。" name="Parcel Access"> + <action description="管理地段出入許可名單" longdescription="在「土地資料」> 出入許可頁籤管理地段的出入許可名單。" name="land manage allowed" value="29"/> + <action description="管理地段禁入名單" longdescription="在「土地資料」> 出入許可頁籤管理地段的禁入名單。" name="land manage banned" value="30"/> + <action description="變更地段的「通行證出售對象」設定" longdescription="在「土地資料」> 出入許可頁籤變更地段的「通行證出售對象」設定。" name="land manage passes" value="31"/> + <action description="將地段內的居民踢出及凍結" longdescription="身負具此能力的角色的成員,可以在群組所有地段上處置不受歡迎的居民,按右鍵加以「踢出」或「凍結」。" name="land admin" value="32"/> </action_set> - <action_set description="These Abilities include powers to allow members to return objects and place and move Linden plants. This is useful for Members to clean up litter and do landscaping, but it should also be used with care, because there's no undo for returning objects." name="Parcel Content"> - <action description="Return objects owned by group" longdescription="Return objects on group-owned parcels that are owned by the group in About Land > Objects tab." name="land return group owned" value="48"/> - <action description="Return objects set to group" longdescription="Return objects on group-owned parcels that are set to the group in About Land > Objects tab." name="land return group set" value="33"/> - <action description="退回非群組物件" longdescription="Return objects on group-owned parcels that are non-group in About Land > Objects tab." name="land return non group" value="34"/> - <action description="Landscaping using Linden plants" longdescription="Landscaping ability to place and move Linden trees, plants, and grasses. These items can be found in your inventory's Library > Objects folder, or they can be created via the Build menu." name="land gardening" value="35"/> + <action_set description="這些能力包括有權允許成員送返物件,或放置或移動 Linden 植物。 這能力的用處是讓成員清理一下土地,做一做景觀佈置,但必須小心使用,因為物件一旦被送返後即無法復原。" name="Parcel Content"> + <action description="送返群組所有的物件" longdescription="在「土地資料」> 物件頁籤送返位於群組所擁有地段上的群組所擁有物件。" name="land return group owned" value="48"/> + <action description="送返設給群組的物件" longdescription="在「土地資料」> 物件頁籤送返位於群組所擁有地段的設給群組的物件。" name="land return group set" value="33"/> + <action description="退回非群組物件" longdescription="在「土地資料」> 物件頁籤送返位於群組所擁有地段的非群組物件。" name="land return non group" value="34"/> + <action description="用 Linden 植物佈置景觀。" longdescription="允許放置或移動 Linden 樹種、草地和其他植物的景觀佈置能力。 這些物項在你收納區的資源庫 > 物件資料夾可找到,你也可以透過「建製」選單加以新建。" name="land gardening" value="35"/> </action_set> - <action_set description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Build Tools > General tab. Right-click an object and Edit to see its settings." name="Object Management"> - <action description="讓渡物件給群組" longdescription="Deed objects to group in the Build Tools > General tab." name="object deed" value="36"/> - <action description="Manipulate (move, copy, modify) group-owned objects" longdescription="Manipulate (move, copy, modify) group-owned objects in the Build Tools > General tab." name="object manipulate" value="38"/> - <action description="Set group-owned objects for sale" longdescription="Set group-owned objects for sale in the Build Tools > General tab." name="object set sale" value="39"/> + <action_set description="這些能力包括有權讓渡、修改或出售本群組擁有的物件。 這些變更可在「建製工具」> 基本頁籤完成。 對一個物件點按右鍵,選擇「編輯」即可察看其設定。" name="Object Management"> + <action description="讓渡物件給群組" longdescription="在「建製工具」> 基本頁籤將物件讓渡給群組。" name="object deed" value="36"/> + <action description="操縱(移動、複製、修改)群組所擁有物件" longdescription="在「建製工具」> 基本頁籤操縱(移動、複製、修改)群組所擁有物件。" name="object manipulate" value="38"/> + <action description="設定出售群組所擁有物件" longdescription="在「建製工具」> 基本頁籤設定出售群組所擁有物件。" name="object set sale" value="39"/> </action_set> - <action_set description="These Abilities include powers which require Members to pay group liabilities and receive group dividends, and restrict access to group account history." name="Accounting"> - <action description="Pay group liabilities and receive group dividends" longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees." name="accounting accountable" value="40"/> + <action_set description="這些能力包括有權要求成員支付群組開銷、收取群組利息,限制群組帳號歷史開放對象。" name="Accounting"> + <action description="支付群組開銷,收取群組利息" longdescription="身負具這能力的角色的成員,將自動支付群組開銷並收取群組利息。 這表示他們將獲取群組所擁有土地出售後的部分收入,每日結算,同時並分攤地段刊登費等開銷。" name="accounting accountable" value="40"/> </action_set> - <action_set description="These Abilities include powers to allow Members to send, receive, and view group Notices." name="Notices"> - <action description="送出通知" longdescription="Members in a Role with this Ability can send Notices via the Group > Notices section." name="notices send" value="42"/> - <action description="接收通知與察看過去通知" longdescription="Members in a Role with this Ability can receive Notices and view past Notices in Group > Notices section." name="notices receive" value="43"/> + <action_set description="這些能力包括可允許成員發送、接收並察看群組通知。" name="Notices"> + <action description="送出通知" longdescription="身負具這能力的角色的成員,可以到「群組」> 通知欄發送通知。" name="notices send" value="42"/> + <action description="接收通知與察看過去通知" longdescription="身負具這能力的角色的成員,可以到「群組」> 通知欄接收通知並察看過去的通知。" name="notices receive" value="43"/> </action_set> - <action_set description="These Abilities include powers to allow or restrict access to group chat sessions and group voice chat." name="Chat"> - <action description="加入群組聊天" longdescription="Members in a Role with this Ability can join group chat sessions, for text and voice." name="join group chat" value="16"/> - <action description="加入群組語音聊天" longdescription="Members in a Role with this Ability can join group voice chat sessions. NOTE: The Join Group Chat ability is required to access the voice chat session." name="join voice chat" value="27"/> - <action description="適度成人內容的群組聊天" longdescription="Members in a Role with this Ability can control access and participation in group voice and text chat sessions." name="moderate group chat" value="37"/> + <action_set description="這些能力包括可允許或限制人們加入群組聊天會話和群組語音聊天。" name="Chat"> + <action description="加入群組聊天" longdescription="身負具這能力的角色的成員,可以加入群組的文字或語音聊天會話。" name="join group chat" value="16"/> + <action description="加入群組語音聊天" longdescription="身負具這能力的角色的成員,可以加入群組的語音聊天會話。 注意:欲加入語音聊天會話,需有「加入群組聊天」能力。" name="join voice chat" value="27"/> + <action description="適度成人內容的群組聊天" longdescription="身負具這能力的角色的成員,可以控制誰可加入群組語音和文字聊天會話。" name="moderate group chat" value="37"/> </action_set> </role_actions> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml index 7d8a502594..83a9bdf6a5 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml @@ -11,7 +11,7 @@ (狀態) </text> <text name="currentlook_name"> - MyOutfit With a really Long Name like MOOSE + 名稱很長、很長、很長、很長、很長的 MyOutfit </text> <button label="" name="edit_outfit_btn" tool_tip="編輯這裝扮"/> </panel> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml index 7abe95a402..c8aae15011 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml @@ -1,16 +1,37 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="事物" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> + <layout_stack name="inventory_layout_stack"> + <layout_panel name="inbox_layout_panel"> + <panel label="" name="marketplace_inbox"> + <string name="InboxLabelWithArg"> + 收到的物項 ([NUM]) + </string> + <string name="InboxLabelNoArg"> + 收到的物項 + </string> + <button label="收到的物項" name="inbox_btn"/> + <text name="inbox_fresh_new_count"> + [NUM] 項新的 + </text> + <panel name="inbox_inventory_placeholder_panel" tool_tip="將物項拖曳置放到收納區,即可開始使用"> + <text name="inbox_inventory_placeholder"> + 從第二人生購物市集購得物項將送到這裡。 + </text> + </panel> + </panel> + </layout_panel> + </layout_stack> <panel name="button_panel"> <layout_stack name="button_panel_ls"> <layout_panel name="info_btn_lp"> <button label="檔案" name="info_btn" tool_tip="顯示物件檔案"/> </layout_panel> <layout_panel name="share_btn_lp"> - <button label="分享" name="share_btn" tool_tip="Share an inventory item"/> + <button label="分享" name="share_btn" tool_tip="分享一個收納區物品"/> </layout_panel> <layout_panel name="shop_btn_lp"> - <button label="Shop" name="shop_btn" tool_tip="Open Marketplace webpage"/> + <button label="購物" name="shop_btn" tool_tip="開啟 Marketplace 購物市集網頁"/> <button label="穿上" name="wear_btn" tool_tip="穿上所選擇的裝扮"/> <button label="播放" name="play_btn"/> <button label="瞬間傳送" name="teleport_btn" tool_tip="瞬間傳送到所選的區域"/> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml index adc815fb4b..1b093e0ecd 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml @@ -3,6 +3,9 @@ <panel.string name="unknown"> (未知) </panel.string> + <panel.string name="unknown_multiple"> + (未知 / 多項) + </panel.string> <panel.string name="public"> (公開) </panel.string> @@ -10,7 +13,7 @@ 你可以: </panel.string> <panel.string name="owner_can"> - 擁有者可以: + 所有人可以: </panel.string> <panel.string name="acquiredDate"> [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] @@ -19,7 +22,7 @@ (收納區) </panel.string> <panel.string name="origin_inworld"> - (Inworld) + (在虛擬世界) </panel.string> <text name="title" value="物品檔案"/> <text name="origin" value="(收納區)"/> @@ -35,7 +38,7 @@ 創造者: </text> <text name="LabelOwnerTitle"> - 擁有者: + 所有人: </text> <text name="LabelAcquiredTitle"> 取得於: @@ -45,26 +48,26 @@ 你可以: </text> <check_box label="修改" name="CheckOwnerModify"/> - <check_box label="覆製" name="CheckOwnerCopy"/> + <check_box label="恚庨" name="CheckOwnerCopy"/> <check_box label="轉移" name="CheckOwnerTransfer"/> <text name="AnyoneLabel"> 任何人: </text> - <check_box label="覆製" name="CheckEveryoneCopy"/> + <check_box label="恚庨" name="CheckEveryoneCopy"/> <text name="GroupLabel"> 群組: </text> - <check_box label="分享" name="CheckShareWithGroup" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> + <check_box label="分享" name="CheckShareWithGroup" tool_tip="允許此群組所有成員共享你修改此物件的權限。 你必須讓渡才能啟動角色限制。"/> <text name="NextOwnerLabel"> - 下一個擁有者: + 下一個所有人: </text> <check_box label="修改" name="CheckNextOwnerModify"/> - <check_box label="覆製" name="CheckNextOwnerCopy"/> - <check_box label="轉移" name="CheckNextOwnerTransfer" tool_tip="Next owner can give away or resell this object"/> + <check_box label="恚庨" name="CheckNextOwnerCopy"/> + <check_box label="轉移" name="CheckNextOwnerTransfer" tool_tip="下一個所有人可贈送或轉售這個物件"/> </panel> <check_box label="出售" name="CheckPurchase"/> <combo_box name="combobox sale copy"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="恚庨" name="Copy"/> <combo_box.item label="原件" name="Original"/> </combo_box> <spinner label="價格: L$" name="Edit Cost"/> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml index 3d46e52726..982dde4010 100644 --- a/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml @@ -7,28 +7,34 @@ 讓渡 </panel.string> <panel.string name="text modify info 1"> - 你可以修改這個物件 + 你能修改這個物件 </panel.string> <panel.string name="text modify info 2"> - 你可以修改這些物件 + 你能修改這些物件 </panel.string> <panel.string name="text modify info 3"> - 你不可以修改這個物件 + 你不能修改這個物件 </panel.string> <panel.string name="text modify info 4"> - 你不可以修改這些物件 + 你不能修改這些物件 + </panel.string> + <panel.string name="text modify info 5"> + 無法跨地區修改這個物件 + </panel.string> + <panel.string name="text modify info 6"> + 無法跨地區修改這些物件 </panel.string> <panel.string name="text modify warning"> - 這個物件有聯結到其他部分 + 這個物件含有聯結的部分 </panel.string> <panel.string name="Cost Default"> 價格: L$ </panel.string> <panel.string name="Cost Total"> - 總價: L$ + 總價:L$ </panel.string> <panel.string name="Cost Per Unit"> - 單價: L$ + 單價:L$ </panel.string> <panel.string name="Cost Mixed"> 混合價格 @@ -37,7 +43,7 @@ 混合銷售 </panel.string> <text name="title" value="物件檔案"/> - <text name="where" value="(Inworld)"/> + <text name="where" value="(在虛擬世界)"/> <panel label="" name="properties_panel"> <text name="Name:"> 名稱: @@ -49,23 +55,23 @@ 創造者: </text> <text name="Owner:"> - 擁有者: + 所有人: </text> <text name="Group_label"> 群組: </text> - <button name="button set group" tool_tip="選擇一個群組以分享這個物件的權限"/> + <button name="button set group" tool_tip="選擇一個群組以分享這物件的權限"/> <name_box initial_value="載入中..." name="Group Name Proxy"/> - <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/> + <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="「讓渡」會把這物件贈送出去並賦予「下一個所有人」權限。 群組所分享的物件可由群組職員加以讓渡。"/> <text name="label click action"> - 點擊以: + 點按以: </text> <combo_box name="clickaction"> <combo_box.item label="觸碰(預設)" name="Touch/grab(default)"/> <combo_box.item label="坐在物件上" name="Sitonobject"/> <combo_box.item label="購買物件" name="Buyobject"/> <combo_box.item label="支付物件" name="Payobject"/> - <combo_box.item label="開啟" name="Open"/> + <combo_box.item label="打開" name="Open"/> </combo_box> <panel name="perms_inv"> <text name="perm_modify"> @@ -74,27 +80,30 @@ <text name="Anyone can:"> 任何人: </text> - <check_box label="覆製" name="checkbox allow everyone copy"/> + <check_box label="恚庨" name="checkbox allow everyone copy"/> <check_box label="移動" name="checkbox allow everyone move"/> <text name="GroupLabel"> 群組: </text> - <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> + <check_box label="分享" name="checkbox share with group" tool_tip="允許此群組所有成員共享你修改此物件的權限。 你必須讓渡才能啟動角色限制。"/> <text name="NextOwnerLabel"> - 下一個擁有者: + 下一個所有人: </text> <check_box label="修改" name="checkbox next owner can modify"/> - <check_box label="覆製" name="checkbox next owner can copy"/> - <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個擁有者可以送出或轉售這個物件"/> + <check_box label="恚庨" name="checkbox next owner can copy"/> + <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個所有人可贈送或轉售這個物件"/> </panel> <check_box label="出售" name="checkbox for sale"/> <combo_box name="sale type"> - <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="恚庨" name="Copy"/> <combo_box.item label="內容" name="Contents"/> <combo_box.item label="原件" name="Original"/> </combo_box> <spinner label="價格: L$" name="Edit Cost"/> <check_box label="顯示在搜尋中" name="search_check" tool_tip="讓其他人可以在搜尋結果中察看到此物件"/> + <text name="pathfinding_attributes_label"> + 尋徑屬性: + </text> <text name="B:"> B: </text> @@ -115,7 +124,7 @@ </text> </panel> <panel name="button_panel"> - <button label="開啟" name="open_btn"/> + <button label="打開" name="open_btn"/> <button label="支付" name="pay_btn"/> <button label="購買" name="buy_btn"/> <button label="細節" name="details_btn"/> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index 6dbe44d32e..3f17324006 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -29,11 +29,14 @@ 快取清除中... </string> <string name="StartupInitializingTextureCache"> - 材質快取初始化中... + 正在初始化材質快取... </string> <string name="StartupInitializingVFS"> VFS 初始化中... </string> + <string name="StartupRequireDriverUpdate"> + 顯像初始化失敗。 請更新你的顯像卡驅動程式! + </string> <string name="ProgressRestoring"> 回存中... </string> @@ -44,7 +47,7 @@ 全亮(舊版) </string> <string name="LoginInProgress"> - 登入中。[APP_NAME] 可能出現凍結狀態。請耐心稍等。 + 登入中。[APP_NAME] 可能看似凍結,請耐心稍等。 請稍候。 </string> <string name="LoginInProgressNoFrozen"> 登入中... @@ -56,7 +59,7 @@ 進行帳戶維護... </string> <string name="LoginAttempt"> - 先前企圖嘗試登入失敗。現登入中,嘗試 [NUMBER] + 前一次登入失敗。 登入中,第 [NUMBER] 次嘗試 </string> <string name="LoginPrecaching"> 世界載入中... @@ -74,10 +77,10 @@ 驗證快取檔案(約需 60-90 秒左右)... </string> <string name="LoginProcessingResponse"> - 回應處理中... + 正在處理回應... </string> <string name="LoginInitializingWorld"> - 世界初始化中... + 正在初始化虛擬世界… </string> <string name="LoginDecodingImages"> 圖像解碼中... @@ -91,6 +94,12 @@ <string name="LoginQuicktimeOK"> QuickTime 已成功初始化。 </string> + <string name="LoginRequestSeedCapGrant"> + 詢問地區負荷力… + </string> + <string name="LoginRetrySeedCapGrant"> + 詢問地區負荷力,第 [NUMBER] 次嘗試… + </string> <string name="LoginWaitingForRegionHandshake"> 地區交握等待中... </string> @@ -101,25 +110,25 @@ 服裝下載中... </string> <string name="InvalidCertificate"> - 伺服器回傳一個無效果損壞的憑證。請連繫網格管理者。 + 伺服器回傳一個無效或損壞的憑證。 請聯絡網格管理員。 </string> <string name="CertInvalidHostname"> - An invalid hostname was used to access the server, please check your SLURL or Grid hostname. + 用了無效的主機名來聯絡伺服器,請檢查你的 SLURL 或網格主機名。 </string> <string name="CertExpired"> - The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator. + 網格傳回的憑證似乎已過期。 請檢查系統時鐘,或聯絡網格管理員。 </string> <string name="CertKeyUsage"> - The certificate returned by the server could not be used for SSL. Please contact your Grid administrator. + 伺服器傳回的憑證無法用於 SSL。 請聯絡網格管理員。 </string> <string name="CertBasicConstraints"> - Too many certificates were in the servers Certificate chain. Please contact your Grid administrator. + 伺服器憑證鍊中的憑證數目太多。 請聯絡網格管理員。 </string> <string name="CertInvalidSignature"> - The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator. + 無法檢驗通過網格伺服器傳回的憑證簽名。 請聯絡網格管理員。 </string> <string name="LoginFailedNoNetwork"> - Network Error: Could not establish connection, please check your network connection. + 網路錯誤:無法建立連線,請檢查網路連線是否正常。 </string> <string name="LoginFailed"> 登入失敗。 @@ -128,10 +137,138 @@ 結束退出 </string> <string name="create_account_url"> - http://join.secondlife.com/ + http://join.secondlife.com/?sourceid=[sourceid] + </string> + <string name="LoginFailedViewerNotPermitted"> + 你目前所用的 Viewer 已經無法再進入第二人生。 請到這個頁面下載最新 Viewer: +http://secondlife.com/download + +欲知詳情,請參閱下面的常見問題集: +http://secondlife.com/viewer-access-faq + </string> + <string name="LoginIntermediateOptionalUpdateAvailable"> + 有可以選擇性安裝的更新版:[VERSION] + </string> + <string name="LoginFailedRequiredUpdate"> + 你必須更新為這個版本:[VERSION] + </string> + <string name="LoginFailedAlreadyLoggedIn"> + 此用戶已經登入。 + </string> + <string name="LoginFailedAuthenticationFailed"> + 抱歉! 我們無法讓你登入。 +請檢查確定你輸入了正確的 + * 使用者名稱(例:bobsmith123 或 steller.sunshine) + * 密碼 +並請確定鍵盤沒有鎖定大寫鍵。 + </string> + <string name="LoginFailedPasswordChanged"> + 為了安全起見,已經變更你的密碼。 +請到位於 http://secondlife.com/password 的帳號頁面 +回答安全驗證問題後,重設密碼。 +如有造成不便請多包涵。 + </string> + <string name="LoginFailedPasswordReset"> + 我們系統有所變更,你必須重設密碼。 +請到位於 http://secondlife.com/password 的帳號頁面 +回答安全驗證問題後,重設密碼。 +如有造成不便請多包涵。 + </string> + <string name="LoginFailedEmployeesOnly"> + 第二人生目前暫時關閉進行維護。 +目前僅允許林登員工登入。 +請到 www.secondlife.com/status 察看最新公告。 + </string> + <string name="LoginFailedPremiumOnly"> + 第二人生此時暫時限制登入,以確保不影響效能,讓目前虛擬世界裡的用戶享受最佳的體驗。 + +免費帳戶的用戶此時暫時無法進入第二人生,因為我們必須優先容納付費用戶。 + </string> + <string name="LoginFailedComputerProhibited"> + 無法從這部電腦進入第二人生。 +如你認為這是我們弄錯,請聯絡 support@secondlife.com。 + </string> + <string name="LoginFailedAcountSuspended"> + 你的帳號要等到 [TIME] (太平洋時間)才可使用。 + </string> + <string name="LoginFailedAccountDisabled"> + 此時無法完成你的請求。 +請到 http://secondlife.com/support 聯絡支援人員獲得幫助。 +如果你無法變更密碼,請致電 (866) 476-9763 (美國)。 + </string> + <string name="LoginFailedTransformError"> + 登入時的資料不一致。 +請聯絡 support@secondlife.com。 + </string> + <string name="LoginFailedAccountMaintenance"> + 你的帳號目前正在進行小規模的維護。 +你的帳號要等到 [TIME] (太平洋時間)才可使用。 +如你認為這是我們弄錯,請聯絡 support@secondlife.com。 + </string> + <string name="LoginFailedPendingLogoutFault"> + 模擬器回應:登出請求出錯。 + </string> + <string name="LoginFailedPendingLogout"> + 系統正在處理你的登出。 +你的帳號要等到 [TIME] (太平洋時間)才可使用。 + </string> + <string name="LoginFailedUnableToCreateSession"> + 無法建立有效的時域。 + </string> + <string name="LoginFailedUnableToConnectToSimulator"> + 無法連接到模擬器。 + </string> + <string name="LoginFailedRestrictedHours"> + 你的帳號僅能在 [START] 到 [END] (太平洋時間)時段進入第二人生。 +請耐心等到該時段再回來。 +如你認為這是我們弄錯,請聯絡 support@secondlife.com。 + </string> + <string name="LoginFailedIncorrectParameters"> + 錯誤的參數。 +如你認為這是我們弄錯,請聯絡 support@secondlife.com。 + </string> + <string name="LoginFailedFirstNameNotAlphanumeric"> + 全名的第一個字(first name)須為英文字母或數字。 +如你認為這是我們弄錯,請聯絡 support@secondlife.com。 + </string> + <string name="LoginFailedLastNameNotAlphanumeric"> + 全名的第二個字(last name)須為英文字母或數字。 +如你認為這是我們弄錯,請聯絡 support@secondlife.com。 + </string> + <string name="LogoutFailedRegionGoingOffline"> + 地區即將離線。 +請稍待一分鐘再試。 + </string> + <string name="LogoutFailedAgentNotInRegion"> + 用戶不在地區裡。 +請稍待一分鐘再試。 + </string> + <string name="LogoutFailedPendingLogin"> + 地區正在登入另一個時域。 +請稍待一分鐘再試。 + </string> + <string name="LogoutFailedLoggingOut"> + 地區正在登入上一個時域。 +請稍待一分鐘再試。 + </string> + <string name="LogoutFailedStillLoggingOut"> + 地區正在登出上一個時域。 +請稍待一分鐘再試。 + </string> + <string name="LogoutSucceeded"> + 地區剛剛登出上一個時域。 +請稍待一分鐘再試。 + </string> + <string name="LogoutFailedLogoutBegun"> + 地區已經開始登出程序。 +請稍待一分鐘再試。 + </string> + <string name="LoginFailedLoggingOutSession"> + 系統已經開始登出你的上一個時域。 +請稍待一分鐘再試。 </string> <string name="AgentLostConnection"> - 這個地區可能遭遇問題,請檢查你的網路連線。 + 本區域可能正發生問題。 請檢查你的網際網路連線是否正常。 </string> <string name="SavingSettings"> 你的設定儲存中... @@ -158,7 +295,7 @@ (無名稱) </string> <string name="TooltipOwner"> - 擁有者: + 所有人: </string> <string name="TooltipPublic"> 公開 @@ -196,60 +333,90 @@ <string name="TooltipMustSingleDrop"> 只有一個物品可以被拖曳到此處 </string> - <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipOutboxDragToWorld"> + 商家發件匣內的物項無法產生到虛擬世界 + </string> + <string name="TooltipOutboxNoTransfer"> + 至少一個物件無法出售或轉移。 + </string> + <string name="TooltipOutboxNotInInventory"> + 你的商家發件匣只能接受直接來自收納區的物項。 + </string> + <string name="TooltipOutboxWorn"> + 你穿著中的物項無法放入商家發件匣。 + </string> + <string name="TooltipOutboxCallingCard"> + 名片不得放入商家發件匣 + </string> + <string name="TooltipOutboxFolderLevels"> + 巢狀資料夾深度超過 3 + </string> + <string name="TooltipOutboxTooManyFolders"> + 頂層資料夾的子資料夾數目超過 20 + </string> + <string name="TooltipOutboxTooManyObjects"> + 頂層資料夾物項數目超過 200 + </string> + <string name="TooltipDragOntoOwnChild"> + 資料夾不得移到其子資料夾底下 + </string> + <string name="TooltipDragOntoSelf"> + 資料夾移動的目標不得為它本身 + </string> <string name="TooltipHttpUrl"> - 點擊以察看這個網頁 + 點按以察看這個網頁 </string> <string name="TooltipSLURL"> - 點擊以察看這個位置資訊 + 點按以察看這個位置資訊 </string> <string name="TooltipAgentUrl"> - 點擊以察看這個居民檔案 + 點按以察看這個居民檔案 </string> <string name="TooltipAgentInspect"> 瞭解更多有關這個居民 </string> <string name="TooltipAgentMute"> - 點擊以封鎖這位居民 + 點按以封鎖這位居民 </string> <string name="TooltipAgentUnmute"> - 點擊以解除封鎖這位居民 + 點按以解除封鎖這位居民 </string> <string name="TooltipAgentIM"> - 點擊開始 IM 這位居民 + 點按開始 IM 這位居民 </string> <string name="TooltipAgentPay"> - 點擊以支付這位居民 + 點按以支付這位居民 </string> <string name="TooltipAgentOfferTeleport"> - 點擊以送出瞬間傳送邀請給這位居民 + 點按以送出瞬間傳送邀請給這位居民 </string> <string name="TooltipAgentRequestFriend"> - 點擊以送出交友邀請給這位居民 + 點按以送出交友邀請給這位居民 </string> <string name="TooltipGroupUrl"> - 點擊以察看這個群組的描述 + 點按以察看這個群組的描述 </string> <string name="TooltipEventUrl"> - 點擊以察看這個活動的描述 + 點按以察看這個活動的描述 </string> <string name="TooltipClassifiedUrl"> - Click to view this classified + 點按察看這個個人廣告 </string> <string name="TooltipParcelUrl"> - 點擊以察看這個地段的描述 + 點按以察看這個地段的描述 </string> <string name="TooltipTeleportUrl"> - 點擊以傳送到這個位置 + 點按以傳送到這個位置 </string> <string name="TooltipObjectIMUrl"> - 點擊以察看這個物件的描述 + 點按以察看這個物件的描述 </string> <string name="TooltipMapUrl"> - 點擊以察看此處在地圖上的位置 + 點按以察看此處在地圖上的位置 </string> <string name="TooltipSLAPP"> - 點擊以執行 secondlife:// 指令 + 點按以執行 secondlife:// 指令 </string> <string name="CurrentURL" value="目前網址:[CurrentURL]"/> <string name="SLurlLabelTeleport"> @@ -304,7 +471,7 @@ 搜尋中... </string> <string name="NoneFound"> - 未發現。 + 查無結果。 </string> <string name="RetrievingData"> 檢索... @@ -328,7 +495,7 @@ (無) </string> <string name="AvalineCaller"> - Avaline Caller [ORDER] + Avaline 通話者 [ORDER] </string> <string name="AssetErrorNone"> 無錯誤 @@ -355,10 +522,10 @@ 檔案傳輸逾時 </string> <string name="AssetErrorCircuitGone"> - Circuit gone + 失去線路 </string> <string name="AssetErrorPriceMismatch"> - Viewer and server do not agree on price + Viewer 和伺服器無法同意價格 </string> <string name="AssetErrorUnknownStatus"> 未知狀態 @@ -391,13 +558,13 @@ 資料夾 </string> <string name="root"> - root + 根目錄 </string> <string name="lsl2 script"> - LSL2 script + LSL2 腳本 </string> <string name="lsl bytecode"> - LSL bytecode + LSL 位元組碼 </string> <string name="tga texture"> tga 材質 @@ -409,7 +576,7 @@ 快照 </string> <string name="lost and found"> - Lost and Found + 失物招領 </string> <string name="targa image"> targa 圖像 @@ -438,6 +605,9 @@ <string name="symbolic folder link"> 資料夾聯結 </string> + <string name="mesh"> + 網面 + </string> <string name="AvatarEditingAppearance"> (外觀編輯中) </string> @@ -457,88 +627,88 @@ 生氣 </string> <string name="anim_away"> - Away + 離開 </string> <string name="anim_backflip"> - Backflip + 後空翻 </string> <string name="anim_express_laugh"> - Belly Laugh + 捧腹大笑 </string> <string name="anim_express_toothsmile"> - BigSmile + 大微笑 </string> <string name="anim_blowkiss"> - Blow Kiss + 飛吻 </string> <string name="anim_express_bored"> 無聊 </string> <string name="anim_bow"> - Bow + 彎腰點頭 </string> <string name="anim_clap"> 拍手 </string> <string name="anim_courtbow"> - Court Bow + 宮廷鞠躬 </string> <string name="anim_express_cry"> 哭泣 </string> <string name="anim_dance1"> - Dance 1 + 跳舞1 </string> <string name="anim_dance2"> - Dance 2 + 跳舞2 </string> <string name="anim_dance3"> - Dance 3 + 跳舞3 </string> <string name="anim_dance4"> - Dance 4 + 跳舞4 </string> <string name="anim_dance5"> - Dance 5 + 跳舞5 </string> <string name="anim_dance6"> - Dance 6 + 跳舞6 </string> <string name="anim_dance7"> - Dance 7 + 跳舞7 </string> <string name="anim_dance8"> - Dance 8 + 跳舞8 </string> <string name="anim_express_disdain"> - Disdain + 鄙視 </string> <string name="anim_drink"> - Drink + 喝一口 </string> <string name="anim_express_embarrased"> - Embarrassed + 尷尬 </string> <string name="anim_angry_fingerwag"> - Finger Wag + 揮動食指 </string> <string name="anim_fist_pump"> - Fist Pump + 高舉右拳 </string> <string name="anim_yoga_float"> - Floating Yoga + 漂浮瑜伽 </string> <string name="anim_express_frown"> - Frown + 皺眉 </string> <string name="anim_impatient"> - Impatient + 不耐煩 </string> <string name="anim_jumpforjoy"> - Jump For Joy + 雀躍 </string> <string name="anim_kissmybutt"> - Kiss My Butt + 親我屁股! </string> <string name="anim_express_kiss"> 親吻 @@ -547,55 +717,55 @@ 笑 </string> <string name="anim_musclebeach"> - Muscle Beach + 秀健美肌肉 </string> <string name="anim_no_unhappy"> 不(不快樂) </string> <string name="anim_no_head"> - 不 + 否 </string> <string name="anim_nyanya"> Nya-nya-nya </string> <string name="anim_punch_onetwo"> - One-Two Punch + 連續左右出拳 </string> <string name="anim_express_open_mouth"> - Open Mouth + 張口 </string> <string name="anim_peace"> - Peace + 和平手勢 </string> <string name="anim_point_you"> - Point at Other + 指著別人 </string> <string name="anim_point_me"> - Point at Self + 指著自己 </string> <string name="anim_punch_l"> - Punch Left + 左出拳 </string> <string name="anim_punch_r"> - Punch Right + 右出拳 </string> <string name="anim_rps_countdown"> - RPS count + 剪刀石頭布預備動作 </string> <string name="anim_rps_paper"> - RPS paper + 剪刀石頭布:布 </string> <string name="anim_rps_rock"> - RPS rock + 剪刀石頭布:石頭 </string> <string name="anim_rps_scissors"> - RPS scissors + 剪刀石頭布:剪刀 </string> <string name="anim_express_repulsed"> - Repulsed + 作噁 </string> <string name="anim_kick_roundhouse_r"> - Roundhouse Kick + 旋踢 </string> <string name="anim_express_sad"> 傷心 @@ -604,37 +774,37 @@ 敬禮 </string> <string name="anim_shout"> - Shout + 吶喊 </string> <string name="anim_express_shrug"> - Shrug + 聳聳肩 </string> <string name="anim_express_smile"> 微笑 </string> <string name="anim_smoke_idle"> - Smoke Idle + 悠閒抽菸 </string> <string name="anim_smoke_inhale"> - Smoke Inhale + 吸一口菸 </string> <string name="anim_smoke_throw_down"> - Smoke Throw Down + 甩菸蒂 </string> <string name="anim_express_surprise"> 驚喜 </string> <string name="anim_sword_strike_r"> - Sword Strike + 劍擊 </string> <string name="anim_angry_tantrum"> - Tantrum + 鬧脾氣 </string> <string name="anim_express_tongue_out"> - TongueOut + 吐舌頭 </string> <string name="anim_hello"> - Wave + 揮手 </string> <string name="anim_whisper"> 耳語 @@ -657,6 +827,9 @@ <string name="anim_yes_head"> 是 </string> + <string name="multiple_textures"> + 多個 + </string> <string name="texture_loading"> 載入中... </string> @@ -664,19 +837,19 @@ 離線 </string> <string name="worldmap_item_tooltip_format"> - [AREA] m² L$[PRICE] + [AREA] 平方公尺 L$[PRICE] </string> <string name="worldmap_results_none_found"> - 沒有發現。 + 查無結果。 </string> <string name="Ok"> 確定 </string> <string name="Premature end of file"> - Premature end of file + 檔案異常中止 </string> <string name="ST_NO_JOINT"> - Can't find ROOT or JOINT. + 找不到 ROOT 或旋軸。 </string> <string name="whisper"> 低語: @@ -700,34 +873,37 @@ 現在你將重新聯接到附近的語音聊天 </string> <string name="ScriptQuestionCautionChatGranted"> - '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS]. + 物件「[OBJECTNAME]'」(所有人「[OWNERNAME]」,位於「[REGIONNAME]」,方位「[REGIONPOS]」)已獲得下列權限:[PERMISSIONS]。 </string> <string name="ScriptQuestionCautionChatDenied"> - '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS]. + 物件「[OBJECTNAME]'」(所有人「[OWNERNAME]」,位於「[REGIONNAME]」,方位「[REGIONPOS]」)已被撤除下列權限:[PERMISSIONS]。 + </string> + <string name="AdditionalPermissionsRequestHeader"> + 你如果打開帳戶權限,也將一併允許該物件: </string> <string name="ScriptTakeMoney"> 由你身上拿走林登幣(L$) </string> <string name="ActOnControlInputs"> - Act on your control inputs + 按你的控制輸入行動 </string> <string name="RemapControlInputs"> - Remap your control inputs + 重新規劃你的控制輸入 </string> <string name="AnimateYourAvatar"> - Animate your avatar + 使化身動起來 </string> <string name="AttachToYourAvatar"> - Attach to your avatar + 附加到化身 </string> <string name="ReleaseOwnership"> - Release ownership and become public + 釋出所有權,開放給所有人 </string> <string name="LinkAndDelink"> - Link and delink from other objects + 連結其他物件或去除連結 </string> <string name="AddAndRemoveJoints"> - Add and remove joints with other objects + 和其他物件建立或移除旋軸 </string> <string name="ChangePermissions"> 變更它的權限 @@ -738,6 +914,9 @@ <string name="ControlYourCamera"> 控制你的攝影機 </string> + <string name="TeleportYourAgent"> + 瞬間傳送你本人 + </string> <string name="NotConnected"> 未聯接 </string> @@ -799,7 +978,7 @@ AVI 視頻檔案 </string> <string name="xaf_animation_file"> - XAF Anim File + XAF 動畫檔案 </string> <string name="xml_file"> XML 檔案 @@ -816,6 +995,12 @@ <string name="choose_the_directory"> 選擇目錄 </string> + <string name="script_files"> + 腳本 + </string> + <string name="dictionary_files"> + 字典 + </string> <string name="AvatarSetNotAway"> 非離開 </string> @@ -991,19 +1176,19 @@ 送出由 </string> <string name="GroupNotifyAttached"> - Attached: + 附件: </string> <string name="GroupNotifyViewPastNotices"> - View past notices or opt-out of receiving these messages here. + 在這裡察看舊通知或選擇不接收訊息。 </string> <string name="GroupNotifyOpenAttachment"> - Open Attachment + 開啟附件 </string> <string name="GroupNotifySaveAttachment"> - Save Attachment + 儲存附件 </string> <string name="TeleportOffer"> - Teleport offering + 發出「瞬間傳送」邀請 </string> <string name="StartUpNotifications"> 當你離開時有新的通知送達。 @@ -1042,16 +1227,75 @@ 按下 ESC 鍵回復到世界的視角 </string> <string name="InventoryNoMatchingItems"> - 沒有發現你想要找的嗎?試試 [secondlife:///app/search/all/[SEARCH_TERM] 搜尋]。 + 找不到你要找的嗎? 請試試 [secondlife:///app/search/places/ 搜尋]。 </string> <string name="PlacesNoMatchingItems"> - 沒有發現你想要找的嗎?試試 [secondlife:///app/search/places/[SEARCH_TERM] 搜尋]。 + 找不到你要找的嗎? 請試試 [secondlife:///app/search/places/[SEARCH_TERM] 搜尋]。 </string> <string name="FavoritesNoMatchingItems"> - Drag a landmark here to add it to your favorites. + 將一個地標拖曳到這裡,加進「我的最愛」。 </string> <string name="InventoryNoTexture"> - You do not have a copy of this texture in your inventory + 你的收納區裡沒有這個材質的副本 + </string> + <string name="InventoryInboxNoItems"> + 你從第二人生購物市集購買的物品將出現在這裡。 你可以把它們拖曳到你的收納區,開始使用。 + </string> + <string name="MarketplaceURL"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ + </string> + <string name="MarketplaceURL_CreateStore"> + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4 + </string> + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard + </string> + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports + </string> + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more + </string> + <string name="InventoryOutboxNotMerchantTitle"> + 任何人都可在第二人生購物市集出售物品。 + </string> + <string name="InventoryOutboxNotMerchantTooltip"/> + <string name="InventoryOutboxNotMerchant"> + 如果你想成為商家,你需要在第二人生購物市集[[MARKETPLACE_CREATE_STORE_URL]開設一間商店]。 + </string> + <string name="InventoryOutboxNoItemsTitle"> + 你的發件匣目前是空的。 + </string> + <string name="InventoryOutboxNoItemsTooltip"/> + <string name="InventoryOutboxNoItems"> + 將資料夾拖曳到這個區域,再點按「送往第二人生購物市集」,即可在[[MARKETPLACE_DASHBOARD_URL]第二人生購物市集]登列出售。 + </string> + <string name="Marketplace Error None"> + 零錯誤 + </string> + <string name="Marketplace Error Not Merchant"> + 發生錯誤:將物項送往第二人生購物市集之前,你必須取得商家的身份(免費)。 + </string> + <string name="Marketplace Error Empty Folder"> + 錯誤:此資料夾沒有內容。 + </string> + <string name="Marketplace Error Unassociated Products"> + 錯誤:此物項上傳失敗,因為你的商家帳戶有太多和產品無關聯的物項。 要解決這個問題,請登入第二人生購物市集網站,減低你的無關聯物項數目。 + </string> + <string name="Marketplace Error Object Limit"> + 錯誤:此物項包含太多物件。 要解決這錯誤,請將物件裝箱,使總物件數目不超過 200。 + </string> + <string name="Marketplace Error Folder Depth"> + 錯誤:此物項含有太多層的巢狀資料夾。 請加以重新整理,至多允許 3 層的巢狀資料夾。 + </string> + <string name="Marketplace Error Unsellable Item"> + 錯誤:此物項無法在第二人生購物市集出售。 + </string> + <string name="Marketplace Error Internal Import"> + 錯誤:這個物項有問題。 請稍候再試一次。 + </string> + <string name="Open landmarks"> + 開啟地標 </string> <string name="no_transfer" value="(禁止轉讓)"/> <string name="no_modify" value="(禁止修改)"/> @@ -1066,7 +1310,7 @@ 無內容 </string> <string name="WornOnAttachmentPoint" value="(已穿 [ATTACHMENT_POINT])"/> - <string name="ActiveGesture" value="[GESLABEL] (active)"/> + <string name="ActiveGesture" value="[GESLABEL](使用中)"/> <string name="PermYes"> 是 </string> @@ -1078,30 +1322,27 @@ <string name="Wait" value="--- 等待:"/> <string name="AnimFlagStop" value="停止動作:"/> <string name="AnimFlagStart" value="開始動作:"/> - <string name="Wave" value="Wave"/> + <string name="Wave" value="揮手"/> <string name="GestureActionNone" value="無"/> - <string name="HelloAvatar" value="Hello, avatar!"/> + <string name="HelloAvatar" value="你好,化身!"/> <string name="ViewAllGestures" value="察看全部 >>"/> <string name="GetMoreGestures" value="取得更多 >>"/> - <string name="Animations" value="動作,"/> - <string name="Calling Cards" value="名片,"/> - <string name="Clothing" value="服裝,"/> - <string name="Gestures" value="姿勢,"/> - <string name="Landmarks" value="地標,"/> - <string name="Notecards" value="記事卡,"/> - <string name="Objects" value="物件,"/> - <string name="Scripts" value="腳本,"/> - <string name="Sounds" value="聲音,"/> - <string name="Textures" value="材質,"/> - <string name="Snapshots" value="快照,"/> - <string name="No Filters" value="No"/> + <string name="Animations" value="動作,"/> + <string name="Calling Cards" value="名片,"/> + <string name="Clothing" value="服裝,"/> + <string name="Gestures" value="姿勢,"/> + <string name="Landmarks" value="地標,"/> + <string name="Notecards" value="記事卡,"/> + <string name="Objects" value="物件,"/> + <string name="Scripts" value="腳本,"/> + <string name="Sounds" value="聲音,"/> + <string name="Textures" value="材質,"/> + <string name="Snapshots" value="快照,"/> + <string name="No Filters" value="否"/> <string name="Since Logoff" value="- 自上次登出"/> <string name="InvFolder My Inventory"> 我的收納區 </string> - <string name="InvFolder My Favorites"> - 我的最愛 - </string> <string name="InvFolder Library"> 資源庫 </string> @@ -1136,7 +1377,7 @@ 收納區 </string> <string name="InvFolder Uncompressed Images"> - Uncompressed Images + 未壓縮圖像 </string> <string name="InvFolder Body Parts"> 身體部位 @@ -1148,10 +1389,10 @@ 相簿 </string> <string name="InvFolder Lost And Found"> - Lost And Found + 失物招領 </string> <string name="InvFolder Uncompressed Sounds"> - 無壓縮聲音 + 未壓縮聲音 </string> <string name="InvFolder Animations"> 動作 @@ -1165,6 +1406,12 @@ <string name="InvFolder favorite"> 我的最愛 </string> + <string name="InvFolder Favorites"> + 我的最愛 + </string> + <string name="InvFolder favorites"> + 我的最愛 + </string> <string name="InvFolder Current Outfit"> 目前裝扮 </string> @@ -1177,17 +1424,32 @@ <string name="InvFolder Accessories"> 配件 </string> + <string name="InvFolder Meshes"> + 網面 + </string> + <string name="InvFolder Received Items"> + 收到的物項 + </string> + <string name="InvFolder Merchant Outbox"> + 商家發件匣 + </string> <string name="InvFolder Friends"> 朋友 </string> <string name="InvFolder All"> 全部 </string> + <string name="no_attachments"> + 未穿著任何附件 + </string> + <string name="Attachments remain"> + 附件(尚可容納 [COUNT] 件) + </string> <string name="Buy"> 購買 </string> <string name="BuyforL$"> - Buy for L$ + 出價購買:L$ </string> <string name="Stone"> 石頭 @@ -1211,13 +1473,13 @@ 橡膠 </string> <string name="Light"> - Light + 光源 </string> <string name="KBShift"> - Shift + Shift 鍵 </string> <string name="KBCtrl"> - Ctrl + Ctrl 鍵 </string> <string name="Chest"> 胸部 @@ -1250,7 +1512,7 @@ 骨盆 </string> <string name="Mouth"> - 嘴 + 嘴巴 </string> <string name="Chin"> 下巴 @@ -1309,23 +1571,29 @@ <string name="Right Pec"> 右胸肌 </string> + <string name="Neck"> + 頸部 + </string> + <string name="Avatar Center"> + 化身中心 + </string> <string name="Invalid Attachment"> - 無效的附件聯接點 + 無效的附接點 </string> <string name="YearsMonthsOld"> - [AGEYEARS] [AGEMONTHS] old + 年齡:[AGEYEARS] 年 [AGEMONTHS] 月 </string> <string name="YearsOld"> - [AGEYEARS] old + 年齡:[AGEYEARS] 年 </string> <string name="MonthsOld"> - [AGEMONTHS] old + [AGEMONTHS] 月 </string> <string name="WeeksOld"> - [AGEWEEKS] old + [AGEWEEKS] 週 </string> <string name="DaysOld"> - [AGEDAYS] old + [AGEDAYS] 天 </string> <string name="TodayOld"> 今日剛加入 @@ -1367,40 +1635,40 @@ [COUNT] 天 </string> <string name="GroupMembersA"> - [COUNT] 成員 + [COUNT] 位成員 </string> <string name="GroupMembersB"> - [COUNT] 成員 + [COUNT] 位成員 </string> <string name="GroupMembersC"> - [COUNT] 成員 + [COUNT] 位成員 </string> <string name="AcctTypeResident"> 居民 </string> <string name="AcctTypeTrial"> - Trial + 試用 </string> <string name="AcctTypeCharterMember"> - Charter Member + 老牌 Charter 成員 </string> <string name="AcctTypeEmployee"> 林登實驗室員工 </string> <string name="PaymentInfoUsed"> - Payment Info Used + 使用的付款資料 </string> <string name="PaymentInfoOnFile"> - Payment Info On File + 預留付款資料 </string> <string name="NoPaymentInfoOnFile"> - No Payment Info On File + 未預留付款資料 </string> <string name="AgeVerified"> - 已年齡驗證 + 通過年齡驗證 </string> <string name="NotAgeVerified"> - 未年齡驗證 + 未通過年齡驗證 </string> <string name="Center 2"> 中央 2 @@ -1427,22 +1695,22 @@ 右下 </string> <string name="CompileQueueDownloadedCompiling"> - 已下載,現在進行編譯中 + 已下載,正在編譯中 </string> <string name="CompileQueueScriptNotFound"> 伺服器上未發現腳本。 </string> <string name="CompileQueueProblemDownloading"> - 問題下載中 + 下載時出問題 </string> <string name="CompileQueueInsufficientPermDownload"> - Insufficient permissions to download a script. + 下載腳本的權限不足。 </string> <string name="CompileQueueInsufficientPermFor"> - Insufficient permissions for + 權限不足: </string> <string name="CompileQueueUnknownFailure"> - Unknown failure to download + 下載失敗,原因不明 </string> <string name="CompileQueueTitle"> 重新編譯進度 @@ -1457,19 +1725,19 @@ 重設 </string> <string name="RunQueueTitle"> - 設定執行中程序 + 設定「執行中」進度 </string> <string name="RunQueueStart"> - 設為執行中 + 設為「執行中」 </string> <string name="NotRunQueueTitle"> - 設定非執行中程序 + 設定「非執行中」進度 </string> <string name="NotRunQueueStart"> - 設為非執行中 + 設為「非執行中」 </string> <string name="CompileSuccessful"> - 編譯成功!! + 編譯成功! </string> <string name="CompileSuccessfulSaving"> 編譯成功,儲存中... @@ -1490,36 +1758,42 @@ <string name="Unknown"> (未知) </string> - <string name="SummaryForTheWeek" value="Summary for this week, beginning on"/> + <string name="SummaryForTheWeek" value="本週摘要,起始日:"/> <string name="NextStipendDay" value="下一個發薪日為"/> - <string name="GroupIndividualShare" value="Group Individual Share"/> + <string name="GroupPlanningDate"> + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + </string> + <string name="GroupIndividualShare" value="群組 個人份額"/> <string name="GroupColumn" value="群組"/> <string name="Balance"> - Balance + 餘額 </string> <string name="Credits"> - Credits + 貸記 </string> <string name="Debits"> - Debits + 借記 </string> <string name="Total"> - Total + 總額 </string> <string name="NoGroupDataFound"> - 無群組資料發現 + 查無群組資料 </string> <string name="IMParentEstate"> - parent estate + 母領地 </string> <string name="IMMainland"> - mainland + 大陸 </string> <string name="IMTeen"> - teen + 青少年 + </string> + <string name="Anyone"> + 任何人 </string> <string name="RegionInfoError"> - error + 錯誤 </string> <string name="RegionInfoAllEstatesOwnedBy"> [OWNER] 所擁有的的全部領地 @@ -1528,13 +1802,13 @@ 你所擁有的全部領地 </string> <string name="RegionInfoAllEstatesYouManage"> - all estates that you manage for [OWNER] + 你為 [OWNER] 管理的全部領地 </string> <string name="RegionInfoAllowedResidents"> - Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS]) + 允許居民:([ALLOWEDAGENTS],最多 [MAXACCESS]) </string> <string name="RegionInfoAllowedGroups"> - 允許的群群組:([ALLOWEDGROUPS],最大 [MAXACCESS]) + 允許的群組:([ALLOWEDGROUPS],最多 [MAXACCESS]) </string> <string name="ScriptLimitsParcelScriptMemory"> 地段腳本記憶體 @@ -1549,28 +1823,28 @@ 記憶體用量:[COUNT] kb </string> <string name="ScriptLimitsParcelScriptURLs"> - 地段腳本 URLs + 地段腳本的 URL </string> <string name="ScriptLimitsURLsUsed"> - URLs used: [COUNT] out of [MAX]; [AVAILABLE] available + URL 使用狀況:最多可用 [MAX],已用 [COUNT],剩餘 [AVAILABLE] </string> <string name="ScriptLimitsURLsUsedSimple"> - URLs used: [COUNT] + 已用 URL:[COUNT] </string> <string name="ScriptLimitsRequestError"> - Error requesting information + 調資料時出錯 </string> <string name="ScriptLimitsRequestNoParcelSelected"> - 無地段被選擇 + 未選擇地段 </string> <string name="ScriptLimitsRequestWrongRegion"> - Error: script information is only available in your current region + 錯誤:只能在你目前所處區域取得腳本資訊 </string> <string name="ScriptLimitsRequestWaiting"> - Retrieving information... + 正在調閱資料... </string> <string name="ScriptLimitsRequestDontOwnParcel"> - You do not have permission to examine this parcel + 你無權審視此地段 </string> <string name="SITTING_ON"> 坐在 @@ -1666,34 +1940,34 @@ 左胸肌 </string> <string name="ATTACH_HUD_CENTER_2"> - HUD Center 2 + 擡頭顯示中央 2 </string> <string name="ATTACH_HUD_TOP_RIGHT"> - HUD Top Right + 擡頭顯示右上 </string> <string name="ATTACH_HUD_TOP_CENTER"> - HUD Top Center + 擡頭顯示中央上方 </string> <string name="ATTACH_HUD_TOP_LEFT"> - HUD Top Left + 擡頭顯示左上 </string> <string name="ATTACH_HUD_CENTER_1"> - HUD Center 1 + 擡頭顯示中央 1 </string> <string name="ATTACH_HUD_BOTTOM_LEFT"> - HUD Bottom Left + 擡頭顯示左下 </string> <string name="ATTACH_HUD_BOTTOM"> - HUD Bottom + 擡頭顯示下方 </string> <string name="ATTACH_HUD_BOTTOM_RIGHT"> - HUD Bottom Right + 擡頭顯示右下 </string> <string name="CursorPos"> - Line [LINE], Column [COLUMN] + 橫行 [LINE],縱列 [COLUMN] </string> <string name="PanelDirCountFound"> - [COUNT] found + 找到 [COUNT] </string> <string name="PanelDirTimeStr"> [hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt] @@ -1702,16 +1976,16 @@ [mthnum,datetime,slt]/[day,datetime,slt] </string> <string name="PanelContentsTooltip"> - 物件的內容 + 物件內容 </string> <string name="PanelContentsNewScript"> 新腳本 </string> <string name="BusyModeResponseDefault"> - 你傳送訊息的居民目前處於忙碌模式中,這意味著他要求不被打擾。你所傳的訊息仍將會留存並顯示於 IM 面板上供他稍後時查閱。 + 你傳訊過去的居民目前處於忙碌狀態,這意味著他要求不被打擾。 你的訊息仍將留存並顯示於對���的 IM 面板上供稍後查閱。 </string> <string name="MuteByName"> - (由名稱) + (按名稱) </string> <string name="MuteAgent"> (居民) @@ -1726,12 +2000,12 @@ (外部) </string> <string name="RegionNoCovenant"> - 此領地未提供任何契約要求。 + 此領地沒有任何契約要求。 </string> <string name="RegionNoCovenantOtherOwner"> - There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details. + 此領地沒有任何契約要求。 本領地土地的出售人是領地所有人,不是林登實驗室。 請聯絡領地所有人獲知售地詳情。 </string> - <string name="covenant_last_modified" value="最後修改於:"/> + <string name="covenant_last_modified" value="最後修改時間:"/> <string name="none_text" value="(無)"/> <string name="never_text" value="(絕不)"/> <string name="GroupOwned"> @@ -1740,14 +2014,20 @@ <string name="Public"> 公開 </string> + <string name="LocalSettings"> + 本地設定 + </string> + <string name="RegionSettings"> + 地區設定 + </string> <string name="ClassifiedClicksTxt"> - Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile + 點按:[TELEPORT] 瞬間傳送,[MAP] 地圖,[PROFILE] 檔案 </string> <string name="ClassifiedUpdateAfterPublish"> - (將於發布後自動更新) + (將於發布後更新) </string> <string name="NoPicksClassifiedsText"> - You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified. + 你尚未建立任何精選地點或個人廣告。 點按下面的 + 按鈕建立精選地點或個人廣告。 </string> <string name="NoAvatarPicksClassifiedsText"> 使用者無精選地點或個人廣告 @@ -1762,86 +2042,89 @@ 屬性 </string> <string name="InvOfferAnObjectNamed"> - An object named + 一個物件,名為 </string> <string name="InvOfferOwnedByGroup"> - 群組所擁有 + 屬於群組 </string> <string name="InvOfferOwnedByUnknownGroup"> - 由一個未知的群組所擁有 + 屬於一個未知群組 </string> <string name="InvOfferOwnedBy"> - owned by + 所有人: </string> <string name="InvOfferOwnedByUnknownUser"> - owned by an unknown user + 屬於某未知使用者 </string> <string name="InvOfferGaveYou"> - gave you + 給予你 </string> <string name="InvOfferDecline"> - You decline [DESC] from <nolink>[NAME]</nolink>. + 你拒絕了來自 <nolink>[NAME]</nolink> 的 [DESC]。 </string> <string name="GroupMoneyTotal"> - Total + 總額 </string> <string name="GroupMoneyBought"> - bought + 買了 </string> <string name="GroupMoneyPaidYou"> - paid you + 支付給你 </string> <string name="GroupMoneyPaidInto"> - paid into + 支付給 </string> <string name="GroupMoneyBoughtPassTo"> - bought pass to + 買了通行權: </string> <string name="GroupMoneyPaidFeeForEvent"> - paid fee for event + 付了費用參加活動 </string> <string name="GroupMoneyPaidPrizeForEvent"> - paid prize for event + 付了賞金參加活動 </string> <string name="GroupMoneyBalance"> - Balance + 餘額 </string> <string name="GroupMoneyCredits"> - Credits + 貸記 </string> <string name="GroupMoneyDebits"> - Debits + 借記 + </string> + <string name="GroupMoneyDate"> + [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc] </string> <string name="ViewerObjectContents"> - Contents + 內容 </string> <string name="AcquiredItems"> - Acquired Items + 取得物品 </string> <string name="Cancel"> 取消 </string> <string name="UploadingCosts"> - 花費 L$ [AMOUNT] 上傳 [NAME] + 上傳 [NAME] 費用 L$ [AMOUNT] </string> <string name="BuyingCosts"> - 花費 L$ [AMOUNT] 購買這個 + 購買這個需要 L$ [AMOUNT] </string> <string name="UnknownFileExtension"> 未知的副檔名 .%s -預期為 .wav, .tga, .bmp, .jpg, .jpeg, or .bvh 類型 +應該是 .wav、.tga、.bmp、.jpg、.jpeg 或 .bvh </string> <string name="MuteObject2"> - Block + 封鎖 </string> <string name="MuteAvatar"> - Block + 封鎖 </string> <string name="UnmuteObject"> - Unblock + 解除封鎖 </string> <string name="UnmuteAvatar"> - Unblock + 解除封鎖 </string> <string name="AddLandmarkNavBarMenu"> 添加到我的地標... @@ -1877,25 +2160,25 @@ 接收中 </string> <string name="AM"> - AM + 上午 </string> <string name="PM"> - PM + 下午 </string> <string name="PST"> - PST + 太平洋時間 </string> <string name="PDT"> - PDT + 太平洋日光節約時間 </string> <string name="Direction_Forward"> 向前 </string> <string name="Direction_Left"> - 向左 + 左移鍵 </string> <string name="Direction_Right"> - 向右 + 右移鍵 </string> <string name="Direction_Back"> 向後 @@ -1913,46 +2196,46 @@ 東 </string> <string name="Direction_Up"> - 向上 + 上移鍵 </string> <string name="Direction_Down"> - 向下 + 下移鍵 </string> <string name="Any Category"> 任何類別 </string> <string name="Shopping"> - 採購 + 購物 </string> <string name="Land Rental"> - Land Rental + 土地租賃 </string> <string name="Property Rental"> - Property Rental + 房產租賃 </string> <string name="Special Attraction"> - Special Attraction + 熱門地點 </string> <string name="New Products"> - New Products + 新產品 </string> <string name="Employment"> - Employment + 徵人 </string> <string name="Wanted"> - Wanted + 徵求 </string> <string name="Service"> - Service + 服務 </string> <string name="Personal"> - Personal + 交友 </string> <string name="None"> 無 </string> <string name="Linden Location"> - Linden Location + 林登位置 </string> <string name="Adult"> 完全成人 @@ -1973,25 +2256,25 @@ 聚會所 </string> <string name="Newcomer Friendly"> - 新手友善 + 歡迎新手光臨 </string> <string name="Parks&Nature"> - 公園與自然 + 公園與自然景觀 </string> <string name="Residential"> 住宅 </string> <string name="Stage"> - Stage + 舞臺 </string> <string name="Other"> - Other + 其他 </string> <string name="Rental"> - Rental + 出租 </string> <string name="Any"> - Any + 任何 </string> <string name="You"> 你 @@ -2027,7 +2310,7 @@ 多媒體 </string> <string name="Play Media"> - 播放/暫停 媒體 + 播放/暫停媒體 </string> <string name="MBCmdLineError"> 解析命令列時發現錯誤。 @@ -2038,1510 +2321,1510 @@ [APP_NAME] 命令列用法: </string> <string name="MBUnableToAccessFile"> - [APP_NAME] 無法存取它所需要的檔案。 + [APP_NAME] 無法存取它所需的檔案。 -This can be because you somehow have multiple copies running, or your system incorrectly thinks a file is open. -If this message persists, restart your computer and try again. -If it continues to persist, you may need to completely uninstall [APP_NAME] and reinstall it. +你可能有多重實例執行中,或你的系統誤以為某檔案已經開啟。 +如果這個訊息持續出現,請重新啟動你的電腦。 +如果問題仍然存在,你可能需要徹底卸除 [APP_NAME] 再重新安裝。 </string> <string name="MBFatalError"> 致命錯誤 </string> <string name="MBRequiresAltiVec"> - [APP_NAME] requires a processor with AltiVec (G4 or later). + [APP_NAME] 需要有 AltiVec(G4 或更新版)的處理器。 </string> <string name="MBAlreadyRunning"> [APP_NAME] 已經在執行中。 -請檢查你的工作列裡是否有其他最小化的相同程式。 +請檢查你的工作列裡是否已有最小化的相同程式。 如果這個訊息持續出現,請重新啟動你的電腦。 </string> <string name="MBFrozenCrashed"> - [APP_NAME] appears to have frozen or crashed on the previous run. -Would you like to send a crash report? + [APP_NAME] 上次執行時好像出現凍結或當掉。 +你是否想要報告當機事例? </string> <string name="MBAlert"> 通知 </string> <string name="MBNoDirectX"> - [APP_NAME] is unable to detect DirectX 9.0b or greater. -[APP_NAME] uses DirectX to detect hardware and/or outdated drivers that can cause stability problems, poor performance and crashes. While you can run [APP_NAME] without it, we highly recommend running with DirectX 9.0b. + [APP_NAME] 偵測不到 DirectX 9.0b 或更新版。 +[APP_NAME] 使用 DirectX 來偵測可能導致不穩定、執行效能不佳或當機發生的硬體或老舊驅動器。 你可以選擇不用 DirectX 9.0b 來執行 [APP_NAME],但我們大力推薦你使用。 -Do you wish to continue? +你確定要繼續嗎? </string> <string name="MBWarning"> 警告 </string> <string name="MBNoAutoUpdate"> - Automatic updating is not yet implemented for Linux. -Please download the latest version from www.secondlife.com. + 尚無試用於 Linux 的自動更新功能。 +請到 www.secondlife.com 下載最新版本。 </string> <string name="MBRegClassFailed"> - RegisterClass failed + RegisterClass 失敗 </string> <string name="MBError"> 錯誤 </string> <string name="MBFullScreenErr"> - 無法執行全螢幕於 [WIDTH] x [HEIGHT]. -執行於視窗中。 + [WIDTH] x [HEIGHT] 解析度下無法執行全螢幕。 +在視窗中執行。 </string> <string name="MBDestroyWinFailed"> - Shutdown Error while destroying window (DestroyWindow() failed) + 消滅視窗時發生強行關閉錯誤(DestroyWindow()失敗) </string> <string name="MBShutdownErr"> - Shutdown Error + 強行關閉出錯 </string> <string name="MBDevContextErr"> - Can't make GL device context + 無法建立 GL 裝置環境 </string> <string name="MBPixelFmtErr"> - Can't find suitable pixel format + 找不到適合的像素格式 </string> <string name="MBPixelFmtDescErr"> - Can't get pixel format description + 無法取得像素格式描述 </string> <string name="MBTrueColorWindow"> - [APP_NAME] requires True Color (32-bit) to run. -Please go to your computer's display settings and set the color mode to 32-bit. + [APP_NAME] 需要全彩(32位元)才能執行。 +請到電腦的顯示設定,將色彩模式設為 32 位元。 </string> <string name="MBAlpha"> - [APP_NAME] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues. -Please make sure you have the latest video card drivers installed. -Also be sure your monitor is set to True Color (32-bit) in Control Panels > Display > Settings. -If you continue to receive this message, contact the [SUPPORT_SITE]. + [APP_NAME] 無法執行,無法取得 8 位元 alpha 頻道。 這通常是因為顯示卡驅動程式出問題。 +請確定你安裝了最新的顯示卡驅動程式。 +請到控制台 > 顯示 > 設定處將螢幕設為全彩(32 位元)。 +如果你繼續看到此訊息,請聯絡 [SUPPORT_SITE]。 </string> <string name="MBPixelFmtSetErr"> 無法設定像素格式 </string> <string name="MBGLContextErr"> - Can't create GL rendering context + 無法建立 GL 呈像環境 </string> <string name="MBGLContextActErr"> - Can't activate GL rendering context + 無法啟動 GL 呈像環境 </string> <string name="MBVideoDrvErr"> - [APP_NAME] is unable to run because your video card drivers did not install properly, are out of date, or are for unsupported hardware. Please make sure you have the latest video card drivers and even if you do have the latest, try reinstalling them. + [APP_NAME] 無法執行,這可能因為你的顯示卡驅動程式安裝不當、版本過舊,或者你的硬體不受支援。 請確定你安裝了最新的顯示卡驅動程式。如果已裝了最新驅動程式,請再重新安裝。 -If you continue to receive this message, contact the [SUPPORT_SITE]. +如果你繼續看到此訊息,請聯絡 [SUPPORT_SITE]。 </string> <string name="5 O'Clock Shadow"> - 5 O'Clock Shadow + 下午五點的新鬍渣 </string> <string name="All White"> 全白 </string> <string name="Anime Eyes"> - Anime Eyes + 日式動漫眼 </string> <string name="Arced"> - Arced + 彎拱的 </string> <string name="Arm Length"> - Arm Length + 臂長 </string> <string name="Attached"> - Attached + 貼附的 </string> <string name="Attached Earlobes"> - Attached Earlobes + 附著耳垂 </string> <string name="Back Fringe"> - Back Fringe + 後瀏海 </string> <string name="Baggy"> - Baggy + 袋型的 </string> <string name="Bangs"> - Bangs + 瀏海 </string> <string name="Beady Eyes"> - Beady Eyes + 珠圓銳光眼 </string> <string name="Belly Size"> - Belly Size + 腹部大小 </string> <string name="Big"> - Big + 大 </string> <string name="Big Butt"> - Big Butt + 大臀部 </string> <string name="Big Hair Back"> - Big Hair: Back + 大型頭髮:後面 </string> <string name="Big Hair Front"> - Big Hair: Front + 大型頭髮:前面 </string> <string name="Big Hair Top"> - Big Hair: Top + 大型頭髮:頂部 </string> <string name="Big Head"> - Big Head + 大頭 </string> <string name="Big Pectorals"> - Big Pectorals + 大胸肌 </string> <string name="Big Spikes"> - Big Spikes + 大尖直髮 </string> <string name="Black"> - Black + 黑色 </string> <string name="Blonde"> - Blonde + 金色 </string> <string name="Blonde Hair"> - Blonde Hair + 金髮 </string> <string name="Blush"> - Blush + 腮紅 </string> <string name="Blush Color"> - Blush Color + 淺粉色 </string> <string name="Blush Opacity"> - Blush Opacity + 腮紅不透明度: </string> <string name="Body Definition"> - Body Definition + 身體結實度 </string> <string name="Body Fat"> - Body Fat + 體脂肪 </string> <string name="Body Freckles"> - Body Freckles + 身體雀斑 </string> <string name="Body Thick"> - Body Thick + 寬厚體型 </string> <string name="Body Thickness"> - Body Thickness + 體型厚度 </string> <string name="Body Thin"> - Body Thin + 窄瘦體型 </string> <string name="Bow Legged"> - Bow Legged + 弓形腿 </string> <string name="Breast Buoyancy"> - Breast Buoyancy + 乳房彈性 </string> <string name="Breast Cleavage"> - Breast Cleavage + 乳溝深淺 </string> <string name="Breast Size"> - Breast Size + 乳房尺寸 </string> <string name="Bridge Width"> - Bridge Width + 兩眼間距 </string> <string name="Broad"> - Broad + 寬 </string> <string name="Brow Size"> - Brow Size + 眉毛大小 </string> <string name="Bug Eyes"> - Bug Eyes + 突眼 </string> <string name="Bugged Eyes"> - Bugged Eyes + 突眼 </string> <string name="Bulbous"> - Bulbous + 球狀 </string> <string name="Bulbous Nose"> - Bulbous Nose + 球狀鼻 </string> <string name="Breast Physics Mass"> - Breast Mass + 乳房質量 </string> <string name="Breast Physics Smoothing"> - Breast Smoothing + 乳房增圓滑 </string> <string name="Breast Physics Gravity"> - Breast Gravity + 乳房重力特性 </string> <string name="Breast Physics Drag"> - Breast Drag + 乳房阻力 </string> <string name="Breast Physics InOut Max Effect"> - Max Effect + 最大效果 </string> <string name="Breast Physics InOut Spring"> - Spring + 彈跳 </string> <string name="Breast Physics InOut Gain"> - Gain + 增益 </string> <string name="Breast Physics InOut Damping"> - Damping + 阻尼 </string> <string name="Breast Physics UpDown Max Effect"> - Max Effect + 最大效果 </string> <string name="Breast Physics UpDown Spring"> - Spring + 彈跳 </string> <string name="Breast Physics UpDown Gain"> - Gain + 增益 </string> <string name="Breast Physics UpDown Damping"> - Damping + 阻尼 </string> <string name="Breast Physics LeftRight Max Effect"> - Max Effect + 最大效果 </string> <string name="Breast Physics LeftRight Spring"> - Spring + 彈跳 </string> <string name="Breast Physics LeftRight Gain"> - Gain + 增益 </string> <string name="Breast Physics LeftRight Damping"> - Damping + 阻尼 </string> <string name="Belly Physics Mass"> - Belly Mass + 腹部質量 </string> <string name="Belly Physics Smoothing"> - Belly Smoothing + 腹部增圓滑 </string> <string name="Belly Physics Gravity"> - Belly Gravity + 腹部重力特性 </string> <string name="Belly Physics Drag"> - Belly Drag + 腹部阻力 </string> <string name="Belly Physics UpDown Max Effect"> - Max Effect + 最大效果 </string> <string name="Belly Physics UpDown Spring"> - Spring + 彈跳 </string> <string name="Belly Physics UpDown Gain"> - Gain + 增益 </string> <string name="Belly Physics UpDown Damping"> - Damping + 阻尼 </string> <string name="Butt Physics Mass"> - Butt Mass + 臀部質量 </string> <string name="Butt Physics Smoothing"> - Butt Smoothing + 臀部增圓滑 </string> <string name="Butt Physics Gravity"> - Butt Gravity + 臀部重力特性 </string> <string name="Butt Physics Drag"> - Butt Drag + 臀部阻力 </string> <string name="Butt Physics UpDown Max Effect"> - Max Effect + 最大效果 </string> <string name="Butt Physics UpDown Spring"> - Spring + 彈跳 </string> <string name="Butt Physics UpDown Gain"> - Gain + 增益 </string> <string name="Butt Physics UpDown Damping"> - Damping + 阻尼 </string> <string name="Butt Physics LeftRight Max Effect"> - Max Effect + 最大效果 </string> <string name="Butt Physics LeftRight Spring"> - Spring + 彈跳 </string> <string name="Butt Physics LeftRight Gain"> - Gain + 增益 </string> <string name="Butt Physics LeftRight Damping"> - Damping + 阻尼 </string> <string name="Bushy Eyebrows"> - Bushy Eyebrows + 濃眉 </string> <string name="Bushy Hair"> - Bushy Hair + 濃密頭髮 </string> <string name="Butt Size"> - Butt Size + 臀部大小 </string> <string name="Butt Gravity"> - Butt Gravity + 臀部重力特性 </string> <string name="bustle skirt"> - Bustle Skirt + 側皺過膝長裙 </string> <string name="no bustle"> - No Bustle + 無側皺 </string> <string name="more bustle"> - More Bustle + 增加側皺 </string> <string name="Chaplin"> Chaplin </string> <string name="Cheek Bones"> - Cheek Bones + 顴骨 </string> <string name="Chest Size"> - Chest Size + 胸部大小 </string> <string name="Chin Angle"> 下巴角度 </string> <string name="Chin Cleft"> - Chin Cleft + 下巴裂度 </string> <string name="Chin Curtains"> - Chin Curtains + 絡腮鬍 </string> <string name="Chin Depth"> - Chin Depth + 下巴深度 </string> <string name="Chin Heavy"> - Chin Heavy + 下巴厚重 </string> <string name="Chin In"> - Chin In + 下巴後縮 </string> <string name="Chin Out"> - Chin Out + 下巴突出 </string> <string name="Chin-Neck"> - Chin-Neck + 下巴-頸部 </string> <string name="Clear"> 清除 </string> <string name="Cleft"> - Cleft + 分裂 </string> <string name="Close Set Eyes"> - Close Set Eyes + 雙眼靠近 </string> <string name="Closed"> - Closed + 閉合 </string> <string name="Closed Back"> - Closed Back + 後閉合 </string> <string name="Closed Front"> - Closed Front + 前閉合 </string> <string name="Closed Left"> - Closed Left + 左閉合 </string> <string name="Closed Right"> - Closed Right + 右閉合 </string> <string name="Coin Purse"> - Coin Purse + 小錢包 </string> <string name="Collar Back"> - Collar Back + 後 Collar </string> <string name="Collar Front"> - Collar Front + 前 Collar </string> <string name="Corner Down"> - Corner Down + 角落朝下 </string> <string name="Corner Up"> - Corner Up + 角落朝上 </string> <string name="Creased"> - Creased + 皺褶 </string> <string name="Crooked Nose"> - Crooked Nose + 彎曲鼻 </string> <string name="Cuff Flare"> - Cuff Flare + 袖口裝飾 </string> <string name="Dark"> - Dark + 深暗 </string> <string name="Dark Green"> - Dark Green + 深綠 </string> <string name="Darker"> - Darker + 更深暗 </string> <string name="Deep"> - Deep + 深 </string> <string name="Default Heels"> - Default Heels + 預設高跟鞋 </string> <string name="Dense"> - Dense + 稠密 </string> <string name="Double Chin"> - Double Chin + 雙下巴 </string> <string name="Downturned"> - Downturned + 嘴角下垂 </string> <string name="Duffle Bag"> - Duffle Bag + 旅行袋 </string> <string name="Ear Angle"> - Ear Angle + 耳朵角度 </string> <string name="Ear Size"> - Ear Size + 耳朵大小 </string> <string name="Ear Tips"> - Ear Tips + 耳端 </string> <string name="Egg Head"> - Egg Head + 蛋形頭 </string> <string name="Eye Bags"> - Eye Bags + 眼袋 </string> <string name="Eye Color"> - Eye Color + 眼睛顏色 </string> <string name="Eye Depth"> - Eye Depth + 眼睛深度 </string> <string name="Eye Lightness"> - Eye Lightness + 眼睛亮度 </string> <string name="Eye Opening"> - Eye Opening + 眼睛垂直大小 </string> <string name="Eye Pop"> - Eye Pop + 眼睛 Pop </string> <string name="Eye Size"> - Eye Size + 眼睛大小 </string> <string name="Eye Spacing"> - Eye Spacing + 雙眼間距 </string> <string name="Eyebrow Arc"> - Eyebrow Arc + 眉毛弧度 </string> <string name="Eyebrow Density"> - Eyebrow Density + 眉毛密度 </string> <string name="Eyebrow Height"> - Eyebrow Height + 眉毛高度 </string> <string name="Eyebrow Points"> - Eyebrow Points + 眉毛點 </string> <string name="Eyebrow Size"> - Eyebrow Size + 眉毛尺寸 </string> <string name="Eyelash Length"> - Eyelash Length + 睫毛長度 </string> <string name="Eyeliner"> - Eyeliner + 眼線筆 </string> <string name="Eyeliner Color"> - Eyeliner Color + 眼影筆顏色 </string> <string name="Eyes Bugged"> - Eyes Bugged + 突眼 </string> <string name="Face Shear"> - Face Shear + 臉部偏移 </string> <string name="Facial Definition"> - Facial Definition + 臉部結實度 </string> <string name="Far Set Eyes"> - Far Set Eyes + 雙眼距離遠 </string> <string name="Fat Lips"> - Fat Lips + 厚脣 </string> <string name="Female"> - Female + 女性 </string> <string name="Fingerless"> - Fingerless + 無手指 </string> <string name="Fingers"> - Fingers + 手指 </string> <string name="Flared Cuffs"> - Flared Cuffs + 帶裝飾袖口 </string> <string name="Flat"> - Flat + 平 </string> <string name="Flat Butt"> - Flat Butt + 臀部扁平 </string> <string name="Flat Head"> - Flat Head + 頭部扁平 </string> <string name="Flat Toe"> - Flat Toe + 腳趾扁平 </string> <string name="Foot Size"> - Foot Size + 腳部大小 </string> <string name="Forehead Angle"> - Forehead Angle + 前額角度 </string> <string name="Forehead Heavy"> - Forehead Heavy + 前額寬厚 </string> <string name="Freckles"> - Freckles + 雀斑 </string> <string name="Front Fringe"> - Front Fringe + 前瀏海 </string> <string name="Full Back"> - Full Back + 後部飽滿 </string> <string name="Full Eyeliner"> - Full Eyeliner + 厚重眼線 </string> <string name="Full Front"> - Full Front + 前面飽滿 </string> <string name="Full Hair Sides"> - Full Hair Sides + 側髮飽滿 </string> <string name="Full Sides"> - Full Sides + 兩側飽滿 </string> <string name="Glossy"> - Glossy + 光亮 </string> <string name="Glove Fingers"> - Glove Fingers + 手套手指 </string> <string name="Glove Length"> - Glove Length + 手套長度 </string> <string name="Hair"> 頭髮 </string> <string name="Hair Back"> - Hair: Back + 頭髮:後面 </string> <string name="Hair Front"> - Hair: Front + 頭髮:前面 </string> <string name="Hair Sides"> - Hair: Sides + 頭髮:側面 </string> <string name="Hair Sweep"> - Hair Sweep + 頭髮垂擺 </string> <string name="Hair Thickess"> - Hair Thickness + 頭髮厚度 </string> <string name="Hair Thickness"> - Hair Thickness + 頭髮厚度 </string> <string name="Hair Tilt"> - Hair Tilt + 頭髮傾度 </string> <string name="Hair Tilted Left"> - Hair Tilted Left + 頭髮傾左 </string> <string name="Hair Tilted Right"> - Hair Tilted Right + 頭髮傾右 </string> <string name="Hair Volume"> - Hair: Volume + 頭髮:髮量 </string> <string name="Hand Size"> - Hand Size + 手部大小 </string> <string name="Handlebars"> - Handlebars + 把手 </string> <string name="Head Length"> - Head Length + 頭部長度 </string> <string name="Head Shape"> - Head Shape + 頭型 </string> <string name="Head Size"> - Head Size + 頭部大小 </string> <string name="Head Stretch"> - Head Stretch + 頭部延展度 </string> <string name="Heel Height"> - Heel Height + 腳踵高度 </string> <string name="Heel Shape"> - Heel Shape + 腳踵形狀 </string> <string name="Height"> - Height + 高度 </string> <string name="High"> - High + 高 </string> <string name="High Heels"> - High Heels + 高跟鞋 </string> <string name="High Jaw"> - High Jaw + 高顎 </string> <string name="High Platforms"> - High Platforms + 高平臺 </string> <string name="High and Tight"> - High and Tight + 高而緊緻 </string> <string name="Higher"> - Higher + 更高 </string> <string name="Hip Length"> - Hip Length + 腰長 </string> <string name="Hip Width"> - Hip Width + 腰寬 </string> <string name="In"> - In + 向內 </string> <string name="In Shdw Color"> - Inner Shadow Color + 內陰影顏色 </string> <string name="In Shdw Opacity"> - Inner Shadow Opacity + 內陰影不透明度 </string> <string name="Inner Eye Corner"> - Inner Eye Corner + 眼內角 </string> <string name="Inner Eye Shadow"> - Inner Eye Shadow + 內眼陰影 </string> <string name="Inner Shadow"> - Inner Shadow + 內陰影 </string> <string name="Jacket Length"> - Jacket Length + 外套長度 </string> <string name="Jacket Wrinkles"> - Jacket Wrinkles + 外套皺褶 </string> <string name="Jaw Angle"> - Jaw Angle + 顎角度 </string> <string name="Jaw Jut"> - Jaw Jut + 顎突出 </string> <string name="Jaw Shape"> - Jaw Shape + 顎形 </string> <string name="Join"> - Join + 加入 </string> <string name="Jowls"> - Jowls + 下頜 </string> <string name="Knee Angle"> - Knee Angle + 膝部角度 </string> <string name="Knock Kneed"> - Knock Kneed + 八字腿 </string> <string name="Large"> - Large + 大 </string> <string name="Large Hands"> - Large Hands + 大手掌 </string> <string name="Left Part"> - Left Part + 左邊分 </string> <string name="Leg Length"> - Leg Length + 腿長 </string> <string name="Leg Muscles"> - Leg Muscles + 腿肌肉 </string> <string name="Less"> - Less + 更少 </string> <string name="Less Body Fat"> - Less Body Fat + 體脂肪較少 </string> <string name="Less Curtains"> - Less Curtains + 絡腮鬍較短 </string> <string name="Less Freckles"> - Less Freckles + 雀斑較少 </string> <string name="Less Full"> - Less Full + 較不飽滿 </string> <string name="Less Gravity"> - Less Gravity + 較少重力 </string> <string name="Less Love"> - Less Love + 少一點愛 </string> <string name="Less Muscles"> - Less Muscles + 少一點肌肉 </string> <string name="Less Muscular"> - Less Muscular + 少一點肌壯感 </string> <string name="Less Rosy"> - Less Rosy + 少一點紅潤 </string> <string name="Less Round"> - Less Round + 少一點圓度 </string> <string name="Less Saddle"> - Less Saddle + 腿靠攏一點 </string> <string name="Less Square"> - Less Square + 少一點方形 </string> <string name="Less Volume"> - Less Volume + 少一點量 </string> <string name="Less soul"> - Less soul + 少一點靈魂 </string> <string name="Lighter"> - Lighter + 亮一點 </string> <string name="Lip Cleft"> - Lip Cleft + 脣裂度 </string> <string name="Lip Cleft Depth"> - Lip Cleft Depth + 脣裂深度 </string> <string name="Lip Fullness"> - Lip Fullness + 脣豐度 </string> <string name="Lip Pinkness"> - Lip Pinkness + 脣色粉紅度 </string> <string name="Lip Ratio"> - Lip Ratio + 脣比率 </string> <string name="Lip Thickness"> - Lip Thickness + 脣厚度 </string> <string name="Lip Width"> - Lip Width + 脣寬度 </string> <string name="Lipgloss"> - Lipgloss + 脣蜜 </string> <string name="Lipstick"> - Lipstick + 脣膏 </string> <string name="Lipstick Color"> - Lipstick Color + 脣膏顏色 </string> <string name="Long"> - Long + 長 </string> <string name="Long Head"> - Long Head + 長臉 </string> <string name="Long Hips"> - Long Hips + 高腰 </string> <string name="Long Legs"> - Long Legs + 長腿 </string> <string name="Long Neck"> - Long Neck + 長頸 </string> <string name="Long Pigtails"> - Long Pigtails + 長辮子 </string> <string name="Long Ponytail"> - Long Ponytail + 長馬尾辮 </string> <string name="Long Torso"> - Long Torso + 長軀幹 </string> <string name="Long arms"> - Long arms + 長臂 </string> <string name="Loose Pants"> - Loose Pants + 寬鬆褲子 </string> <string name="Loose Shirt"> - Loose Shirt + 寬鬆襯衫 </string> <string name="Loose Sleeves"> - Loose Sleeves + 寬鬆袖子 </string> <string name="Love Handles"> - Love Handles + 腰間贅肉 </string> <string name="Low"> - Low + 低 </string> <string name="Low Heels"> - Low Heels + 低跟鞋 </string> <string name="Low Jaw"> - Low Jaw + 低顎 </string> <string name="Low Platforms"> - Low Platforms + 低平臺 </string> <string name="Low and Loose"> - Low and Loose + 低而寬鬆 </string> <string name="Lower"> - Lower + 降低 </string> <string name="Lower Bridge"> - Lower Bridge + 鼻樑低一點 </string> <string name="Lower Cheeks"> - Lower Cheeks + 雙頰低一點 </string> <string name="Male"> 男性 </string> <string name="Middle Part"> - Middle Part + 中間邊分 </string> <string name="More"> 更多 </string> <string name="More Blush"> - More Blush + 增加腮紅 </string> <string name="More Body Fat"> - More Body Fat + 增加體脂肪 </string> <string name="More Curtains"> - More Curtains + 增加絡腮鬍 </string> <string name="More Eyeshadow"> - More Eyeshadow + 增加眼影 </string> <string name="More Freckles"> - More Freckles + 增加雀斑 </string> <string name="More Full"> - More Full + 更飽滿 </string> <string name="More Gravity"> - More Gravity + 增加重力 </string> <string name="More Lipstick"> - More Lipstick + 多一點脣膏 </string> <string name="More Love"> - More Love + 多一點愛 </string> <string name="More Lower Lip"> - More Lower Lip + 下脣更豐滿 </string> <string name="More Muscles"> - More Muscles + 多一點肌肉 </string> <string name="More Muscular"> - More Muscular + 增加肌壯感 </string> <string name="More Rosy"> - More Rosy + 更加紅潤 </string> <string name="More Round"> - More Round + 增加圓度 </string> <string name="More Saddle"> - More Saddle + 腿更加張開 </string> <string name="More Sloped"> - More Sloped + 更加傾斜 </string> <string name="More Square"> - More Square + 增加方形 </string> <string name="More Upper Lip"> - More Upper Lip + 上脣更豐滿 </string> <string name="More Vertical"> - More Vertical + 更加垂直 </string> <string name="More Volume"> - More Volume + 多一點量 </string> <string name="More soul"> - More soul + 多一點靈魂 </string> <string name="Moustache"> - Moustache + 髭鬍 </string> <string name="Mouth Corner"> - Mouth Corner + 嘴角 </string> <string name="Mouth Position"> - Mouth Position + 嘴巴位置 </string> <string name="Mowhawk"> - Mowhawk + 莫霍克髮型 </string> <string name="Muscular"> - Muscular + 肌肉發達 </string> <string name="Mutton Chops"> - Mutton Chops + 羊排式絡腮鬍 </string> <string name="Nail Polish"> - Nail Polish + 指甲油 </string> <string name="Nail Polish Color"> - Nail Polish Color + 指甲油顏色 </string> <string name="Narrow"> - Narrow + 窄 </string> <string name="Narrow Back"> - Narrow Back + 後窄 </string> <string name="Narrow Front"> - Narrow Front + 前窄 </string> <string name="Narrow Lips"> - Narrow Lips + 窄脣 </string> <string name="Natural"> - Natural + 自然 </string> <string name="Neck Length"> - Neck Length + 頸長 </string> <string name="Neck Thickness"> - Neck Thickness + 頸部厚度 </string> <string name="No Blush"> - No Blush + 無腮紅 </string> <string name="No Eyeliner"> - No Eyeliner + 無眼線 </string> <string name="No Eyeshadow"> - No Eyeshadow + 無眼影 </string> <string name="No Lipgloss"> - No Lipgloss + 無脣蜜 </string> <string name="No Lipstick"> - No Lipstick + 無脣膏 </string> <string name="No Part"> - No Part + 無邊分 </string> <string name="No Polish"> - No Polish + 無指甲油 </string> <string name="No Red"> - No Red + 去紅色 </string> <string name="No Spikes"> - No Spikes + 無尖直形 </string> <string name="No White"> - No White + 去白色 </string> <string name="No Wrinkles"> - No Wrinkles + 無皺紋 </string> <string name="Normal Lower"> - Normal Lower + 正常下半 </string> <string name="Normal Upper"> - Normal Upper + 正常上半 </string> <string name="Nose Left"> - Nose Left + 左鼻 </string> <string name="Nose Right"> - Nose Right + 右鼻 </string> <string name="Nose Size"> - Nose Size + 鼻部大小 </string> <string name="Nose Thickness"> - Nose Thickness + 鼻子厚度 </string> <string name="Nose Tip Angle"> - Nose Tip Angle + 鼻尖角度 </string> <string name="Nose Tip Shape"> - Nose Tip Shape + 鼻尖形狀 </string> <string name="Nose Width"> - Nose Width + 鼻寬 </string> <string name="Nostril Division"> - Nostril Division + 鼻孔分開度 </string> <string name="Nostril Width"> - Nostril Width + 鼻孔寬 </string> <string name="Opaque"> - Opaque + 不透明 </string> <string name="Open"> - Open + 打開 </string> <string name="Open Back"> - Open Back + 後開 </string> <string name="Open Front"> - Open Front + 前開 </string> <string name="Open Left"> - Open Left + 左開 </string> <string name="Open Right"> - Open Right + 右開 </string> <string name="Orange"> - Orange + 橘色 </string> <string name="Out"> - Out + 外 </string> <string name="Out Shdw Color"> - Outer Shadow Color + 外陰影顏色 </string> <string name="Out Shdw Opacity"> - Outer Shadow Opacity + 外陰影不透明度 </string> <string name="Outer Eye Corner"> - Outer Eye Corner + 眼外角 </string> <string name="Outer Eye Shadow"> - Outer Eye Shadow + 外眼陰影 </string> <string name="Outer Shadow"> - Outer Shadow + 外陰影 </string> <string name="Overbite"> - Overbite + 齙牙 </string> <string name="Package"> - Package + 配套 </string> <string name="Painted Nails"> - Painted Nails + 美甲 </string> <string name="Pale"> - Pale + 蒼白 </string> <string name="Pants Crotch"> - Pants Crotch + 褲襠 </string> <string name="Pants Fit"> - Pants Fit + 褲子合身度 </string> <string name="Pants Length"> - Pants Length + 褲長 </string> <string name="Pants Waist"> - Pants Waist + 褲腰 </string> <string name="Pants Wrinkles"> - Pants Wrinkles + 褲子皺褶 </string> <string name="Part"> - Part + 邊分 </string> <string name="Part Bangs"> - Part Bangs + 邊分瀏海 </string> <string name="Pectorals"> - Pectorals + 胸肌 </string> <string name="Pigment"> - Pigment + 色素 </string> <string name="Pigtails"> - Pigtails + 辮子 </string> <string name="Pink"> - Pink + 粉紅 </string> <string name="Pinker"> - Pinker + 增加粉紅 </string> <string name="Platform Height"> - Platform Height + 平臺高度 </string> <string name="Platform Width"> - Platform Width + 平臺寬度 </string> <string name="Pointy"> - Pointy + 尖狀 </string> <string name="Pointy Heels"> - Pointy Heels + 尖狀高跟鞋 </string> <string name="Ponytail"> - Ponytail + 馬尾辮 </string> <string name="Poofy Skirt"> - Poofy Skirt + 蓬蓬裙 </string> <string name="Pop Left Eye"> - Pop Left Eye + 左眼 Pop </string> <string name="Pop Right Eye"> - Pop Right Eye + 右眼 Pop </string> <string name="Puffy"> - Puffy + 眼腫 </string> <string name="Puffy Eyelids"> - Puffy Eyelids + 眼瞼腫 </string> <string name="Rainbow Color"> - Rainbow Color + 虹彩 </string> <string name="Red Hair"> - Red Hair + 紅髮 </string> <string name="Regular"> - Regular + 一般 </string> <string name="Right Part"> - Right Part + 右邊分 </string> <string name="Rosy Complexion"> - Rosy Complexion + 臉色紅潤 </string> <string name="Round"> - Round + 圓 </string> <string name="Ruddiness"> - Ruddiness + 紅潤度 </string> <string name="Ruddy"> - Ruddy + 紅潤 </string> <string name="Rumpled Hair"> - Rumpled Hair + 亂髮 </string> <string name="Saddle Bags"> - Saddle Bags + 馬鞍型工具袋 </string> <string name="Scrawny Leg"> - Scrawny Leg + 削瘦的腿 </string> <string name="Separate"> - Separate + 分開 </string> <string name="Shallow"> - Shallow + 淺 </string> <string name="Shear Back"> - Shear Back + 後偏移 </string> <string name="Shear Face"> - Shear Face + 臉部偏移 </string> <string name="Shear Front"> - Shear Front + 前偏移 </string> <string name="Shear Left Up"> - Shear Left Up + 左上偏移 </string> <string name="Shear Right Up"> - Shear Right Up + 右上偏移 </string> <string name="Sheared Back"> - Sheared Back + 後偏移 </string> <string name="Sheared Front"> - Sheared Front + 前偏移 </string> <string name="Shift Left"> - Shift Left + 左移 </string> <string name="Shift Mouth"> - Shift Mouth + 嘴部偏移 </string> <string name="Shift Right"> - Shift Right + 右移 </string> <string name="Shirt Bottom"> - Shirt Bottom + 襯衫底 </string> <string name="Shirt Fit"> - Shirt Fit + 襯衫合身度 </string> <string name="Shirt Wrinkles"> - Shirt Wrinkles + 襯衫皺褶 </string> <string name="Shoe Height"> - Shoe Height + 鞋高 </string> <string name="Short"> - Short + 短 </string> <string name="Short Arms"> - Short Arms + 短臂 </string> <string name="Short Legs"> - Short Legs + 短腿 </string> <string name="Short Neck"> - Short Neck + 短頸 </string> <string name="Short Pigtails"> - Short Pigtails + 短辮子 </string> <string name="Short Ponytail"> - Short Ponytail + 短馬尾辮 </string> <string name="Short Sideburns"> - Short Sideburns + 短鬢鬚 </string> <string name="Short Torso"> - Short Torso + 短軀幹 </string> <string name="Short hips"> - Short hips + 短腰 </string> <string name="Shoulders"> - Shoulders + 肩膀 </string> <string name="Side Fringe"> - Side Fringe + 側瀏海 </string> <string name="Sideburns"> - Sideburns + 鬢鬚 </string> <string name="Sides Hair"> - Sides Hair + 側面頭髮 </string> <string name="Sides Hair Down"> - Sides Hair Down + 側面頭髮下部 </string> <string name="Sides Hair Up"> - Sides Hair Up + 側面頭髮上部 </string> <string name="Skinny Neck"> - Skinny Neck + 削瘦頸部 </string> <string name="Skirt Fit"> - Skirt Fit + 裙子合身度 </string> <string name="Skirt Length"> - Skirt Length + 裙長 </string> <string name="Slanted Forehead"> - Slanted Forehead + 斜前額 </string> <string name="Sleeve Length"> - Sleeve Length + 袖長 </string> <string name="Sleeve Looseness"> - Sleeve Looseness + 袖子寬鬆度 </string> <string name="Slit Back"> - Slit: Back + 後分 </string> <string name="Slit Front"> - Slit: Front + 前分 </string> <string name="Slit Left"> - Slit: Left + 左分 </string> <string name="Slit Right"> - Slit: Right + 右分 </string> <string name="Small"> - Small + 小 </string> <string name="Small Hands"> - Small Hands + 小手 </string> <string name="Small Head"> - Small Head + 小頭 </string> <string name="Smooth"> - Smooth + 平滑 </string> <string name="Smooth Hair"> - Smooth Hair + 平滑頭髮 </string> <string name="Socks Length"> - Socks Length + 襪長 </string> <string name="Soulpatch"> - Soulpatch + 脣下撮鬍 </string> <string name="Sparse"> - Sparse + 稀疏 </string> <string name="Spiked Hair"> - Spiked Hair + 尖直頭髮 </string> <string name="Square"> - Square + 方形 </string> <string name="Square Toe"> - Square Toe + 平頭鞋 </string> <string name="Squash Head"> - Squash Head + 長瓜形臉 </string> <string name="Stretch Head"> - Stretch Head + 延展頭部 </string> <string name="Sunken"> - Sunken + 深陷 </string> <string name="Sunken Chest"> - Sunken Chest + 胸部內陷 </string> <string name="Sunken Eyes"> - Sunken Eyes + 眼睛深陷 </string> <string name="Sweep Back"> - Sweep Back + 後垂擺 </string> <string name="Sweep Forward"> - Sweep Forward + 前垂擺 </string> <string name="Tall"> - Tall + 高 </string> <string name="Taper Back"> - Taper Back + 後漸細 </string> <string name="Taper Front"> - Taper Front + 前漸細 </string> <string name="Thick Heels"> - Thick Heels + 粗腳跟 </string> <string name="Thick Neck"> - Thick Neck + 粗頸 </string> <string name="Thick Toe"> - Thick Toe + 粗腳趾 </string> <string name="Thin"> - Thin + 瘦 </string> <string name="Thin Eyebrows"> - Thin Eyebrows + 細眉 </string> <string name="Thin Lips"> - Thin Lips + 細脣 </string> <string name="Thin Nose"> - Thin Nose + 細鼻 </string> <string name="Tight Chin"> - Tight Chin + 緊緻下巴 </string> <string name="Tight Cuffs"> - Tight Cuffs + 緊緻袖口 </string> <string name="Tight Pants"> - Tight Pants + 緊緻褲子 </string> <string name="Tight Shirt"> - Tight Shirt + 緊緻襯衫 </string> <string name="Tight Skirt"> - Tight Skirt + 緊緻裙子 </string> <string name="Tight Sleeves"> - Tight Sleeves + 緊緻袖子 </string> <string name="Toe Shape"> - Toe Shape + 腳趾形狀 </string> <string name="Toe Thickness"> - Toe Thickness + 腳趾粗細 </string> <string name="Torso Length"> - Torso Length + 軀幹長度 </string> <string name="Torso Muscles"> - Torso Muscles + 軀幹肌肉 </string> <string name="Torso Scrawny"> - Torso Scrawny + 軀幹削瘦 </string> <string name="Unattached"> - Unattached + 未附著 </string> <string name="Uncreased"> - Uncreased + 無皺痕 </string> <string name="Underbite"> - Underbite + 戽斗 </string> <string name="Unnatural"> - Unnatural + 不自然 </string> <string name="Upper Bridge"> - Upper Bridge + 上鼻梁 </string> <string name="Upper Cheeks"> - Upper Cheeks + 上臉頰 </string> <string name="Upper Chin Cleft"> - Upper Chin Cleft + 上部顎裂 </string> <string name="Upper Eyelid Fold"> - Upper Eyelid Fold + 上眼瞼皺褶 </string> <string name="Upturned"> - Upturned + 嘴角上翹 </string> <string name="Very Red"> - Very Red + 大紅 </string> <string name="Waist Height"> - Waist Height + 腰高 </string> <string name="Well-Fed"> - Well-Fed + 飽食的 </string> <string name="White Hair"> - White Hair + 白髮 </string> <string name="Wide"> - Wide + 寬 </string> <string name="Wide Back"> - Wide Back + 後寬 </string> <string name="Wide Front"> - Wide Front + 前寬 </string> <string name="Wide Lips"> - Wide Lips + 寬脣 </string> <string name="Wild"> - Wild + 狂野 </string> <string name="Wrinkles"> - Wrinkles + 皺紋 </string> <string name="LocationCtrlAddLandmarkTooltip"> 添加到我的地標 @@ -3585,6 +3868,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="LocationCtrlGeneralIconTooltip"> 一般普級地區 </string> + <string name="LocationCtrlSeeAVsTooltip"> + 可看到本地段外的化身,並與之交談 + </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + 地區重新產出之前,可移動物件可能無法正常運作。 + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + 這地區並未啟用動態尋徑。 + </string> <string name="UpdaterWindowTitle"> [APP_NAME] 更新 </string> @@ -3595,7 +3887,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. [APP_NAME] 安裝中... </string> <string name="UpdaterUpdatingDescriptive"> - Your [APP_NAME] Viewer is being updated to the latest release. This may take some time, so please be patient. + 你的 [APP_NAME] Viewer 正在更新為最新發行版。 可能要等一會兒,請耐心稍候。 </string> <string name="UpdaterProgressBarTextWithEllipses"> 更新下載中... @@ -3607,7 +3899,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 夏載更新失敗 </string> <string name="UpdaterFailUpdateDescriptive"> - An error occurred while updating [APP_NAME]. Please download the latest version from www.secondlife.com. + [APP_NAME] 更新時出錯。 請到 www.secondlife.com 下載最新版本。 </string> <string name="UpdaterFailInstallTitle"> 安裝更新失敗 @@ -3616,13 +3908,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 啟動瀏覽器失敗 </string> <string name="ItemsComingInTooFastFrom"> - [APP_NAME]: Items coming in too fast from [FROM_NAME], automatic preview disabled for [TIME] seconds + [APP_NAME]:來自 [FROM_NAME] 的項目速度過快,因此自動預覽暫停 [TIME] 秒 </string> <string name="ItemsComingInTooFast"> - [APP_NAME]: Items coming in too fast, automatic preview disabled for [TIME] seconds + [APP_NAME]:進來的項目速度過快,因此自動預覽暫停 [TIME] 秒 </string> <string name="IM_logging_string"> - -- Instant message logging enabled -- + -- 已開啟及時訊息記錄 -- </string> <string name="IM_typing_start_string"> [NAME] 正在輸入... @@ -3631,43 +3923,46 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. (未命名) </string> <string name="IM_moderated_chat_label"> - (Moderated: Voices off by default) + (有人主持:預設關閉語音) </string> <string name="IM_unavailable_text_label"> - Text chat is not available for this call. + 這次通話無法使用文字聊天。 </string> <string name="IM_muted_text_label"> - Your text chat has been disabled by a Group Moderator. + 群組主持人已禁止你進行文字聊天。 </string> <string name="IM_default_text_label"> - 點擊此處以傳送即時訊息。 + 點按此處以傳送即時訊息。 </string> <string name="IM_to_label"> 至 </string> <string name="IM_moderator_label"> - (Moderator) + (主持人) </string> <string name="Saved_message"> - (Saved [LONG_TIMESTAMP]) + (於 [LONG_TIMESTAMP] 儲存) + </string> + <string name="IM_unblock_only_groups_friends"> + 要察看這訊息,你必須到「偏好設定 / 隱私」,取消勾選「只有我的朋友和群組可以 IM 或與我通話」。 </string> <string name="answered_call"> - Your call has been answered + 你的通話已經接通 </string> <string name="you_started_call"> - You started a voice call + 你發起了語音通話 </string> <string name="you_joined_call"> - You joined the voice call + 你發起了語音通話 </string> <string name="name_started_call"> - [NAME] started a voice call + [NAME] 發起了語音通話 </string> <string name="ringing-im"> 加入語音通話... </string> <string name="connected-im"> - Connected, click Leave Call to hang up + 已接通,要掛斷請按「離開通話」 </string> <string name="hang_up-im"> 離開語音通話 @@ -3676,40 +3971,40 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 聯接中... </string> <string name="conference-title"> - Ad-hoc Conference + 臨時多方通話 </string> <string name="conference-title-incoming"> - Conference with [AGENT_NAME] + 和 [AGENT_NAME] 多方通話 </string> <string name="inventory_item_offered-im"> - Inventory item offered + 收納區物品已發送 </string> <string name="share_alert"> - Drag items from inventory here + 將收納區物品拖曳到這裡 </string> <string name="no_session_message"> (IM 會話不存在) </string> <string name="only_user_message"> - You are the only user in this session. + 這次會話只有你一人。 </string> <string name="offline_message"> [NAME] 離線。 </string> <string name="invite_message"> - Click the [BUTTON NAME] button to accept/connect to this voice chat. + 點按 [BUTTON NAME] 按鈕接受並連通到這個語音聊天。 </string> <string name="muted_message"> - You have blocked this Resident. Sending a message will automatically unblock them. + 你已經封鎖這位居民。 發送訊息將會自動解除封鎖。 </string> <string name="generic"> - Error making request, please try again later. + 送出請求時出錯,請稍候再試。 </string> <string name="generic_request_error"> - Error making request, please try again later. + 送出請求時出錯,請稍候再試。 </string> <string name="insufficient_perms_error"> - You do not have sufficient permissions. + 你權限不足。 </string> <string name="session_does_not_exist_error"> 此會話不再存在 @@ -3721,25 +4016,25 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 你並不具有這個能力。 </string> <string name="not_a_mod_error"> - You are not a session moderator. + 你不具會話主持人身份。 </string> <string name="muted"> - A group moderator disabled your text chat. + 某群組主持人禁止了你的文字聊天。 </string> <string name="muted_error"> - A group moderator disabled your text chat. + 某群組主持人禁止了你的文字聊天。 </string> <string name="add_session_event"> - Unable to add users to chat session with [RECIPIENT]. + 無法新增使用者加入與 [RECIPIENT] 的聊天會話。 </string> <string name="message"> - Unable to send your message to the chat session with [RECIPIENT]. + 你的訊息無法傳送給與 [RECIPIENT] 的聊天會話。 </string> <string name="message_session_event"> - Unable to send your message to the chat session with [RECIPIENT]. + 你的訊息無法傳送給與 [RECIPIENT] 的聊天會話。 </string> <string name="mute"> - Error while moderating. + 主持期間發生錯誤。 </string> <string name="removed"> 你已經由群組中被移除。 @@ -3748,49 +4043,64 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 你已經由群組中被移除。 </string> <string name="close_on_no_ability"> - You no longer have the ability to be in the chat session. + 你已無法進入這個聊天會話。 </string> <string name="unread_chat_single"> - [SOURCES] has said something new + [SOURCES] 又說了一些話 </string> <string name="unread_chat_multiple"> - [SOURCES] have said something new + [SOURCES] 又說了一些話 </string> <string name="session_initialization_timed_out_error"> - The session initialization is timed out + 會話初始化逾時,無法完成 + </string> + <string name="Home position set."> + 我的家位置已定。 </string> <string name="voice_morphing_url"> http://secondlife.com/landing/voicemorphing </string> <string name="paid_you_ldollars"> - [NAME] paid you L$[AMOUNT] [REASON]. + [NAME] 支付你 L$[AMOUNT]([REASON])。 </string> <string name="paid_you_ldollars_no_reason"> - [NAME] paid you L$[AMOUNT]. + [NAME] 支付你 L$[AMOUNT]。 </string> <string name="you_paid_ldollars"> - You paid [NAME] L$[AMOUNT] [REASON]. + 你支付 L$[AMOUNT] 給 [NAME]([REASON])。 </string> <string name="you_paid_ldollars_no_info"> - You paid L$[AMOUNT]. + 你支付了 L$[AMOUNT]。 </string> <string name="you_paid_ldollars_no_reason"> - You paid [NAME] L$[AMOUNT]. + 你支付 L$[AMOUNT] 給 [NAME]。 </string> <string name="you_paid_ldollars_no_name"> - You paid L$[AMOUNT] [REASON]. + 你支付了 L$[AMOUNT]([REASON])。 + </string> + <string name="you_paid_failure_ldollars"> + 你支付 L$[AMOUNT] 給 [NAME] 時出錯:[REASON]。 + </string> + <string name="you_paid_failure_ldollars_no_info"> + 你支付 L$[AMOUNT] 時出錯。 + </string> + <string name="you_paid_failure_ldollars_no_reason"> + 你支付 L$[AMOUNT] 給 [NAME] 時出錯。 + </string> + <string name="you_paid_failure_ldollars_no_name"> + 你支付 L$[AMOUNT] 時出錯:[REASON]。 </string> <string name="for item"> - for [ITEM] + 購買 [ITEM] </string> <string name="for a parcel of land"> - for a parcel of land + 購買一土地地段 </string> <string name="for a land access pass"> - for a land access pass + 購買土地出入通行權 </string> <string name="for deeding land"> - for deeding land + 讓渡土地 </string> <string name="to create a group"> 以創造群組 @@ -3802,39 +4112,39 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 以上傳 </string> <string name="to publish a classified ad"> - to publish a classified ad + 發布一則個人廣告 </string> <string name="giving"> - Giving L$ [AMOUNT] + 捐贈 L$ [AMOUNT] </string> <string name="uploading_costs"> 上傳花費 L$ [AMOUNT] </string> <string name="this_costs"> - This costs L$ [AMOUNT] + 本次花費 L$ [AMOUNT] </string> <string name="buying_selected_land"> - Buying selected land for L$ [AMOUNT] + 花費 L$ [AMOUNT] 購買所選土地 </string> <string name="this_object_costs"> - This object costs L$ [AMOUNT] + 本物件價格 L$ [AMOUNT] </string> <string name="group_role_everyone"> 任何人 </string> <string name="group_role_officers"> - Officers + 職員 </string> <string name="group_role_owners"> - 擁有者 + 所有人 </string> <string name="group_member_status_online"> 上線 </string> <string name="uploading_abuse_report"> 上傳中... - -舉報濫用 + +違規舉報 </string> <string name="New Shape"> 新體形 @@ -3861,7 +4171,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 新襪子 </string> <string name="New Jacket"> - 新夾克 + 新外套 </string> <string name="New Gloves"> 新手套 @@ -3912,7 +4222,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 女性姿勢 </string> <string name="Other Gestures"> - 其他姿勢 + 其他���勢 </string> <string name="Speech Gestures"> 演說姿勢 @@ -3921,91 +4231,172 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 一般姿勢 </string> <string name="Male - Excuse me"> - Male - Excuse me + 男性 - Excuse me </string> <string name="Male - Get lost"> - Male - Get lost + Male - 給我滾蛋! </string> <string name="Male - Blow kiss"> - Male - Blow kiss + 男性 - 飛吻 </string> <string name="Male - Boo"> - Male - Boo + 男性 - 我噓你 </string> <string name="Male - Bored"> - Male - Bored + 男性 - 無聊狀 </string> <string name="Male - Hey"> - Male - Hey + 男性 - 嘿! </string> <string name="Male - Laugh"> - Male - Laugh + 男性 - 笑 </string> <string name="Male - Repulsed"> - Male - Repulsed + 男性 - 作噁 </string> <string name="Male - Shrug"> - Male - Shrug + 男性 - 聳聳肩 </string> <string name="Male - Stick tougue out"> - Male - Stick tougue out + 男性 - 吐舌頭 </string> <string name="Male - Wow"> - Male - Wow + 男性 - 哇塞 </string> <string name="Female - Chuckle"> - Female - Chuckle + 女性 - 咯咯笑 </string> <string name="Female - Cry"> - Female - Cry + 女性 - 哭 </string> <string name="Female - Embarrassed"> - Female - Embarrassed + 女性 - 尷尬 </string> <string name="Female - Excuse me"> - Female - Excuse me + 男性 - Excuse me </string> <string name="Female - Get lost"> - Female - Get lost + 女性 - 給我滾蛋! </string> <string name="Female - Blow kiss"> - Female - Blow kiss + 女性 - 飛吻 </string> <string name="Female - Boo"> - Female - Boo + 女性 - 我噓你 </string> <string name="Female - Bored"> - Female - Bored + 女性 - 無聊狀 </string> <string name="Female - Hey"> - Female - Hey + 女性 - 嘿! </string> <string name="Female - Hey baby"> - Female - Hey baby + 女性 - 嘿,寶貝 </string> <string name="Female - Laugh"> - Female - Laugh + 女性 - 笑 </string> <string name="Female - Looking good"> - Female - Looking good + 女性 - 看我美不美 </string> <string name="Female - Over here"> - Female - Over here + 女性 - 我在這兒 </string> <string name="Female - Please"> - Female - Please + 女性 - 請 </string> <string name="Female - Repulsed"> - Female - Repulsed + 女性 - 作噁 </string> <string name="Female - Shrug"> - Female - Shrug + 女性 - 聳聳肩 </string> <string name="Female - Stick tougue out"> - Female - Stick tougue out + 女性 - 吐舌頭 </string> <string name="Female - Wow"> - Female - Wow + 女性 - 哇塞 + </string> + <string name="/bow"> + /彎腰點頭 + </string> + <string name="/clap"> + /拍手 + </string> + <string name="/count"> + /計數 + </string> + <string name="/extinguish"> + /熄菸 + </string> + <string name="/kmb"> + /給我一個吻 + </string> + <string name="/muscle"> + /肌肉 + </string> + <string name="/no"> + /不 + </string> + <string name="/no!"> + /不! + </string> + <string name="/paper"> + /布 + </string> + <string name="/pointme"> + /指自己 + </string> + <string name="/pointyou"> + /指向你 + </string> + <string name="/rock"> + /石頭 + </string> + <string name="/scissor"> + /剪刀 + </string> + <string name="/smoke"> + /抽菸 + </string> + <string name="/stretch"> + /伸展 + </string> + <string name="/whistle"> + /吹口哨 + </string> + <string name="/yes"> + /是 + </string> + <string name="/yes!"> + /是! + </string> + <string name="afk"> + 暫時離開 + </string> + <string name="dance1"> + 跳舞1 + </string> + <string name="dance2"> + 跳舞2 + </string> + <string name="dance3"> + 跳舞3 + </string> + <string name="dance4"> + 跳舞4 + </string> + <string name="dance5"> + 跳舞5 + </string> + <string name="dance6"> + 跳舞6 + </string> + <string name="dance7"> + 跳舞7 + </string> + <string name="dance8"> + 跳舞8 </string> <string name="AvatarBirthDateFormat"> [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] @@ -4018,34 +4409,34 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. </string> <string name="words_separator" value=","/> <string name="server_is_down"> - Despite our best efforts, something unexpected has gone wrong. + 儘管我們努力避免,還是發生意料外的錯誤。 - Please check status.secondlifegrid.net to see if there is a known problem with the service. - If you continue to experience problems, please check your network and firewall setup. + 請察訪 status.secondlifegrid.net 看是否發生了已知狀況。 + 如果文體繼續發生,請檢查你的網路和防火牆設定。 </string> <string name="dateTimeWeekdaysNames"> - Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday + 星期日:星期一:星期二:星期三:星期四:星期五:星期六 </string> <string name="dateTimeWeekdaysShortNames"> - Sun:Mon:Tue:Wed:Thu:Fri:Sat + 星期日:星期一:星期二:星期三:星期四:星期五:星期六 </string> <string name="dateTimeMonthNames"> - January:February:March:April:May:June:July:August:September:October:November:December + 一月:二月:三月:四月:五月:六月:七月:八月:九月:十月:十一月:十二月 </string> <string name="dateTimeMonthShortNames"> - Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec + 一月:二月:三月:四月:五月:六月:七月:八月:九月:十月:十一月:十二月 </string> <string name="dateTimeDayFormat"> [MDAY] </string> <string name="dateTimeAM"> - AM + 上午 </string> <string name="dateTimePM"> - PM + 下午 </string> <string name="LocalEstimateUSD"> - US$ [AMOUNT] + $ [AMOUNT] 美元 </string> <string name="Membership"> 成員資格 @@ -4054,25 +4445,25 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 角色 </string> <string name="Group Identity"> - Group Identity + 群組身份 </string> <string name="Parcel Management"> 地段管理 </string> <string name="Parcel Identity"> - Parcel Identity + 地段名 </string> <string name="Parcel Settings"> 地段設定 </string> <string name="Parcel Powers"> - Parcel Powers + 地段權利 </string> <string name="Parcel Access"> - Parcel Access + 地段出入 </string> <string name="Parcel Content"> - Parcel Content + 地段內容 </string> <string name="Object Management"> 物件管理 @@ -4090,7 +4481,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 刪除所選取的物品? </string> <string name="DeleteItem"> - 刪除所選取的物品? + 刪除所選取的物���? </string> <string name="EmptyOutfitText"> 沒有任何物品在這個裝扮內 @@ -4099,72 +4490,78 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. 選擇一個編輯器使用 ExternalEditor 設定。 </string> <string name="ExternalEditorNotFound"> - Cannot find the external editor you specified. -Try enclosing path to the editor with double quotes. -(e.g. "/path to my/editor" "%s") + 找不到你指定的外部編輯器。 +請嘗試在編輯器路經前後加上英文雙括號。 +(例:"/path to my/editor" "%s") </string> <string name="ExternalEditorCommandParseError"> - Error parsing the external editor command. + 解析外部編輯器指令時出錯。 </string> <string name="ExternalEditorFailedToRun"> 執行外部編輯器失敗。 </string> + <string name="TranslationFailed"> + 無法翻譯:[REASON] + </string> + <string name="TranslationResponseParseError"> + 無法剖析平移回應。 + </string> <string name="Esc"> - Esc + Esc 鍵 </string> <string name="Space"> - Space + 空間鍵 </string> <string name="Enter"> - Enter + Enter 鍵 </string> <string name="Tab"> - Tab + Tab 鍵 </string> <string name="Ins"> - Ins + Ins 鍵 </string> <string name="Del"> - Del + Del 鍵 </string> <string name="Backsp"> - Backsp + Backspace 鍵 </string> <string name="Shift"> - Shift + Shift 鍵 </string> <string name="Ctrl"> - Ctrl + Ctrl 鍵 </string> <string name="Alt"> - Alt + Alt 鍵 </string> <string name="CapsLock"> - CapsLock + CapsLock 鍵 </string> <string name="Left"> - Left + 左移鍵 </string> <string name="Right"> - Right + 右移鍵 </string> <string name="Up"> - Up + 上移鍵 </string> <string name="Down"> - Down + 下移鍵 </string> <string name="Home"> - Home + Home 鍵 </string> <string name="End"> - End + End 鍵 </string> <string name="PgUp"> - PgUp + PgUp 鍵 </string> <string name="PgDn"> - PgDn + PgDn 鍵 </string> <string name="F1"> F1 @@ -4203,16 +4600,16 @@ Try enclosing path to the editor with double quotes. F12 </string> <string name="Add"> - Add + 添加 </string> <string name="Subtract"> - Subtract + 減 </string> <string name="Multiply"> - Multiply + 乘 </string> <string name="Divide"> - Divide + 除 </string> <string name="PAD_DIVIDE"> PAD_DIVIDE @@ -4392,7 +4789,7 @@ Try enclosing path to the editor with double quotes. M </string> <string name="N"> - N + 北 </string> <string name="O"> O @@ -4407,7 +4804,7 @@ Try enclosing path to the editor with double quotes. R </string> <string name="S"> - S + 南 </string> <string name="T"> T @@ -4419,7 +4816,7 @@ Try enclosing path to the editor with double quotes. V </string> <string name="W"> - W + 西 </string> <string name="X"> X @@ -4431,24 +4828,243 @@ Try enclosing path to the editor with double quotes. Z </string> <string name="BeaconParticle"> - Viewing particle beacons (blue) + 檢視粒子效果的導引(藍色) </string> <string name="BeaconPhysical"> - Viewing physical object beacons (green) + 檢視具體物件的導引(綠色) </string> <string name="BeaconScripted"> - Viewing scripted object beacons (red) + 檢視腳本物件的導引(紅色) </string> <string name="BeaconScriptedTouch"> - Viewing scripted object with touch function beacons (red) + 檢視帶有觸摸函式腳本物件的導引(紅色) </string> <string name="BeaconSound"> - Viewing sound beacons (yellow) + 檢視聲音的導引(黃色) </string> <string name="BeaconMedia"> - Viewing media beacons (white) + 檢視媒體的導引(白色) </string> <string name="ParticleHiding"> - Hiding Particles + 隱藏粒子效果 + </string> + <string name="Command_AboutLand_Label"> + 土地資料 + </string> + <string name="Command_Appearance_Label"> + 編輯外觀 + </string> + <string name="Command_Avatar_Label"> + 化身 + </string> + <string name="Command_Build_Label"> + 建造 + </string> + <string name="Command_Chat_Label"> + 聊天 + </string> + <string name="Command_Compass_Label"> + 羅盤 + </string> + <string name="Command_Destinations_Label"> + 目的地 + </string> + <string name="Command_Gestures_Label"> + 姿勢 + </string> + <string name="Command_HowTo_Label"> + 簡易教學 + </string> + <string name="Command_Inventory_Label"> + 收納區 + </string> + <string name="Command_Map_Label"> + 地圖 + </string> + <string name="Command_Marketplace_Label"> + 第二人生購物市集 + </string> + <string name="Command_MiniMap_Label"> + 迷你地圖 + </string> + <string name="Command_Move_Label"> + 行走 / 跑步 / 飛行 + </string> + <string name="Command_Outbox_Label"> + 商家發件匣 + </string> + <string name="Command_People_Label"> + 人群 + </string> + <string name="Command_Picks_Label"> + 精選地點 + </string> + <string name="Command_Places_Label"> + 地點 + </string> + <string name="Command_Preferences_Label"> + 偏好設定 + </string> + <string name="Command_Profile_Label"> + 檔案 + </string> + <string name="Command_Search_Label"> + 搜尋 + </string> + <string name="Command_Snapshot_Label"> + 快照 + </string> + <string name="Command_Speak_Label"> + 說話 + </string> + <string name="Command_View_Label"> + 攝影機控制 + </string> + <string name="Command_Voice_Label"> + 語音設定 + </string> + <string name="Command_AboutLand_Tooltip"> + 有關你所處土地的資訊 + </string> + <string name="Command_Appearance_Tooltip"> + 改變化身 + </string> + <string name="Command_Avatar_Tooltip"> + 選擇一個完整的化身 + </string> + <string name="Command_Build_Tooltip"> + 建製物件和重塑地形 + </string> + <string name="Command_Chat_Tooltip"> + 透過文字和附近人們聊天 + </string> + <string name="Command_Compass_Tooltip"> + 指南針 + </string> + <string name="Command_Destinations_Tooltip"> + 你可能感興趣的目的地 + </string> + <string name="Command_Gestures_Tooltip"> + 你化身可用的姿勢 + </string> + <string name="Command_HowTo_Tooltip"> + 如何完成常用的動作 + </string> + <string name="Command_Inventory_Tooltip"> + 察看並使用你擁有的物件 + </string> + <string name="Command_Map_Tooltip"> + 世界地圖 + </string> + <string name="Command_Marketplace_Tooltip"> + 前往購物 + </string> + <string name="Command_MiniMap_Tooltip"> + 顯示附近的人 + </string> + <string name="Command_Move_Tooltip"> + 移動化身 + </string> + <string name="Command_Outbox_Tooltip"> + 將物項轉移到第二人生購物市集待售 + </string> + <string name="Command_People_Tooltip"> + 朋友、群組和附近的人 + </string> + <string name="Command_Picks_Tooltip"> + 顯示在你的小檔案中的最愛地點 + </string> + <string name="Command_Places_Tooltip"> + 你儲存的地點 + </string> + <string name="Command_Preferences_Tooltip"> + 偏好設定 + </string> + <string name="Command_Profile_Tooltip"> + 編輯或察看你的小檔案 + </string> + <string name="Command_Search_Tooltip"> + 尋找地點、活動、其他人 + </string> + <string name="Command_Snapshot_Tooltip"> + 拍一張照片 + </string> + <string name="Command_Speak_Tooltip"> + 用麥克風和附近人們交談 + </string> + <string name="Command_View_Tooltip"> + 調整攝影機角度 + </string> + <string name="Command_Voice_Tooltip"> + 在虛擬世界裡通話和附近人群的音量控制 + </string> + <string name="Toolbar_Bottom_Tooltip"> + 目前位在你的底部工具列 + </string> + <string name="Toolbar_Left_Tooltip"> + 目前位在你的左工具列 + </string> + <string name="Toolbar_Right_Tooltip"> + 目前位在你的右工具列 + </string> + <string name="Retain%"> + 保留% + </string> + <string name="Detail"> + 細節 + </string> + <string name="Better Detail"> + 更多細節 + </string> + <string name="Surface"> + 表面 + </string> + <string name="Solid"> + 固體 + </string> + <string name="Wrap"> + Wrap + </string> + <string name="Preview"> + 預覽 + </string> + <string name="Normal"> + 正常 + </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + 無 + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + 影響導航網面 + </string> + <string name="Pathfinding_Object_Attr_Character"> + 角色 + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (多項) + </string> + <string name="snapshot_quality_very_low"> + 很低 + </string> + <string name="snapshot_quality_low"> + 低 + </string> + <string name="snapshot_quality_medium"> + 中 + </string> + <string name="snapshot_quality_high"> + 高 + </string> + <string name="snapshot_quality_very_high"> + 很高 + </string> + <string name="TeleportMaturityExceeded"> + 此居民不得進入此地區。 + </string> + <string name="UserDictionary"> + [User] </string> </strings> diff --git a/indra/newview/skins/default/xui/zh/teleport_strings.xml b/indra/newview/skins/default/xui/zh/teleport_strings.xml index bfdb107810..37080a8d0c 100644 --- a/indra/newview/skins/default/xui/zh/teleport_strings.xml +++ b/indra/newview/skins/default/xui/zh/teleport_strings.xml @@ -2,15 +2,15 @@ <teleport_messages> <message_set name="errors"> <message name="invalid_tport"> - Problem encountered processing your teleport request. You may need to log back in before you can teleport. + 處理你瞬間傳送要求時發生問題。 如果想要瞬間傳送,你可能需要重新登入。 如果你持續得到此訊息,請查閱 [SUPPORT_SITE]。 </message> <message name="invalid_region_handoff"> - Problem encountered processing your region crossing. You may need to log back in before you can cross regions. + 處理你跨越地區動作時發生問題。 如果想要跨越地區,你可能需要重新登入。 如果你持續得到此訊息,請查閱 [SUPPORT_SITE]。 </message> <message name="blocked_tport"> - 抱歉,目前瞬間傳送已被阻擋。請稍後再試。 + 抱歉,目前禁止瞬間傳送。 請稍後再試。 如果你仍無法進行瞬間傳送,請登出後重新入來解決此一問題。 </message> <message name="nolandmark_tport"> @@ -21,40 +21,43 @@ 請稍後再試。 </message> <message name="NoHelpIslandTP"> - 您不能瞬间转移回“援助岛”。 -去“公共援助岛”重复您的教程。 + 你無法瞬間傳送回「新手導引島」。 +請到「大眾新手導引島」重新參加導引教學。 </message> <message name="noaccess_tport"> 抱歉,你並沒有權限進入要瞬間傳送的目的地。 </message> <message name="missing_attach_tport"> - Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport. + 你的附件尚未抵達。 請稍候一會兒,或請登出後重新登入,再嘗試瞬間傳送。 </message> <message name="too_many_uploads_tport"> - The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area. + 該地區的資產查詢目前太過擁塞,因此你的瞬間傳送動作可能無法即時發生。 請稍候再試,或請前往較不擁塞的地區。 </message> <message name="expired_tport"> - Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes. + 抱歉,系統無法即時完成為你瞬間傳送。 請稍待幾分鐘再試。 </message> <message name="expired_region_handoff"> - Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes. + 抱歉,系統無法即時讓你跨越地區。 請稍待幾分鐘再試。 </message> <message name="no_host"> - Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes. + 找不到瞬間傳送的目的地。 目的地可能暫時不可用,或已不存在。 請稍待幾分鐘再試。 </message> <message name="no_inventory_host"> 收納區功能目前無法使用。 </message> + <message name="MustGetAgeRegion"> + 你必須年滿 18 歲才可進入這地區。 + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> - Sending to destination. + 送往目的地。 </message> <message name="redirecting"> 重新導向至不同位置。 </message> <message name="relaying"> - Relaying to destination. + 接繼送往目的地。 </message> <message name="sending_home"> 送出家位置的要求。 @@ -80,5 +83,8 @@ <message name="requesting"> 瞬間傳送要求中... </message> + <message name="pending"> + 等待瞬間傳送… + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/paths.xml b/indra/newview/skins/paths.xml deleted file mode 100644 index 3c0da041c7..0000000000 --- a/indra/newview/skins/paths.xml +++ /dev/null @@ -1,10 +0,0 @@ -<paths> - <directory> - <subdir>xui</subdir> - <subdir>en</subdir> - </directory> - <directory> - <subdir>xui</subdir> - <subdir>[LANGUAGE]</subdir> - </directory> -</paths>
\ No newline at end of file diff --git a/indra/newview/tests/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp index 88f063f009..2bc6772d86 100644 --- a/indra/newview/tests/lldir_stub.cpp +++ b/indra/newview/tests/lldir_stub.cpp @@ -32,7 +32,7 @@ BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask void LLDir::setChatLogsDir(const std::string &path) {} void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last) {} void LLDir::setLindenUserDir(const std::string &first, const std::string &last) {} -void LLDir::setSkinFolder(const std::string &skin_folder) {} +void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language) {} bool LLDir::setCacheDir(const std::string &path) { return true; } void LLDir::dumpCurrentDirectories() {} diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 04118a5c87..86f978faf1 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -28,6 +28,7 @@ $/LicenseInfo$ """ import sys import os.path +import errno import re import tarfile import time @@ -74,20 +75,20 @@ class ViewerManifest(LLManifest): # include the list of Lindens (if any) # see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits linden_names_path = os.getenv("LINDEN_CREDITS") - if linden_names_path : + if not linden_names_path : + print "No 'LINDEN_CREDITS' specified in environment, using built-in list" + else: try: linden_file = open(linden_names_path,'r') + except IOError: + print "No Linden names found at '%s', using built-in list" % linden_names_path + else: # all names should be one line, but the join below also converts to a string linden_names = ', '.join(linden_file.readlines()) self.put_in_file(linden_names, "lindens.txt") linden_file.close() print "Linden names extracted from '%s'" % linden_names_path self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")]) - except IOError: - print "No Linden names found at '%s', using built-in list" % linden_names_path - pass - else : - print "No 'LINDEN_CREDITS' specified in environment, using built-in list" # ... and the entire windlight directory self.path("windlight") @@ -114,7 +115,6 @@ class ViewerManifest(LLManifest): # skins if self.prefix(src="skins"): - self.path("paths.xml") # include the entire textures directory recursively if self.prefix(src="*/textures"): self.path("*/*.tga") @@ -132,11 +132,18 @@ class ViewerManifest(LLManifest): self.path("*/*.xml") # Local HTML files (e.g. loading screen) - if self.prefix(src="*/html"): + # The claim is that we never use local html files any + # longer. But rather than commenting out this block, let's + # rename every html subdirectory as html.old. That way, if + # we're wrong, a user actually does have the relevant + # files; s/he just needs to rename every html.old + # directory back to html to recover them. + if self.prefix(src="*/html", dst="*/html.old"): self.path("*.png") self.path("*/*/*.html") self.path("*/*/*.gif") self.end_prefix("*/html") + self.end_prefix("skins") # local_assets dir (for pre-cached textures) @@ -149,14 +156,9 @@ class ViewerManifest(LLManifest): self.path("gpu_table.txt") # The summary.json file gets left in the base checkout dir by - # build.sh. It's only created for a build.sh build, therefore we - # have to check whether it exists. :-P - summary_json = "summary.json" - summary_json_path = os.path.join(os.pardir, os.pardir, summary_json) - if os.path.exists(os.path.join(self.get_src_prefix(), summary_json_path)): - self.path(summary_json_path, summary_json) - else: - print "No %s" % os.path.join(self.get_src_prefix(), summary_json_path) + # build.sh. It's only created for a build.sh build. + if not self.path2basename(os.path.join(os.pardir, os.pardir), "summary.json"): + print "No summary.json file" def login_channel(self): """Channel reported for login and upgrade purposes ONLY; @@ -327,13 +329,13 @@ class WindowsManifest(ViewerManifest): self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) # Plugin host application - self.path(os.path.join(os.pardir, - 'llplugin', 'slplugin', self.args['configuration'], "slplugin.exe"), - "slplugin.exe") + self.path2basename(os.path.join(os.pardir, + 'llplugin', 'slplugin', self.args['configuration']), + "slplugin.exe") #self.disable_manifest_check() - self.path(src="../viewer_components/updater/scripts/windows/update_install.bat", dst="update_install.bat") + self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat") # Get shared libs from the shared libs staging directory if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']), dst=""): @@ -367,9 +369,7 @@ class WindowsManifest(ViewerManifest): # Get fmod dll, continue if missing - try: - self.path("fmod.dll") - except: + if not self.path("fmod.dll"): print "Skipping fmod.dll" # For textures @@ -711,85 +711,82 @@ class DarwinManifest(ViewerManifest): self.path("uk.lproj") self.path("zh-Hans.lproj") - libdir = "../packages/lib/release" - dylibs = {} + def path_optional(src, dst): + """ + For a number of our self.path() calls, not only do we want + to deal with the absence of src, we also want to remember + which were present. Return either an empty list (absent) + or a list containing dst (present). Concatenate these + return values to get a list of all libs that are present. + """ + if self.path(src, dst): + return [dst] + print "Skipping %s" % dst + return [] - # Need to get the llcommon dll from any of the build directories as well - lib = "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.dylib", - "libaprutil-1.0.dylib", - "libexpat.1.5.2.dylib", - "libexception_handler.dylib", - "libGLOD.dylib", - "libcollada14dom.dylib" - ): - self.path(os.path.join(libdir, libfile), libfile) - - # SLVoice and vivox lols - for libfile in ('libsndfile.dylib', 'libvivoxoal.dylib', 'libortp.dylib', \ - 'libvivoxsdk.dylib', 'libvivoxplatform.dylib', 'SLVoice') : - self.path(os.path.join(libdir, libfile), libfile) + libdir = "../packages/lib/release" + # dylibs is a list of all the .dylib files we expect to need + # in our bundled sub-apps. For each of these we'll create a + # symlink from sub-app/Contents/Resources to the real .dylib. + # Need to get the llcommon dll from any of the build directories as well. + libfile = "libllcommon.dylib" + dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir, + "llcommon", + self.args['configuration'], + libfile), + os.path.join(libdir, libfile)), + dst=libfile) + + for libfile in ( + "libapr-1.0.dylib", + "libaprutil-1.0.dylib", + "libcollada14dom.dylib", + "libexpat.1.5.2.dylib", + "libexception_handler.dylib", + "libGLOD.dylib", + ): + dylibs += path_optional(os.path.join(libdir, libfile), libfile) + + # SLVoice and vivox lols, no symlinks needed + for libfile in ( + 'libortp.dylib', + 'libsndfile.dylib', + 'libvivoxoal.dylib', + 'libvivoxsdk.dylib', + 'libvivoxplatform.dylib', + 'SLVoice', + ): + self.path2basename(libdir, libfile) - try: - # FMOD for sound - self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib") - except: - print "Skipping FMOD - not found" + # FMOD for sound + libfile = "libfmodwrapper.dylib" + path_optional(os.path.join(self.args['configuration'], libfile), libfile) # 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") - - # plugin launcher - self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") - - # our apps dependencies on shared libs - if dylibs["llcommon"]: - mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") - mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources") - slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") - for libfile in ("libllcommon.dylib", - "libapr-1.0.dylib", - "libaprutil-1.0.dylib", - "libexpat.1.5.2.dylib", - "libexception_handler.dylib", - "libGLOD.dylib", - "libcollada14dom.dylib" - ): - target_lib = os.path.join('../../..', libfile) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(mac_crash_logger_res_path, libfile)} - ) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(mac_updater_res_path, libfile)} - ) - self.run_command("ln -sf %(target)r %(link)r" % - {'target': target_lib, - 'link' : os.path.join(slplugin_res_path, libfile)} - ) + for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), + ("mac_updater", "mac-updater.app"), + # plugin launcher + (os.path.join("llplugin", "slplugin"), "SLPlugin.app"), + ): + self.path2basename(os.path.join(os.pardir, + app_bld_dir, self.args['configuration']), + app) + + # our apps dependencies on shared libs + # for each app, for each dylib we collected in dylibs, + # create a symlink to the real copy of the dylib. + resource_path = self.dst_path_of(os.path.join(app, "Contents", "Resources")) + for libfile in dylibs: + symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, libfile), + os.path.join(resource_path, libfile)) # plugins if self.prefix(src="", dst="llplugin"): - 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("../packages/lib/release/libllqtwebkit.dylib", "libllqtwebkit.dylib") + self.path2basename("../media_plugins/quicktime/" + self.args['configuration'], + "media_plugin_quicktime.dylib") + self.path2basename("../media_plugins/webkit/" + self.args['configuration'], + "media_plugin_webkit.dylib") + self.path2basename("../packages/lib/release", "libllqtwebkit.dylib") self.end_prefix("llplugin") @@ -817,6 +814,30 @@ class DarwinManifest(ViewerManifest): self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script)) def package_finish(self): + # Sign the app if requested. + if 'signature' in self.args: + identity = self.args['signature'] + if identity == '': + identity = 'Developer ID Application' + + # Look for an environment variable set via build.sh when running in Team City. + try: + build_secrets_checkout = os.environ['build_secrets_checkout'] + except KeyError: + pass + else: + # variable found so use it to unlock keyvchain followed by codesign + home_path = os.environ['HOME'] + keychain_pwd_path = os.path.join(build_secrets_checkout,'code-signing-osx','password.txt') + keychain_pwd = open(keychain_pwd_path).read().rstrip() + + self.run_command('security unlock-keychain -p "%s" "%s/Library/Keychains/viewer.keychain"' % ( keychain_pwd, home_path ) ) + self.run_command('codesign --verbose --force --keychain "%(home_path)s/Library/Keychains/viewer.keychain" --sign %(identity)r %(bundle)r' % { + 'home_path' : home_path, + 'identity': identity, + 'bundle': self.get_dst_prefix() + }) + channel_standin = 'Second Life Viewer' # hah, our default channel is not usable on its own if not self.default_channel(): channel_standin = self.channel() @@ -932,20 +953,25 @@ class LinuxManifest(ViewerManifest): 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") + if self.prefix(src="", dst="etc"): + self.path("handle_secondlifeprotocol.sh") + self.path("register_secondlifeprotocol.sh") + self.path("refresh_desktop_app_entry.sh") + self.path("launch_url.sh") + self.end_prefix("etc") 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') - self.path("secondlife-bin","bin/do-not-directly-run-secondlife-bin") - self.path("../linux_crash_logger/linux-crash-logger","bin/linux-crash-logger.bin") - self.path("../linux_updater/linux-updater", "bin/linux-updater.bin") - self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin") + if self.prefix(src="", dst="bin"): + self.path("secondlife-bin","do-not-directly-run-secondlife-bin") + self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") + self.path("../linux_updater/linux-updater", "linux-updater.bin") + self.path2basename("../llplugin/slplugin", "SLPlugin") + self.path2basename("../viewer_components/updater/scripts/linux", "update_install") + self.end_prefix("bin") if self.prefix("res-sdl"): self.path("*") @@ -961,17 +987,13 @@ class LinuxManifest(ViewerManifest): self.end_prefix("res-sdl") self.end_prefix(icon_path) - self.path("../viewer_components/updater/scripts/linux/update_install", "bin/update_install") - # plugins if self.prefix(src="", dst="bin/llplugin"): - self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so") + self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so") self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") self.end_prefix("bin/llplugin") - try: - self.path("../llcommon/libllcommon.so", "lib/libllcommon.so") - except: + if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"): print "Skipping llcommon.so (assuming llcommon was linked statically)" self.path("featuretable_linux.txt") @@ -1037,9 +1059,21 @@ class Linux_i686Manifest(LinuxManifest): super(Linux_i686Manifest, self).construct() if self.prefix("../packages/lib/release", dst="lib"): - self.path("libapr-1.so*") - self.path("libaprutil-1.so*") - self.path("libbreakpad_client.so*") + self.path("libapr-1.so") + self.path("libapr-1.so.0") + self.path("libapr-1.so.0.4.5") + self.path("libaprutil-1.so") + self.path("libaprutil-1.so.0") + self.path("libaprutil-1.so.0.4.1") + self.path("libboost_program_options-mt.so.1.48.0") + self.path("libboost_regex-mt.so.1.48.0") + self.path("libboost_thread-mt.so.1.48.0") + self.path("libboost_filesystem-mt.so.1.48.0") + self.path("libboost_signals-mt.so.1.48.0") + self.path("libboost_system-mt.so.1.48.0") + self.path("libbreakpad_client.so.0.0.0") + self.path("libbreakpad_client.so.0") + self.path("libbreakpad_client.so") self.path("libcollada14dom.so") self.path("libdb*.so") self.path("libcrypto.so.*") @@ -1055,11 +1089,8 @@ class Linux_i686Manifest(LinuxManifest): self.path("libopenjpeg.so*") self.path("libdirectfb-1.4.so.5") self.path("libfusion-1.4.so.5") - self.path("libdirect-1.4.so.5.0.4") - self.path("libdirect-1.4.so.5") - self.path("libhunspell-1.3.so") - self.path("libhunspell-1.3.so.0") - self.path("libhunspell-1.3.so.0.0.0") + self.path("libdirect-1.4.so.5*") + self.path("libhunspell-1.3.so*") self.path("libalut.so") self.path("libopenal.so", "libopenal.so.1") self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname @@ -1122,5 +1153,25 @@ class Linux_x86_64Manifest(LinuxManifest): ################################################################ +def symlinkf(src, dst): + """ + Like ln -sf, but uses os.symlink() instead of running ln. + """ + try: + os.symlink(src, dst) + except OSError, err: + if err.errno != errno.EEXIST: + raise + # We could just blithely attempt to remove and recreate the target + # file, but that strategy doesn't work so well if we don't have + # permissions to remove it. Check to see if it's already the + # symlink we want, which is the usual reason for EEXIST. + if not (os.path.islink(dst) and os.readlink(dst) == src): + # Here either dst isn't a symlink or it's the wrong symlink. + # Remove and recreate. Caller will just have to deal with any + # exceptions at this stage. + os.remove(dst) + os.symlink(src, dst) + if __name__ == "__main__": main() diff --git a/indra/test/lluuidhashmap_tut.cpp b/indra/test/lluuidhashmap_tut.cpp index 0544e832ce..408bc3faf1 100644 --- a/indra/test/lluuidhashmap_tut.cpp +++ b/indra/test/lluuidhashmap_tut.cpp @@ -30,6 +30,10 @@ #include "linden_common.h" #include "lluuidhashmap.h" #include "llsdserialize.h" +#include "lldir.h" +#include "stringize.h" +#include <iostream> +#include <fstream> namespace tut { @@ -79,40 +83,133 @@ namespace tut template<> template<> void hash_index_object_t::test<1>() { - LLUUIDHashMap<UUIDTableEntry, 32> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); + set_test_name("stress test"); + // As of 2012-10-10, I (nat) have observed sporadic failures of this + // test: "set/get did not work." The trouble is that since test data + // are randomly generated with every run, it is impossible to debug a + // test failure. One is left with the uneasy suspicion that + // LLUUID::generate() can sometimes produce duplicates even within the + // moderately small number requested here. Since rerunning the test + // generally allows it to pass, it's too easy to shrug and forget it. + // The following code is intended to support reproducing such test + // failures. The idea is that, on test failure, we save the generated + // data to a canonical filename in a temp directory. Then on every + // subsequent run, we check for that filename. If it exists, we reload + // that specific data rather than generating fresh data -- which + // should presumably reproduce the same test failure. But we inform + // the user that to resume normal (random) test runs, s/he need only + // delete that file. And since it's in a temp directory, sooner or + // later the system will clean it up anyway. + const char* tempvar = "TEMP"; + const char* tempdir = getenv(tempvar); // Windows convention + if (! tempdir) + { + tempvar = "TMPDIR"; + tempdir = getenv(tempvar); // Mac convention + } + if (! tempdir) + { + // reset tempvar to the first var we check; it's just a + // recommendation + tempvar = "TEMP"; + tempdir = "/tmp"; // Posix in general + } + std::string savefile(gDirUtilp->add(tempdir, "lluuidhashmap_tut.save.txt")); const int numElementsToCheck = 32*256*32; - std::vector<LLUUID> idList(numElementsToCheck); - int i; - - for (i = 0; i < numElementsToCheck; i++) + std::vector<LLUUID> idList; + if (gDirUtilp->fileExists(savefile)) { - LLUUID id; - id.generate(); - UUIDTableEntry entry(id, i); - hashTable.set(id, entry); - idList[i] = id; + // We have saved data from a previous failed run. Reload that data. + std::ifstream inf(savefile.c_str()); + if (! inf.is_open()) + { + fail(STRINGIZE("Although save file '" << savefile << "' exists, it cannot be opened")); + } + std::string item; + while (std::getline(inf, item)) + { + idList.push_back(LLUUID(item)); + } + std::cout << "Reloaded " << idList.size() << " items from '" << savefile << "'"; + if (idList.size() != numElementsToCheck) + { + std::cout << " (expected " << numElementsToCheck << ")"; + } + std::cout << " -- delete this file to generate new data" << std::endl; + } + else + { + // savefile does not exist (normal case): regenerate idList from + // scratch. + for (int i = 0; i < numElementsToCheck; ++i) + { + LLUUID id; + id.generate(); + idList.push_back(id); + } } - for (i = 0; i < numElementsToCheck; i++) + LLUUIDHashMap<UUIDTableEntry, 32> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); + int i; + + for (i = 0; i < idList.size(); ++i) { - LLUUID idToCheck = idList[i]; - UUIDTableEntry entryToCheck = hashTable.get(idToCheck); - ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i); + UUIDTableEntry entry(idList[i], i); + hashTable.set(idList[i], entry); } - for (i = 0; i < numElementsToCheck; i++) + try { - LLUUID idToCheck = idList[i]; - if (i % 2 != 0) + for (i = 0; i < idList.size(); i++) { - hashTable.remove(idToCheck); + LLUUID idToCheck = idList[i]; + UUIDTableEntry entryToCheck = hashTable.get(idToCheck); + ensure_equals(STRINGIZE("set/get ID (entry " << i << ")").c_str(), + entryToCheck.getID(), idToCheck); + ensure_equals(STRINGIZE("set/get value (ID " << idToCheck << ")").c_str(), + entryToCheck.getValue(), (size_t)i); } - } - for (i = 0; i < numElementsToCheck; i++) + for (i = 0; i < idList.size(); i++) + { + LLUUID idToCheck = idList[i]; + if (i % 2 != 0) + { + hashTable.remove(idToCheck); + } + } + + for (i = 0; i < idList.size(); i++) + { + LLUUID idToCheck = idList[i]; + ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck))); + } + } + catch (const failure&) { - LLUUID idToCheck = idList[i]; - ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck))); + // One of the above tests failed. Try to save idList to repro with + // a later run. + std::ofstream outf(savefile.c_str()); + if (! outf.is_open()) + { + // Sigh, don't use fail() here because we want to preserve + // the original test failure. + std::cout << "Cannot open file '" << savefile + << "' to save data -- check and fix " << tempvar << std::endl; + } + else + { + // outf.is_open() + for (int i = 0; i < idList.size(); ++i) + { + outf << idList[i] << std::endl; + } + std::cout << "Saved " << idList.size() << " entries to '" << savefile + << "' -- rerun test to debug with these" << std::endl; + } + // re-raise the same exception -- we WANT this test failure to + // be reported! We just needed to save the data on the way out. + throw; } } diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index d480b63094..bdcb068200 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -271,6 +271,16 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para } return; // Done! } + + /* Sometimes we end with "Started" here. Slightly slow server? + * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. + */ + if( status == "Started") + { + LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; + continue; + } + // If we don't recognize status at all, trouble if (! (status == "CURLError" || status == "XMLRPCError" diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index f0d3fcbd07..a49bc4161e 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -78,7 +78,9 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, void LLDir::setChatLogsDir(const std::string &path){} void LLDir::setPerAccountChatLogsDir(const std::string &username){} void LLDir::setLindenUserDir(const std::string &username){} -void LLDir::setSkinFolder(const std::string &skin_folder){} +void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language){} +std::string LLDir::getSkinFolder() const { return "default"; } +std::string LLDir::getLanguage() const { return "en"; } bool LLDir::setCacheDir(const std::string &path){ return true; } void LLDir::dumpCurrentDirectories() {} |