diff options
| author | Erik Kundiman <erik@megapahit.org> | 2025-04-19 21:14:33 +0800 | 
|---|---|---|
| committer | Erik Kundiman <erik@megapahit.org> | 2025-04-19 21:14:33 +0800 | 
| commit | 9595a3dee48eb8b7f10cad02b4ebdda5f596664e (patch) | |
| tree | aadbfc379b2028e1f22662d38b1094c745064ad9 /indra/newview | |
| parent | ad9c801edb13568657c0964ebfb74257da6d9e00 (diff) | |
| parent | 9a333e65c4019540d5675e72ac57ef5ab106aab0 (diff) | |
Merge tag 'Second_Life_Release#9a333e65-2025.04' into 2025.04
Diffstat (limited to 'indra/newview')
127 files changed, 1907 insertions, 686 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 8d7f37142f..0f81c2b8ef 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -103,6 +103,7 @@ set(viewer_SOURCE_FILES      llagentwearables.cpp      llanimstatelabels.cpp      llappcorehttp.cpp +    llappearancelistener.cpp      llappearancemgr.cpp      llappviewer.cpp      llappviewerlistener.cpp @@ -778,6 +779,7 @@ set(viewer_HEADER_FILES      llanimstatelabels.h      llappcorehttp.h      llappearance.h +    llappearancelistener.h      llappearancemgr.h      llappviewer.h      llappviewerlistener.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f8487c020e..561957477e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -368,6 +368,17 @@        <key>Value</key>        <real>0.5</real>      </map> +    <key>AudioLevelWind</key> +    <map> +      <key>Comment</key> +      <string>Audio level of wind noise when standing still</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>0.5</real> +    </map>  	<key>AudioStreamingMedia</key>      <map>        <key>Comment</key> @@ -9628,6 +9639,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>RenderBalanceInSnapshot</key> +    <map> +      <key>Comment</key> +      <string>Display L$ balance in snapshot</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>RenderUIBuffer</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl index a63b8d7c2b..774ccb6baf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl @@ -117,27 +117,34 @@ uniform float exposure;  uniform float tonemap_mix;  uniform int tonemap_type; +  vec3 toneMap(vec3 color)  {  #ifndef NO_POST -    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - -    color *= exposure * exp_scale; +    vec3 linear_input_color = color; -    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); +    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; +    float final_exposure = exposure * exp_scale; +    vec3 exposed_color = color * final_exposure; +    vec3 tonemapped_color = exposed_color;      switch(tonemap_type)      {      case 0: -        color = PBRNeutralToneMapping(color); +        tonemapped_color = PBRNeutralToneMapping(exposed_color);          break;      case 1: -        color = toneMapACES_Hill(color); +        tonemapped_color = toneMapACES_Hill(exposed_color);          break;      } -    // mix tonemapped and linear here to provide adjustment -    color = mix(clamped_color, color, tonemap_mix); +    vec3 exposed_linear_input = linear_input_color * final_exposure; +    color = mix(exposed_linear_input, tonemapped_color, tonemap_mix); + +    color = clamp(color, 0.0, 1.0); +#else +    color *= exposure * texture(exposureMap, vec2(0.5,0.5)).r; +    color = clamp(color, 0.0, 1.0);  #endif      return color; @@ -147,20 +154,24 @@ vec3 toneMap(vec3 color)  vec3 toneMapNoExposure(vec3 color)  {  #ifndef NO_POST -    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); +    vec3 linear_input_color = color; +    vec3 tonemapped_color = color;      switch(tonemap_type)      {      case 0: -        color = PBRNeutralToneMapping(color); +        tonemapped_color = PBRNeutralToneMapping(color);          break;      case 1: -        color = toneMapACES_Hill(color); +        tonemapped_color = toneMapACES_Hill(color);          break;      } -    // mix tonemapped and linear here to provide adjustment -    color = mix(clamped_color, color, tonemap_mix); +    color = mix(linear_input_color, tonemapped_color, tonemap_mix); + +    color = clamp(color, 0.0, 1.0); +#else +     color = clamp(color, 0.0, 1.0);  #endif      return color; diff --git a/indra/newview/groupchatlistener.cpp b/indra/newview/groupchatlistener.cpp index 43507f13e9..ed9e34d1bf 100644 --- a/indra/newview/groupchatlistener.cpp +++ b/indra/newview/groupchatlistener.cpp @@ -2,11 +2,11 @@   * @file   groupchatlistener.cpp   * @author Nat Goodspeed   * @date   2011-04-11 - * @brief  Implementation for groupchatlistener. + * @brief  Implementation for LLGroupChatListener.   * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * $LicenseInfo:firstyear=2024&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. + * Copyright (C) 2024, 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 @@ -34,43 +34,69 @@  // std headers  // external library headers  // other Linden headers +#include "llchat.h"  #include "llgroupactions.h"  #include "llimview.h" +LLGroupChatListener::LLGroupChatListener(): +    LLEventAPI("GroupChat", +               "API to enter, leave, send and intercept group chat messages") +{ +    add("startGroupChat", +        "Enter a group chat in group with UUID [\"group_id\"]\n" +        "Assumes the logged-in agent is already a member of this group.", +        &LLGroupChatListener::startGroupChat, +        llsd::map("group_id", LLSD())); +    add("leaveGroupChat", +        "Leave a group chat in group with UUID [\"group_id\"]\n" +        "Assumes a prior successful startIM request.", +        &LLGroupChatListener::leaveGroupChat, +        llsd::map("group_id", LLSD())); +    add("sendGroupIM", +        "send a [\"message\"] to group with UUID [\"group_id\"]", +        &LLGroupChatListener::sendGroupIM, +        llsd::map("message", LLSD(), "group_id", LLSD())); +} -namespace { -    void startIm_wrapper(LLSD const & event) +bool is_in_group(LLEventAPI::Response &response, const LLSD &data) +{ +    if (!LLGroupActions::isInGroup(data["group_id"]))      { -        LLUUID session_id = LLGroupActions::startIM(event["id"].asUUID()); -        sendReply(LLSDMap("session_id", LLSD(session_id)), event); +        response.error(stringize("You are not the member of the group:", std::quoted(data["group_id"].asString()))); +        return false;      } +    return true; +} -    void send_message_wrapper(const std::string& text, const LLUUID& session_id, const LLUUID& group_id) +void LLGroupChatListener::startGroupChat(LLSD const &data) +{ +    Response response(LLSD(), data); +    if (!is_in_group(response, data)) +    { +        return; +    } +    if (LLGroupActions::startIM(data["group_id"]).isNull())      { -        LLIMModel::sendMessage(text, session_id, group_id, IM_SESSION_GROUP_START); +        return response.error(stringize("Failed to start group chat session ", std::quoted(data["group_id"].asString())));      }  } +void LLGroupChatListener::leaveGroupChat(LLSD const &data) +{ +    Response response(LLSD(), data); +    if (is_in_group(response, data)) +    { +        LLGroupActions::endIM(data["group_id"].asUUID()); +    } +} -GroupChatListener::GroupChatListener(): -    LLEventAPI("GroupChat", -               "API to enter, leave, send and intercept group chat messages") +void LLGroupChatListener::sendGroupIM(LLSD const &data)  { -    add("startIM", -        "Enter a group chat in group with UUID [\"id\"]\n" -        "Assumes the logged-in agent is already a member of this group.", -        &startIm_wrapper); -    add("endIM", -        "Leave a group chat in group with UUID [\"id\"]\n" -        "Assumes a prior successful startIM request.", -        &LLGroupActions::endIM, -        llsd::array("id")); -    add("sendIM", -        "send a groupchat IM", -        &send_message_wrapper, -        llsd::array("text", "session_id", "group_id")); +    Response response(LLSD(), data); +    if (!is_in_group(response, data)) +    { +        return; +    } +    LLUUID group_id(data["group_id"]); +    LLIMModel::sendMessage(data["message"], gIMMgr->computeSessionID(IM_SESSION_GROUP_START, group_id), group_id, IM_SESSION_SEND);  } -/* -    static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, -                                const LLUUID& other_participant_id, EInstantMessage dialog); -*/ diff --git a/indra/newview/groupchatlistener.h b/indra/newview/groupchatlistener.h index 3819ac59b7..14cd7266a3 100644 --- a/indra/newview/groupchatlistener.h +++ b/indra/newview/groupchatlistener.h @@ -26,15 +26,20 @@   * $/LicenseInfo$   */ -#if ! defined(LL_GROUPCHATLISTENER_H) -#define LL_GROUPCHATLISTENER_H +#if ! defined(LL_LLGROUPCHATLISTENER_H) +#define LL_LLGROUPCHATLISTENER_H  #include "lleventapi.h" -class GroupChatListener: public LLEventAPI +class LLGroupChatListener: public LLEventAPI  {  public: -    GroupChatListener(); +    LLGroupChatListener(); + +private: +    void startGroupChat(LLSD const &data); +    void leaveGroupChat(LLSD const &data); +    void sendGroupIM(LLSD const &data);  }; -#endif /* ! defined(LL_GROUPCHATLISTENER_H) */ +#endif /* ! defined(LL_LLGROUPCHATLISTENER_H) */ diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 0c120ae01d..5ddb87558a 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -31,19 +31,25 @@  #include "llagentlistener.h"  #include "llagent.h" +#include "llagentcamera.h" +#include "llavatarname.h" +#include "llavatarnamecache.h"  #include "llvoavatar.h"  #include "llcommandhandler.h" +#include "llinventorymodel.h"  #include "llslurl.h"  #include "llurldispatcher.h" +#include "llviewercontrol.h"  #include "llviewernetwork.h"  #include "llviewerobject.h"  #include "llviewerobjectlist.h"  #include "llviewerregion.h" +#include "llvoavatarself.h"  #include "llsdutil.h"  #include "llsdutil_math.h"  #include "lltoolgrab.h"  #include "llhudeffectlookat.h" -#include "llagentcamera.h" +#include "llviewercamera.h"  LLAgentListener::LLAgentListener(LLAgent &agent)    : LLEventAPI("LLAgent", @@ -69,13 +75,6 @@ LLAgentListener::LLAgentListener(LLAgent &agent)      add("resetAxes",          "Set the agent to a fixed orientation (optionally specify [\"lookat\"] = array of [x, y, z])",          &LLAgentListener::resetAxes); -    add("getAxes", -        "Obsolete - use getPosition instead\n" -        "Send information about the agent's orientation on [\"reply\"]:\n" -        "[\"euler\"]: map of {roll, pitch, yaw}\n" -        "[\"quat\"]:  array of [x, y, z, w] quaternion values", -        &LLAgentListener::getAxes, -        LLSDMap("reply", LLSD()));      add("getPosition",          "Send information about the agent's position and orientation on [\"reply\"]:\n"          "[\"region\"]: array of region {x, y, z} position\n" @@ -87,33 +86,34 @@ LLAgentListener::LLAgentListener(LLAgent &agent)      add("startAutoPilot",          "Start the autopilot system using the following parameters:\n"          "[\"target_global\"]: array of target global {x, y, z} position\n" -        "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]\n" +        "[\"stop_distance\"]: maximum stop distance from target [default: autopilot guess]\n"          "[\"target_rotation\"]: array of [x, y, z, w] quaternion values [default: no target]\n"          "[\"rotation_threshold\"]: target maximum angle from target facing rotation [default: 0.03 radians]\n" -        "[\"behavior_name\"]: name of the autopilot behavior [default: \"\"]" -        "[\"allow_flying\"]: allow flying during autopilot [default: True]", -        //"[\"callback_pump\"]: pump to send success/failure and callback data to [default: none]\n" -        //"[\"callback_data\"]: data to send back during a callback [default: none]", -        &LLAgentListener::startAutoPilot); +        "[\"behavior_name\"]: name of the autopilot behavior [default: \"\"]\n" +        "[\"allow_flying\"]: allow flying during autopilot [default: True]\n" +        "event with [\"success\"] flag is sent to 'LLAutopilot' event pump, when auto pilot is terminated", +        &LLAgentListener::startAutoPilot, +        llsd::map("target_global", LLSD()));      add("getAutoPilot",          "Send information about current state of the autopilot system to [\"reply\"]:\n"          "[\"enabled\"]: boolean indicating whether or not autopilot is enabled\n"          "[\"target_global\"]: array of target global {x, y, z} position\n"          "[\"leader_id\"]: uuid of target autopilot is following\n" -        "[\"stop_distance\"]: target maximum distance from target\n" +        "[\"stop_distance\"]: maximum stop distance from target\n"          "[\"target_distance\"]: last known distance from target\n"          "[\"use_rotation\"]: boolean indicating if autopilot has a target facing rotation\n"          "[\"target_facing\"]: array of {x, y} target direction to face\n"          "[\"rotation_threshold\"]: target maximum angle from target facing rotation\n"          "[\"behavior_name\"]: name of the autopilot behavior",          &LLAgentListener::getAutoPilot, -        LLSDMap("reply", LLSD())); +        llsd::map("reply", LLSD()));      add("startFollowPilot",          "[\"leader_id\"]: uuid of target to follow using the autopilot system (optional with avatar_name)\n"          "[\"avatar_name\"]: avatar name to follow using the autopilot system (optional with leader_id)\n"          "[\"allow_flying\"]: allow flying during autopilot [default: True]\n" -        "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]", -        &LLAgentListener::startFollowPilot); +        "[\"stop_distance\"]: maximum stop distance from target [default: autopilot guess]", +        &LLAgentListener::startFollowPilot, +        llsd::map("reply", LLSD()));      add("setAutoPilotTarget",          "Update target for currently running autopilot:\n"          "[\"target_global\"]: array of target global {x, y, z} position", @@ -138,6 +138,69 @@ LLAgentListener::LLAgentListener(LLAgent &agent)          "[\"contrib\"]: user's land contribution to this group\n",          &LLAgentListener::getGroups,          LLSDMap("reply", LLSD())); +    //camera params are similar to LSL, see https://wiki.secondlife.com/wiki/LlSetCameraParams +    add("setCameraParams", +        "Set Follow camera params, and then activate it:\n" +        "[\"camera_pos\"]: vector3, camera position in region coordinates\n" +        "[\"focus_pos\"]: vector3, what the camera is aimed at (in region coordinates)\n" +        "[\"focus_offset\"]: vector3, adjusts the camera focus position relative to the target, default is (1, 0, 0)\n" +        "[\"distance\"]: float (meters), distance the camera wants to be from its target, default is 3\n" +        "[\"focus_threshold\"]: float (meters), sets the radius of a sphere around the camera's target position within which its focus is not affected by target motion, default is 1\n" +        "[\"camera_threshold\"]: float (meters), sets the radius of a sphere around the camera's ideal position within which it is not affected by target motion, default is 1\n" +        "[\"focus_lag\"]: float (seconds), how much the camera lags as it tries to aim towards the target, default is 0.1\n" +        "[\"camera_lag\"]: float (seconds), how much the camera lags as it tries to move towards its 'ideal' position, default is 0.1\n" +        "[\"camera_pitch\"]: float (degrees), adjusts the angular amount that the camera aims straight ahead vs. straight down, maintaining the same distance, default is 0\n" +        "[\"behindness_angle\"]: float (degrees), sets the angle in degrees within which the camera is not constrained by changes in target rotation, default is 10\n" +        "[\"behindness_lag\"]: float (seconds), sets how strongly the camera is forced to stay behind the target if outside of behindness angle, default is 0\n" +        "[\"camera_locked\"]: bool, locks the camera position so it will not move\n" +        "[\"focus_locked\"]: bool, locks the camera focus so it will not move", +        &LLAgentListener::setFollowCamParams); +    add("setFollowCamActive", +        "Turns on or off scripted control of the camera using boolean [\"active\"]", +        &LLAgentListener::setFollowCamActive, +        llsd::map("active", LLSD())); +    add("removeCameraParams", +        "Reset Follow camera params", +        &LLAgentListener::removeFollowCamParams); + +    add("playAnimation", +        "Play [\"item_id\"] animation locally (by default) or [\"inworld\"] (when set to true)", +        &LLAgentListener::playAnimation, +        llsd::map("item_id", LLSD(), "reply", LLSD())); +    add("stopAnimation", +        "Stop playing [\"item_id\"] animation", +        &LLAgentListener::stopAnimation, +        llsd::map("item_id", LLSD(), "reply", LLSD())); +    add("getAnimationInfo", +        "Return information about [\"item_id\"] animation", +        &LLAgentListener::getAnimationInfo, +        llsd::map("item_id", LLSD(), "reply", LLSD())); + +    add("getID", +        "Return your own avatar ID", +        &LLAgentListener::getID, +        llsd::map("reply", LLSD())); + +    add("getNearbyAvatarsList", +        "Return result set key [\"result\"] for nearby avatars in a range of [\"dist\"]\n" +        "if [\"dist\"] is not specified, 'RenderFarClip' setting is used\n" +        "reply contains \"result\" table with \"id\", \"name\", \"global_pos\", \"region_pos\", \"region_id\" fields", +        &LLAgentListener::getNearbyAvatarsList, +        llsd::map("reply", LLSD())); + +    add("getNearbyObjectsList", +        "Return result set key [\"result\"] for nearby objects in a range of [\"dist\"]\n" +        "if [\"dist\"] is not specified, 'RenderFarClip' setting is used\n" +        "reply contains \"result\" table with \"id\", \"global_pos\", \"region_pos\", \"region_id\" fields", +        &LLAgentListener::getNearbyObjectsList, +        llsd::map("reply", LLSD())); + +    add("getAgentScreenPos", +        "Return screen position of the [\"avatar_id\"] avatar or own avatar if not specified\n" +        "reply contains \"x\", \"y\" coordinates and \"onscreen\" flag to indicate if it's actually in within the current window\n" +        "avatar render position is used as the point", +        &LLAgentListener::getAgentScreenPos, +        llsd::map("reply", LLSD()));  }  void LLAgentListener::requestTeleport(LLSD const & event_data) const @@ -168,7 +231,7 @@ void LLAgentListener::requestSit(LLSD const & event_data) const      //mAgent.getAvatarObject()->sitOnObject();      // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand()      // *TODO - find a permanent place to share this code properly. - +    Response response(LLSD(), event_data);      LLViewerObject *object = NULL;      if (event_data.has("obj_uuid"))      { @@ -177,7 +240,13 @@ void LLAgentListener::requestSit(LLSD const & event_data) const      else if (event_data.has("position"))      {          LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); -        object = findObjectClosestTo(target_position); +        object = findObjectClosestTo(target_position, true); +    } +    else +    { +        //just sit on the ground +        mAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); +        return;      }      if (object && object->getPCode() == LL_PCODE_VOLUME) @@ -194,8 +263,7 @@ void LLAgentListener::requestSit(LLSD const & event_data) const      }      else      { -        LL_WARNS() << "LLAgent requestSit could not find the sit target: " -            << event_data << LL_ENDL; +        response.error("requestSit could not find the sit target");      }  } @@ -205,7 +273,7 @@ void LLAgentListener::requestStand(LLSD const & event_data) const  } -LLViewerObject * LLAgentListener::findObjectClosestTo( const LLVector3 & position ) const +LLViewerObject * LLAgentListener::findObjectClosestTo(const LLVector3 & position, bool sit_target) const  {      LLViewerObject *object = NULL; @@ -216,8 +284,13 @@ LLViewerObject * LLAgentListener::findObjectClosestTo( const LLVector3 & positio      while (cur_index < num_objects)      {          LLViewerObject * cur_object = gObjectList.getObject(cur_index++); -        if (cur_object) -        {   // Calculate distance from the target position +        if (cur_object && !cur_object->isAttachment()) +        { +            if(sit_target && (cur_object->getPCode() != LL_PCODE_VOLUME)) +            { +                continue; +            } +            // Calculate distance from the target position              LLVector3 target_diff = cur_object->getPositionRegion() - position;              F32 distance_to_target = target_diff.length();              if (distance_to_target < min_distance) @@ -296,22 +369,6 @@ void LLAgentListener::resetAxes(const LLSD& event_data) const      }  } -void LLAgentListener::getAxes(const LLSD& event_data) const -{ -    LLQuaternion quat(mAgent.getQuat()); -    F32 roll, pitch, yaw; -    quat.getEulerAngles(&roll, &pitch, &yaw); -    // The official query API for LLQuaternion's [x, y, z, w] values is its -    // public member mQ... -    LLSD reply = LLSD::emptyMap(); -    reply["quat"] = llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ)); -    reply["euler"] = LLSD::emptyMap(); -    reply["euler"]["roll"] = roll; -    reply["euler"]["pitch"] = pitch; -    reply["euler"]["yaw"] = yaw; -    sendReply(reply, event_data); -} -  void LLAgentListener::getPosition(const LLSD& event_data) const  {      F32 roll, pitch, yaw; @@ -333,14 +390,13 @@ void LLAgentListener::getPosition(const LLSD& event_data) const  void LLAgentListener::startAutoPilot(LLSD const & event_data)  { -    LLQuaternion target_rotation_value;      LLQuaternion* target_rotation = NULL;      if (event_data.has("target_rotation"))      { -        target_rotation_value = ll_quaternion_from_sd(event_data["target_rotation"]); +        LLQuaternion target_rotation_value = ll_quaternion_from_sd(event_data["target_rotation"]);          target_rotation = &target_rotation_value;      } -    // *TODO: Use callback_pump and callback_data +      F32 rotation_threshold = 0.03f;      if (event_data.has("rotation_threshold"))      { @@ -360,13 +416,24 @@ void LLAgentListener::startAutoPilot(LLSD const & event_data)          stop_distance = (F32)event_data["stop_distance"].asReal();      } +    std::string behavior_name = LLCoros::getName(); +    if (event_data.has("behavior_name")) +    { +        behavior_name = event_data["behavior_name"].asString(); +    } +      // Clear follow target, this is doing a path      mFollowTarget.setNull(); +    auto finish_cb = [](bool success, void*) +    { +        LLEventPumps::instance().obtain("LLAutopilot").post(llsd::map("success", success)); +    }; +      mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event_data["target_global"]), -                                event_data["behavior_name"], +                                behavior_name,                                  target_rotation, -                                NULL, NULL, +                                finish_cb, NULL,                                  stop_distance,                                  rotation_threshold,                                  allow_flying); @@ -374,7 +441,7 @@ void LLAgentListener::startAutoPilot(LLSD const & event_data)  void LLAgentListener::getAutoPilot(const LLSD& event_data) const  { -    LLSD reply = LLSD::emptyMap(); +    Response reply(LLSD(), event_data);      LLSD::Boolean enabled = mAgent.getAutoPilot();      reply["enabled"] = enabled; @@ -403,12 +470,11 @@ void LLAgentListener::getAutoPilot(const LLSD& event_data) const      reply["rotation_threshold"] = mAgent.getAutoPilotRotationThreshold();      reply["behavior_name"] = mAgent.getAutoPilotBehaviorName();      reply["fly"] = (LLSD::Boolean) mAgent.getFlying(); - -    sendReply(reply, event_data);  }  void LLAgentListener::startFollowPilot(LLSD const & event_data)  { +    Response response(LLSD(), event_data);      LLUUID target_id;      bool allow_flying = true; @@ -442,6 +508,10 @@ void LLAgentListener::startFollowPilot(LLSD const & event_data)              }          }      } +    else +    { +        return response.error("'leader_id' or 'avatar_name' should be specified"); +    }      F32 stop_distance = 0.f;      if (event_data.has("stop_distance")) @@ -449,13 +519,16 @@ void LLAgentListener::startFollowPilot(LLSD const & event_data)          stop_distance = (F32)event_data["stop_distance"].asReal();      } -    if (target_id.notNull()) +    if (!gObjectList.findObject(target_id))      { -        mAgent.setFlying(allow_flying); -        mFollowTarget = target_id;  // Save follow target so we can report distance later - -        mAgent.startFollowPilot(target_id, allow_flying, stop_distance); +        std::string target_info = event_data.has("leader_id") ? event_data["leader_id"] : event_data["avatar_name"]; +        return response.error(stringize("Target ", std::quoted(target_info), " was not found"));      } + +    mAgent.setFlying(allow_flying); +    mFollowTarget = target_id;  // Save follow target so we can report distance later + +    mAgent.startFollowPilot(target_id, allow_flying, stop_distance);  }  void LLAgentListener::setAutoPilotTarget(LLSD const & event_data) const @@ -519,3 +592,209 @@ void LLAgentListener::getGroups(const LLSD& event) const      }      sendReply(LLSDMap("groups", reply), event);  } + +/*----------------------------- camera control -----------------------------*/ +// specialize LLSDParam to support (const LLVector3&) arguments -- this +// wouldn't even be necessary except that the relevant LLVector3 constructor +// is explicitly explicit +template <> +class LLSDParam<const LLVector3&>: public LLSDParamBase +{ +public: +    LLSDParam(const LLSD& value): value(LLVector3(value)) {} + +    operator const LLVector3&() const { return value; } + +private: +    LLVector3 value; +}; + +// accept any of a number of similar LLFollowCamMgr methods with different +// argument types, and return a wrapper lambda that accepts LLSD and converts +// to the target argument type +template <typename T> +auto wrap(void (LLFollowCamMgr::*method)(const LLUUID& source, T arg)) +{ +    return [method](LLFollowCamMgr& followcam, const LLUUID& source, const LLSD& arg) +    { (followcam.*method)(source, LLSDParam<T>(arg)); }; +} + +// table of supported LLFollowCamMgr methods, +// with the corresponding setFollowCamParams() argument keys +static std::pair<std::string, std::function<void(LLFollowCamMgr&, const LLUUID&, const LLSD&)>> +cam_params[] = +{ +    { "camera_pos",       wrap(&LLFollowCamMgr::setPosition) }, +    { "focus_pos",        wrap(&LLFollowCamMgr::setFocus) }, +    { "focus_offset",     wrap(&LLFollowCamMgr::setFocusOffset) }, +    { "camera_locked",    wrap(&LLFollowCamMgr::setPositionLocked) }, +    { "focus_locked",     wrap(&LLFollowCamMgr::setFocusLocked) }, +    { "distance",         wrap(&LLFollowCamMgr::setDistance) }, +    { "focus_threshold",  wrap(&LLFollowCamMgr::setFocusThreshold) }, +    { "camera_threshold", wrap(&LLFollowCamMgr::setPositionThreshold) }, +    { "focus_lag",        wrap(&LLFollowCamMgr::setFocusLag) }, +    { "camera_lag",       wrap(&LLFollowCamMgr::setPositionLag) }, +    { "camera_pitch",     wrap(&LLFollowCamMgr::setPitch) }, +    { "behindness_lag",   wrap(&LLFollowCamMgr::setBehindnessLag) }, +    { "behindness_angle", wrap(&LLFollowCamMgr::setBehindnessAngle) }, +}; + +void LLAgentListener::setFollowCamParams(const LLSD& event) const +{ +    auto& followcam{ LLFollowCamMgr::instance() }; +    for (const auto& pair : cam_params) +    { +        if (event.has(pair.first)) +        { +            pair.second(followcam, gAgentID, event[pair.first]); +        } +    } +    followcam.setCameraActive(gAgentID, true); +} + +void LLAgentListener::setFollowCamActive(LLSD const & event) const +{ +    LLFollowCamMgr::getInstance()->setCameraActive(gAgentID, event["active"]); +} + +void LLAgentListener::removeFollowCamParams(LLSD const & event) const +{ +    LLFollowCamMgr::getInstance()->removeFollowCamParams(gAgentID); +} + +LLViewerInventoryItem* get_anim_item(LLEventAPI::Response &response, const LLSD &event_data) +{ +    LLViewerInventoryItem* item = gInventory.getItem(event_data["item_id"].asUUID()); +    if (!item || (item->getInventoryType() != LLInventoryType::IT_ANIMATION)) +    { +        response.error(stringize("Animation item ", std::quoted(event_data["item_id"].asString()), " was not found")); +        return NULL; +    } +    return item; +} + +void LLAgentListener::playAnimation(LLSD const &event_data) +{ +    Response response(LLSD(), event_data); +    if (LLViewerInventoryItem* item = get_anim_item(response, event_data)) +    { +        if (event_data["inworld"].asBoolean()) +        { +            mAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_START); +        } +        else +        { +            gAgentAvatarp->startMotion(item->getAssetUUID()); +        } +    } +} + +void LLAgentListener::stopAnimation(LLSD const &event_data) +{ +    Response response(LLSD(), event_data); +    if (LLViewerInventoryItem* item = get_anim_item(response, event_data)) +    { +        gAgentAvatarp->stopMotion(item->getAssetUUID()); +        mAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP); +    } +} + +void LLAgentListener::getAnimationInfo(LLSD const &event_data) +{ +    Response response(LLSD(), event_data); +    if (LLViewerInventoryItem* item = get_anim_item(response, event_data)) +    { +        // if motion exists, will return existing one +        LLMotion* motion = gAgentAvatarp->createMotion(item->getAssetUUID()); +        response["anim_info"] = llsd::map("duration", motion->getDuration(), +                                               "is_loop", motion->getLoop(), +                                               "num_joints", motion->getNumJointMotions(), +                                               "asset_id", item->getAssetUUID(), +                                               "priority", motion->getPriority()); +    } +} + +void LLAgentListener::getID(LLSD const& event_data) +{ +    Response response(llsd::map("id", gAgentID), event_data); +} + +F32 get_search_radius(LLSD const& event_data) +{ +    static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); +    F32 dist = render_far_clip; +    if (event_data.has("dist")) +    { +        dist = llclamp((F32)event_data["dist"].asReal(), 1, 512); +    } +   return dist * dist; +} + +void LLAgentListener::getNearbyAvatarsList(LLSD const& event_data) +{ +    Response response(LLSD(), event_data); +    F32 radius = get_search_radius(event_data); +    LLVector3d agent_pos = gAgent.getPositionGlobal(); +    for (LLCharacter* character : LLCharacter::sInstances) +    { +        LLVOAvatar* avatar = (LLVOAvatar*)character; +        if (avatar && !avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf()) +        { +            if ((dist_vec_squared(avatar->getPositionGlobal(), agent_pos) <= radius)) +            { +                LLAvatarName av_name; +                LLAvatarNameCache::get(avatar->getID(), &av_name); +                LLVector3 region_pos = avatar->getCharacterPosition(); +                response["result"].append(llsd::map("id", avatar->getID(), "global_pos", ll_sd_from_vector3d(avatar->getPosGlobalFromAgent(region_pos)), +                                                    "region_pos", ll_sd_from_vector3(region_pos), "name", av_name.getUserName(), "region_id", avatar->getRegion()->getRegionID())); +            } +        } +    } +} + +void LLAgentListener::getNearbyObjectsList(LLSD const& event_data) +{ +    Response response(LLSD(), event_data); +    F32 radius = get_search_radius(event_data); +    S32 num_objects = gObjectList.getNumObjects(); +    LLVector3d agent_pos = gAgent.getPositionGlobal(); +    for (S32 i = 0; i < num_objects; ++i) +    { +        LLViewerObject* object = gObjectList.getObject(i); +        if (object && object->getVolume() && !object->isAttachment()) +        { +            if ((dist_vec_squared(object->getPositionGlobal(), agent_pos) <= radius)) +            { +                response["result"].append(llsd::map("id", object->getID(), "global_pos", ll_sd_from_vector3d(object->getPositionGlobal()), "region_pos", +                          ll_sd_from_vector3(object->getPositionRegion()), "region_id", object->getRegion()->getRegionID())); +            } +        } +    } +} + +void LLAgentListener::getAgentScreenPos(LLSD const& event_data) +{ +    Response response(LLSD(), event_data); +    LLVector3 render_pos; +    if (event_data.has("avatar_id") && (event_data["avatar_id"].asUUID() != gAgentID)) +    { +        LLUUID avatar_id(event_data["avatar_id"]); +        for (LLCharacter* character : LLCharacter::sInstances) +        { +            LLVOAvatar* avatar = (LLVOAvatar*)character; +            if (!avatar->isDead() && (avatar->getID() == avatar_id)) +            { +                render_pos = avatar->getRenderPosition(); +                break; +            } +        } +    } +    else if (gAgentAvatarp.notNull() && gAgentAvatarp->isValid()) +    { +        render_pos = gAgentAvatarp->getRenderPosition(); +    } +    LLCoordGL screen_pos; +    response["onscreen"] = LLViewerCamera::getInstance()->projectPosAgentToScreen(render_pos, screen_pos, false); +    response["x"] = screen_pos.mX; +    response["y"] = screen_pos.mY; +} diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index c544d089ce..b5bea8c0bd 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -48,7 +48,6 @@ private:      void requestStand(LLSD const & event_data) const;      void requestTouch(LLSD const & event_data) const;      void resetAxes(const LLSD& event_data) const; -    void getAxes(const LLSD& event_data) const;      void getGroups(const LLSD& event) const;      void getPosition(const LLSD& event_data) const;      void startAutoPilot(const LLSD& event_data); @@ -58,7 +57,20 @@ private:      void stopAutoPilot(const LLSD& event_data) const;      void lookAt(LLSD const & event_data) const; -    LLViewerObject * findObjectClosestTo( const LLVector3 & position ) const; +    void setFollowCamParams(LLSD const & event_data) const; +    void setFollowCamActive(LLSD const & event_data) const; +    void removeFollowCamParams(LLSD const & event_data) const; + +    void playAnimation(LLSD const &event_data); +    void stopAnimation(LLSD const &event_data); +    void getAnimationInfo(LLSD const &event_data); + +    void getID(LLSD const& event_data); +    void getNearbyAvatarsList(LLSD const& event_data); +    void getNearbyObjectsList(LLSD const& event_data); +    void getAgentScreenPos(LLSD const& event_data); + +    LLViewerObject * findObjectClosestTo( const LLVector3 & position, bool sit_target = false ) const;  private:      LLAgent &   mAgent; diff --git a/indra/newview/llappearancelistener.cpp b/indra/newview/llappearancelistener.cpp new file mode 100644 index 0000000000..dc7bbc3236 --- /dev/null +++ b/indra/newview/llappearancelistener.cpp @@ -0,0 +1,158 @@ +/** + * @file llappearancelistener.cpp + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, 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 "llappearancelistener.h" + +#include "llappearancemgr.h" +#include "llinventoryfunctions.h" +#include "lltransutil.h" +#include "llwearableitemslist.h" +#include "stringize.h" + +LLAppearanceListener::LLAppearanceListener() +  : LLEventAPI("LLAppearance", +               "API to wear a specified outfit and wear/remove individual items") +{ +    add("wearOutfit", +        "Wear outfit by folder id: [\"folder_id\"] OR by folder name: [\"folder_name\"]\n" +        "When [\"append\"] is true, outfit will be added to COF\n" +        "otherwise it will replace current oufit", +        &LLAppearanceListener::wearOutfit); + +    add("wearItems", +        "Wear items by id: [items_id]", +        &LLAppearanceListener::wearItems, +        llsd::map("items_id", LLSD(), "replace", LLSD())); + +    add("detachItems", +        "Detach items by id: [items_id]", +        &LLAppearanceListener::detachItems, +        llsd::map("items_id", LLSD())); + +    add("getOutfitsList", +        "Return the table with Outfits info(id and name)", +         &LLAppearanceListener::getOutfitsList); + +    add("getOutfitItems", +        "Return the table of items with info(id : name, wearable_type, is_worn) inside specified outfit folder", +         &LLAppearanceListener::getOutfitItems); +} + + +void LLAppearanceListener::wearOutfit(LLSD const &data) +{ +    Response response(LLSD(), data); +    if (!data.has("folder_id") && !data.has("folder_name")) +    { +        return response.error("Either [folder_id] or [folder_name] is required"); +    } + +    bool append = data.has("append") ? data["append"].asBoolean() : false; +    if (!LLAppearanceMgr::instance().wearOutfit(data, append)) +    { +        response.error("Failed to wear outfit"); +    } +} + +void LLAppearanceListener::wearItems(LLSD const &data) +{ +    const LLSD& items_id{ data["items_id"] }; +    uuid_vec_t  ids; +    if (!items_id.isArray()) +    { +        ids.push_back(items_id.asUUID()); +    } +    else // array +    { +        for (const auto& id : llsd::inArray(items_id)) +        { +            ids.push_back(id); +        } +    } +    LLAppearanceMgr::instance().wearItemsOnAvatar(ids, true, data["replace"].asBoolean()); +} + +void LLAppearanceListener::detachItems(LLSD const &data) +{ +    const LLSD& items_id{ data["items_id"] }; +    uuid_vec_t  ids; +    if (!items_id.isArray()) +    { +        ids.push_back(items_id.asUUID()); +    } +    else // array +    { +        for (const auto& id : llsd::inArray(items_id)) +        { +            ids.push_back(id); +        } +    } +    LLAppearanceMgr::instance().removeItemsFromAvatar(ids); +} + +void LLAppearanceListener::getOutfitsList(LLSD const &data) +{ +    Response response(LLSD(), data); +    const LLUUID outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + +    LLInventoryModel::cat_array_t cat_array; +    LLInventoryModel::item_array_t item_array; + +    LLIsFolderType is_category(LLFolderType::FT_OUTFIT); +    gInventory.collectDescendentsIf(outfits_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, is_category); + +    response["outfits"] = llsd::toMap(cat_array, +        [](const LLPointer<LLViewerInventoryCategory> &cat) +        { return std::make_pair(cat->getUUID().asString(), cat->getName()); }); +} + +void LLAppearanceListener::getOutfitItems(LLSD const &data) +{ +    Response response(LLSD(), data); +    LLUUID outfit_id(data["outfit_id"].asUUID()); +    LLViewerInventoryCategory *cat = gInventory.getCategory(outfit_id); +    if (!cat || cat->getPreferredType() != LLFolderType::FT_OUTFIT) +    { +        return response.error(stringize("Couldn't find outfit ", outfit_id.asString())); +    } +    LLInventoryModel::cat_array_t  cat_array; +    LLInventoryModel::item_array_t item_array; + +    LLFindOutfitItems collector = LLFindOutfitItems(); +    gInventory.collectDescendentsIf(outfit_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, collector); + +    response["items"] = llsd::toMap(item_array, +        [](const LLPointer<LLViewerInventoryItem> &it) +        { +            return std::make_pair( +                it->getUUID().asString(), +                llsd::map( +                    "name", it->getName(), +                    "wearable_type", LLWearableType::getInstance()->getTypeName(it->isWearableType() ? it->getWearableType() : LLWearableType::WT_NONE), +                    "is_worn", get_is_item_worn(it))); +        }); +} diff --git a/indra/newview/llappearancelistener.h b/indra/newview/llappearancelistener.h new file mode 100644 index 0000000000..04c5eac2eb --- /dev/null +++ b/indra/newview/llappearancelistener.h @@ -0,0 +1,46 @@ +/** + * @file llappearancelistener.h + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, 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_LLAPPEARANCELISTENER_H +#define LL_LLAPPEARANCELISTENER_H + +#include "lleventapi.h" + +class LLAppearanceListener : public LLEventAPI +{ +public: +    LLAppearanceListener(); + +private: +    void wearOutfit(LLSD const &data); +    void wearItems(LLSD const &data); +    void detachItems(LLSD const &data); +    void getOutfitsList(LLSD const &data); +    void getOutfitItems(LLSD const &data); +}; + +#endif // LL_LLAPPEARANCELISTENER_H + diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 101aca3823..e9d455ae53 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -31,6 +31,7 @@  #include "llagent.h"  #include "llagentcamera.h"  #include "llagentwearables.h" +#include "llappearancelistener.h"  #include "llappearancemgr.h"  #include "llattachmentsmgr.h"  #include "llcommandhandler.h" @@ -66,6 +67,8 @@  #include "llavatarpropertiesprocessor.h" +LLAppearanceListener sAppearanceListener; +  namespace  {      const S32   BAKE_RETRY_MAX_COUNT = 5; @@ -4762,6 +4765,11 @@ bool wear_category(const LLSD& query_map, bool append)      return false;  } +bool LLAppearanceMgr::wearOutfit(const LLSD& query_map, bool append) +{ +    return wear_category(query_map, append); +} +  class LLWearFolderHandler : public LLCommandHandler  {  public: diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 6c45a32856..bc7dc9506b 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -60,6 +60,7 @@ public:      void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);      void wearCategoryFinal(const LLUUID& cat_id, bool copy_items, bool append);      void wearOutfitByName(const std::string& name); +    bool wearOutfit(const LLSD& query_map, bool append = false);      void changeOutfit(bool proceed, const LLUUID& category, bool append);      void replaceCurrentOutfit(const LLUUID& new_outfit);      void renameOutfit(const LLUUID& outfit_id); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c5190fe486..87b165b739 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4585,6 +4585,7 @@ void LLAppViewer::saveFinalSnapshot()                                      false,                                      gSavedSettings.getBOOL("RenderHUDInSnapshot"),                                      true, +                                    false,                                      LLSnapshotModel::SNAPSHOT_TYPE_COLOR,                                      LLSnapshotModel::SNAPSHOT_FORMAT_PNG);          mSavedFinalSnapshot = true; @@ -5299,6 +5300,8 @@ void LLAppViewer::sendLogoutRequest()          msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());          gAgent.sendReliableMessage(); +        LL_INFOS("Agent") << "Logging out as agent: " << gAgent.getID() << " Session: " << gAgent.getSessionID() << LL_ENDL; +          gLogoutTimer.reset();          gLogoutMaxTime = LOGOUT_REQUEST_TIME;          mLogoutRequestSent = true; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 169fea320a..ef609026ad 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -814,69 +814,11 @@ void write_debug_dx(const std::string& str)  bool LLAppViewerWin32::initHardwareTest()  { -    // -    // Do driver verification and initialization based on DirectX -    // hardware polling and driver versions -    // -    if (true == gSavedSettings.getBOOL("ProbeHardwareOnStartup") && false == gSavedSettings.getBOOL("NoHardwareProbe")) -    { -        // per DEV-11631 - disable hardware probing for everything -        // but vram. -        bool vram_only = true; - -        LLSplashScreen::update(LLTrans::getString("StartupDetectingHardware")); - -        LL_DEBUGS("AppInit") << "Attempting to poll DirectX for hardware info" << LL_ENDL; -        gDXHardware.setWriteDebugFunc(write_debug_dx); -        bool probe_ok = gDXHardware.getInfo(vram_only); - -        if (!probe_ok -            && gWarningSettings.getBOOL("AboutDirectX9")) -        { -            LL_WARNS("AppInit") << "DirectX probe failed, alerting user." << LL_ENDL; - -            // Warn them that runnin without DirectX 9 will -            // not allow us to tell them about driver issues -            std::ostringstream msg; -            msg << LLTrans::getString ("MBNoDirectX"); -            S32 button = OSMessageBox( -                msg.str(), -                LLTrans::getString("MBWarning"), -                OSMB_YESNO); -            if (OSBTN_NO== button) -            { -                LL_INFOS("AppInit") << "User quitting after failed DirectX 9 detection" << LL_ENDL; -                LLWeb::loadURLExternal("http://secondlife.com/support/", false); -                return false; -            } -            gWarningSettings.setBOOL("AboutDirectX9", false); -        } -        LL_DEBUGS("AppInit") << "Done polling DirectX for hardware info" << LL_ENDL; - -        // Only probe once after installation -        gSavedSettings.setBOOL("ProbeHardwareOnStartup", false); - -        // Disable so debugger can work -        std::string splash_msg; -        LLStringUtil::format_map_t args; -        args["[APP_NAME]"] = LLAppViewer::instance()->getSecondLifeTitle(); -        splash_msg = LLTrans::getString("StartupLoading", args); - -        LLSplashScreen::update(splash_msg); -    } -      if (!restoreErrorTrap())      { -        LL_WARNS("AppInit") << " Someone took over my exception handler (post hardware probe)!" << LL_ENDL; +        LL_WARNS("AppInit") << " Someone took over my exception handler!" << LL_ENDL;      } -    if (gGLManager.mVRAM == 0) -    { -        gGLManager.mVRAM = gDXHardware.getVRAM(); -    } - -    LL_INFOS("AppInit") << "Detected VRAM: " << gGLManager.mVRAM << LL_ENDL; -      return true;  } diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 95f96e85d6..90ee95d424 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -491,7 +491,6 @@ void LLDrawPoolAvatar::beginImpostor()      if (!LLPipeline::sReflectionRender)      { -        LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f);          LLVOAvatar::sNumVisibleAvatars = 0;      } @@ -547,7 +546,6 @@ void LLDrawPoolAvatar::beginDeferredImpostor()      if (!LLPipeline::sReflectionRender)      { -        LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f);          LLVOAvatar::sNumVisibleAvatars = 0;      } diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 5380463d01..23cf253b6a 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -38,6 +38,7 @@ public:          VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |                      LLVertexBuffer::MAP_NORMAL |                      LLVertexBuffer::MAP_TANGENT | // Only PBR terrain uses this currently +                    LLVertexBuffer::MAP_TEXCOORD0 | // Ownership overlay                      LLVertexBuffer::MAP_TEXCOORD1      }; diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 0017a724ea..875dac103c 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -2563,7 +2563,6 @@ void LLEnvironment::setSharedEnvironment()  {      clearEnvironment(LLEnvironment::ENV_LOCAL);      setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -    updateEnvironment();  }  void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLUUID asset_id, F32 transition_time) diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 42307dd3f8..0a8b8d321d 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -495,7 +495,6 @@ void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)      updateEditEnvironment();      LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT); -    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);      synchronizeTabs();      updateTabs();      refresh(); @@ -824,7 +823,6 @@ void LLFloaterEditExtDayCycle::onClearTrack()      updateEditEnvironment();      LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT); -    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);      synchronizeTabs();      updateTabs();      refresh(); diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index 35f8340997..4825cbf7fb 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -242,9 +242,7 @@ void LLFloaterEnvironmentAdjust::captureCurrentEnvironment()          environment.setEnvironment(LLEnvironment::ENV_LOCAL, mLiveSky, FLOATER_ENVIRONMENT_UPDATE);          environment.setEnvironment(LLEnvironment::ENV_LOCAL, mLiveWater, FLOATER_ENVIRONMENT_UPDATE);      } -    environment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -    environment.updateEnvironment(LLEnvironment::TRANSITION_INSTANT); - +    environment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);  }  void LLFloaterEnvironmentAdjust::onButtonReset() @@ -258,7 +256,6 @@ void LLFloaterEnvironmentAdjust::onButtonReset()              this->closeFloater();              LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);              LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -            LLEnvironment::instance().updateEnvironment();          }      }); @@ -455,9 +452,29 @@ void LLFloaterEnvironmentAdjust::onMoonAzimElevChanged()  void LLFloaterEnvironmentAdjust::onCloudMapChanged()  {      if (!mLiveSky) +    {          return; -    mLiveSky->setCloudNoiseTextureId(getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->getValue().asUUID()); -    mLiveSky->update(); +    } + +    LLTextureCtrl* picker_ctrl = getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP); + +    LLUUID new_texture_id = picker_ctrl->getValue().asUUID(); + +    LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + +    LLSettingsSky::ptr_t sky_to_set = mLiveSky->buildClone(); +    if (!sky_to_set) +    { +        return; +    } + +    sky_to_set->setCloudNoiseTextureId(new_texture_id); + +    LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, sky_to_set); + +    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true); + +    picker_ctrl->setValue(new_texture_id);  }  void LLFloaterEnvironmentAdjust::onWaterMapChanged() diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 28c651f0cd..db6f9ac22a 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -52,6 +52,7 @@  #include "llfirstuse.h"  #include "llfloaterimnearbychat.h" +#include "llfloaterimnearbychatlistener.h"  #include "llagent.h" // gAgent  #include "llgesturemgr.h"  #include "llmultigesture.h" @@ -71,6 +72,8 @@  S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0; +static LLFloaterIMNearbyChatListener sChatListener; +  constexpr S32 EXPANDED_HEIGHT = 266;  constexpr S32 COLLAPSED_HEIGHT = 60;  constexpr S32 EXPANDED_MIN_HEIGHT = 150; diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp index 43173d3680..b15a32ce40 100644 --- a/indra/newview/llfloaterimnearbychatlistener.cpp +++ b/indra/newview/llfloaterimnearbychatlistener.cpp @@ -34,12 +34,12 @@  #include "llagent.h"  #include "llchat.h"  #include "llviewercontrol.h" +#include "stringize.h" +static const F32 CHAT_THROTTLE_PERIOD = 1.f; -LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar) -  : LLEventAPI("LLChatBar", -               "LLChatBar listener to (e.g.) sendChat, etc."), -    mChatbar(chatbar) +LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener() : +    LLEventAPI("LLChatBar", "LLChatBar listener to (e.g.) sendChat, etc.")  {      add("sendChat",          "Send chat to the simulator:\n" @@ -49,10 +49,18 @@ LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyCh          &LLFloaterIMNearbyChatListener::sendChat);  } -  // "sendChat" command -void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const +void LLFloaterIMNearbyChatListener::sendChat(LLSD const& chat_data)  { +    F64 cur_time = LLTimer::getElapsedSeconds(); + +    if (cur_time < mLastThrottleTime + CHAT_THROTTLE_PERIOD) +    { +        LL_WARNS("LLFloaterIMNearbyChatListener") << "'sendChat' was  throttled" << LL_ENDL; +        return; +    } +    mLastThrottleTime = cur_time; +      // Extract the data      std::string chat_text = chat_data["message"].asString(); @@ -81,20 +89,12 @@ void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const      }      // Have to prepend /42 style channel numbers -    std::string chat_to_send; -    if (channel == 0) -    { -        chat_to_send = chat_text; -    } -    else +    if (channel)      { -        chat_to_send += "/"; -        chat_to_send += chat_data["channel"].asString(); -        chat_to_send += " "; -        chat_to_send += chat_text; +        chat_text = stringize("/", chat_data["channel"].asString(), " ", chat_text);      }      // Send it as if it was typed in -    mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, ((bool)(channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim")); +    LLFloaterIMNearbyChat::sendChatFromViewer(chat_text, type_o_chat, (channel == 0) && gSavedSettings.getBOOL("PlayChatAnim"));  } diff --git a/indra/newview/llfloaterimnearbychatlistener.h b/indra/newview/llfloaterimnearbychatlistener.h index 96184d95b3..71eba53a9a 100644 --- a/indra/newview/llfloaterimnearbychatlistener.h +++ b/indra/newview/llfloaterimnearbychatlistener.h @@ -38,12 +38,12 @@ class LLFloaterIMNearbyChat;  class LLFloaterIMNearbyChatListener : public LLEventAPI  {  public: -    LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar); +    LLFloaterIMNearbyChatListener();  private: -    void sendChat(LLSD const & chat_data) const; +    void sendChat(LLSD const & chat_data); -    LLFloaterIMNearbyChat & mChatbar; +    F64 mLastThrottleTime{0};  };  #endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 335aba2cc9..553aa1ff4b 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -39,6 +39,7 @@  #include "llchicletbar.h"  #include "lldraghandle.h"  #include "llemojidictionary.h" +#include "llemojihelper.h"  #include "llfloaterreg.h"  #include "llfloateremojipicker.h"  #include "llfloaterimsession.h" @@ -300,6 +301,8 @@ bool LLFloaterIMSessionTab::postBuild()      mEmojiPickerShowBtn = getChild<LLButton>("emoji_picker_show_btn");      mEmojiPickerShowBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerShowBtnClicked(); }); +    mEmojiPickerShowBtn->setMouseDownCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerShowBtnDown(); }); +    mEmojiCloseConn = LLEmojiHelper::instance().setCloseCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerClosed(); });      mGearBtn = getChild<LLButton>("gear_btn");      mAddBtn = getChild<LLButton>("add_btn"); @@ -532,8 +535,43 @@ void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked()  void LLFloaterIMSessionTab::onEmojiPickerShowBtnClicked()  { -    mInputEditor->setFocus(true); -    mInputEditor->showEmojiHelper(); +    if (!mEmojiPickerShowBtn->getToggleState()) +    { +        mInputEditor->hideEmojiHelper(); +        mInputEditor->setFocus(true); +        mInputEditor->showEmojiHelper(); +        mEmojiPickerShowBtn->setToggleState(true); // in case hideEmojiHelper closed a visible instance +    } +    else +    { +        mInputEditor->hideEmojiHelper(); +        mEmojiPickerShowBtn->setToggleState(false); +    } +} + +void LLFloaterIMSessionTab::onEmojiPickerShowBtnDown() +{ +    if (mEmojiHelperLastCallbackFrame == LLFrameTimer::getFrameCount()) +    { +        // Helper gets closed by focus lost event on Down before before onEmojiPickerShowBtnDown +        // triggers. +        // If this condition is true, user pressed button and it was 'toggled' during press, +        // restore 'toggled' state so that button will not reopen helper. +        mEmojiPickerShowBtn->setToggleState(true); +    } +} + +void LLFloaterIMSessionTab::onEmojiPickerClosed() +{ +    if (mEmojiPickerShowBtn->getToggleState()) +    { +        mEmojiPickerShowBtn->setToggleState(false); +        // Helper gets closed by focus lost event on Down before onEmojiPickerShowBtnDown +        // triggers. If mEmojiHelperLastCallbackFrame is set and matches Down, means close +        // was triggered by user's press. +        // A bit hacky, but I can't think of a better way to handle this without rewriting helper. +        mEmojiHelperLastCallbackFrame = LLFrameTimer::getFrameCount(); +    }  }  void LLFloaterIMSessionTab::initEmojiRecentPanel() diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 367d988f26..6d04d622e1 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -235,6 +235,8 @@ private:      void onEmojiRecentPanelToggleBtnClicked();      void onEmojiPickerShowBtnClicked(); +    void onEmojiPickerShowBtnDown(); +    void onEmojiPickerClosed();      void initEmojiRecentPanel();      void onEmojiRecentPanelFocusReceived();      void onEmojiRecentPanelFocusLost(); @@ -249,6 +251,9 @@ private:      S32 mInputEditorPad;      S32 mChatLayoutPanelHeight;      S32 mFloaterHeight; + +    boost::signals2::connection mEmojiCloseConn; +    U32 mEmojiHelperLastCallbackFrame = { 0 };  }; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 68b9e758a1..faf7ed0d8c 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -60,12 +60,13 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase*  {      LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");      LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel_container->getCurrentPanel()); -    if (!active_panel) -    { -        LL_WARNS() << "No snapshot active panel, current panel index: " << panel_container->getCurrentPanelIndex() << LL_ENDL; -    } +      if (!ok_if_not_found)      { +        if (!active_panel) +        { +            LL_WARNS() << "No snapshot active panel, current panel index: " << panel_container->getCurrentPanelIndex() << LL_ENDL; +        }          llassert_always(active_panel != NULL);      }      return active_panel; @@ -516,34 +517,13 @@ void LLFloaterSnapshotBase::ImplBase::onClickFilter(LLUICtrl *ctrl, void* data)  }  // static -void LLFloaterSnapshotBase::ImplBase::onClickUICheck(LLUICtrl *ctrl, void* data) +void LLFloaterSnapshotBase::ImplBase::onClickDisplaySetting(LLUICtrl* ctrl, void* data)  { -    LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; -    gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() ); - -    LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; +    LLFloaterSnapshot* view = (LLFloaterSnapshot*)data;      if (view)      {          LLSnapshotLivePreview* previewp = view->getPreviewView(); -        if(previewp) -        { -            previewp->updateSnapshot(true, true); -        } -        view->impl->updateControls(view); -    } -} - -// static -void LLFloaterSnapshotBase::ImplBase::onClickHUDCheck(LLUICtrl *ctrl, void* data) -{ -    LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; -    gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() ); - -    LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; -    if (view) -    { -        LLSnapshotLivePreview* previewp = view->getPreviewView(); -        if(previewp) +        if (previewp)          {              previewp->updateSnapshot(true, true);          } @@ -1002,11 +982,9 @@ bool LLFloaterSnapshot::postBuild()      mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");      mFailureLblPanel = getChild<LLUICtrl>("failed_panel"); -    childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this); -    getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); - -    childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this); -    getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); +    childSetCommitCallback("ui_check", ImplBase::onClickDisplaySetting, this); +    childSetCommitCallback("balance_check", ImplBase::onClickDisplaySetting, this); +    childSetCommitCallback("hud_check", ImplBase::onClickDisplaySetting, this);      ((Impl*)impl)->setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot")); diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 6df851b839..186d9c41cf 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -103,8 +103,7 @@ public:      static void onClickAutoSnap(LLUICtrl *ctrl, void* data);      static void onClickNoPost(LLUICtrl *ctrl, void* data);      static void onClickFilter(LLUICtrl *ctrl, void* data); -    static void onClickUICheck(LLUICtrl *ctrl, void* data); -    static void onClickHUDCheck(LLUICtrl *ctrl, void* data); +    static void onClickDisplaySetting(LLUICtrl *ctrl, void* data);      static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);      virtual LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) = 0; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 30ed723db6..a798ba31ee 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -486,8 +486,11 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)          const LLUUID landmark_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);          LLInventoryModelBackgroundFetch::instance().start(landmark_folder_id); -        mLocationEditor->setFocus( true); -        gFocusMgr.triggerFocusFlash(); +        if (hasFocus()) +        { +            mLocationEditor->setFocus( true); +            gFocusMgr.triggerFocusFlash(); +        }          buildAvatarIDList();          buildLandmarkIDLists(); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index ba9c9fa13f..34d96aa024 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -46,7 +46,7 @@  //  // Globals  // -static GroupChatListener sGroupChatListener; +static LLGroupChatListener sGroupChatListener;  class LLGroupHandler : public LLCommandHandler  { diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 4e8bcc4f7a..4c02511268 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -422,6 +422,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,      U8 *binary_bucket,      S32 binary_bucket_size,      LLHost &sender, +    LLSD metadata,      LLUUID aux_id)  {      LLChat chat; @@ -451,6 +452,28 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,      bool is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&          LLMuteList::isLinden(name); +    /*** +    * The simulator may have flagged this sender as a bot, if the viewer would like to display +    * the chat text in a different color or font, the below code is how the viewer can +    * tell if the sender is a bot. +    *----------------------------------------------------- +    bool is_bot = false; +    if (metadata.has("sender")) +    {   // The server has identified this sender as a bot. +        is_bot = metadata["sender"]["bot"].asBoolean(); +    } +    *----------------------------------------------------- +    */ + +    std::string notice_name; +    LLSD notice_args; +    if (metadata.has("notice")) +    {   // The server has injected a notice into the IM conversation. +        // These will be things like bot notifications, etc. +        notice_name = metadata["notice"]["id"].asString(); +        notice_args = metadata["notice"]["data"]; +    } +      chat.mMuted = is_muted;      chat.mFromID = from_id;      chat.mFromName = name; @@ -544,7 +567,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,              }              else              { -                // standard message, not from system +                // standard message, server may have injected a notice into the conversation.                  std::string saved;                  if (offline == IM_OFFLINE)                  { @@ -579,8 +602,17 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,                              region_message = true;                          }                      } -                    gIMMgr->addMessage( -                        session_id, + +                    std::string real_name; + +                    if (!notice_name.empty()) +                    {   // The simulator has injected some sort of notice into the conversation. +                        // findString will only replace the contents of buffer if the notice_id is found. +                        LLTrans::findString(buffer, notice_name, notice_args); +                        real_name = SYSTEM_FROM; +                    } + +                    gIMMgr->addMessage(session_id,                          from_id,                          name,                          buffer, @@ -591,7 +623,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,                          region_id,                          position,                          region_message, -                        timestamp); +                        timestamp, +                        LLUUID::null, +                        real_name);                  }                  else                  { @@ -1619,6 +1653,12 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)              from_group = message_data["from_group"].asString() == "Y";          } +        LLSD metadata; +        if (message_data.has("metadata")) +        { +            metadata = message_data["metadata"]; +        } +          EInstantMessage dialog = static_cast<EInstantMessage>(message_data["dialog"].asInteger());          LLUUID session_id = message_data["transaction-id"].asUUID();          if (session_id.isNull() && dialog == IM_FROM_TASK) @@ -1646,6 +1686,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)                      local_bin_bucket.data(),                      S32(local_bin_bucket.size()),                      local_sender, +                    metadata,                      message_data["asset_id"].asUUID());              }); diff --git a/indra/newview/llimprocessing.h b/indra/newview/llimprocessing.h index 030d28b198..66ffc59ae0 100644 --- a/indra/newview/llimprocessing.h +++ b/indra/newview/llimprocessing.h @@ -48,6 +48,7 @@ public:          U8 *binary_bucket,          S32 binary_bucket_size,          LLHost &sender, +        LLSD metadata,          LLUUID aux_id = LLUUID::null);      // Either receives list of offline messages from 'ReadOfflineMsgs' capability diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 756f3b33ed..77451a6248 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -3144,9 +3144,16 @@ void LLIMMgr::addMessage(      const LLUUID& region_id,      const LLVector3& position,      bool is_region_msg, -    U32 timestamp)      // May be zero +    U32 timestamp,  // May be zero +    LLUUID display_id, +    std::string_view display_name)  {      LLUUID other_participant_id = target_id; +    std::string message_display_name = (display_name.empty()) ? from : std::string(display_name); +    if (display_id.isNull() && (display_name.empty())) +    { +        display_id = other_participant_id; +    }      LLUUID new_session_id = session_id;      if (new_session_id.isNull()) @@ -3243,7 +3250,7 @@ void LLIMMgr::addMessage(              }              //Play sound for new conversations -            if (!skip_message & !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation"))) +            if (!skip_message && !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation")))              {                  make_ui_sound("UISndNewIncomingIMSession");              } @@ -3257,7 +3264,7 @@ void LLIMMgr::addMessage(      if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)      { -        LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg, timestamp); +        LLIMModel::instance().addMessage(new_session_id, message_display_name, display_id, msg, true, is_region_msg, timestamp);      }      // Open conversation floater if offline messages are present diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 61776860e3..23f90ca795 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -368,7 +368,9 @@ public:                      const LLUUID& region_id = LLUUID::null,                      const LLVector3& position = LLVector3::zero,                      bool is_region_msg = false, -                    U32 timestamp = 0); +                    U32 timestamp = 0, +                    LLUUID display_id = LLUUID::null, +                    std::string_view display_name = "");      void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 15190854a2..ee530c163b 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -104,7 +104,6 @@ static bool check_item(const LLUUID& item_id,                         LLInventoryFilter* filter);  // Helper functions -  bool isAddAction(const std::string& action)  {      return ("wear" == action || "attach" == action || "activate" == action); @@ -2697,7 +2696,12 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,          U32 max_items_to_wear = gSavedSettings.getU32("WearFolderLimit");          if (is_movable && move_is_into_outfit)          { -            if (mUUID == my_outifts_id) +            if ((inv_cat->getPreferredType() != LLFolderType::FT_NONE) && (inv_cat->getPreferredType() != LLFolderType::FT_OUTFIT)) +            { +                tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                is_movable = false; +            } +            else if (mUUID == my_outifts_id)              {                  if (source != LLToolDragAndDrop::SOURCE_AGENT || move_is_from_marketplacelistings)                  { @@ -2714,13 +2718,39 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,                      is_movable = false;                  }              } -            else if(getCategory() && getCategory()->getPreferredType() == LLFolderType::FT_NONE) +            else if (!getCategory())              { -                is_movable = ((inv_cat->getPreferredType() == LLFolderType::FT_NONE) || (inv_cat->getPreferredType() == LLFolderType::FT_OUTFIT)); +                is_movable = false; +                tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit");              }              else              { -                is_movable = false; +                EMyOutfitsSubfolderType dest_res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id); +                EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); +                if ((dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) && inv_res == MY_OUTFITS_OUTFIT) +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantMoveOutfitIntoOutfit"); +                } +                else if (dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                } +                else if (dest_res == MY_OUTFITS_SUBFOLDER && inv_res == MY_OUTFITS_SUBOUTFIT) +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                } +                else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) +                { +                    is_movable = true; +                } +                else +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                }              }          }          if (is_movable && move_is_into_current_outfit && is_link) @@ -2912,9 +2942,77 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,              if (mUUID == my_outifts_id)              { -                // Category can contains objects, -                // create a new folder and populate it with links to original objects -                dropToMyOutfits(inv_cat, cb); +                EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); +                if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT) +                { +                    LLInvFVBridge::changeCategoryParent( +                        model, +                        (LLViewerInventoryCategory*)inv_cat, +                        mUUID, +                        false); +                    if (cb) cb->fire(inv_cat->getUUID()); +                } +                else +                { +                    // Moving from inventory +                    // create a new folder and populate it with links to original objects +                    dropToMyOutfits(inv_cat, cb); +                } +            } +            else if (move_is_into_my_outfits) +            { +                EMyOutfitsSubfolderType dest_res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id); +                EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); +                switch (inv_res) +                { +                case MY_OUTFITS_NO: +                    // Moning from outside outfits into outfits +                    if (dest_res == MY_OUTFITS_SUBFOLDER) +                    { +                        // turn it into outfit +                        dropToMyOutfitsSubfolder(inv_cat, mUUID, LLFolderType::FT_OUTFIT, cb); +                    } +                    else +                    { +                        // or link it? +                        dropToMyOutfitsSubfolder(inv_cat, mUUID, LLFolderType::FT_NONE, cb); +                    } +                    break; +                case MY_OUTFITS_SUBFOLDER: +                case MY_OUTFITS_OUTFIT: +                    // only permit moving subfodlers and outfits into other subfolders +                    if (dest_res == MY_OUTFITS_SUBFOLDER) +                    { +                        LLInvFVBridge::changeCategoryParent( +                            model, +                            (LLViewerInventoryCategory*)inv_cat, +                            mUUID, +                            false); +                        if (cb) cb->fire(inv_cat->getUUID()); +                    } +                    else +                    { +                        assert(false); // mot permitted, shouldn't have accepted +                    } +                    break; +                case MY_OUTFITS_SUBOUTFIT: +                    if (dest_res == MY_OUTFITS_SUBOUTFIT || dest_res == MY_OUTFITS_OUTFIT) +                    { +                        LLInvFVBridge::changeCategoryParent( +                            model, +                            (LLViewerInventoryCategory*)inv_cat, +                            mUUID, +                            false); +                        if (cb) cb->fire(inv_cat->getUUID()); +                    } +                    else +                    { +                        assert(false); // mot permitted, shouldn't have accepted +                    } +                    break; +                default: +                    break; +                }              }              // if target is current outfit folder we use link              else if (move_is_into_current_outfit && @@ -4008,6 +4106,7 @@ void LLFolderBridge::perform_pasteFromClipboard()                  {                      if (!move_is_into_my_outfits && item && can_move_to_outfit(item, move_is_into_current_outfit))                      { +                        // todo: this is going to create dupplicate folders?                          dropToOutfit(item, move_is_into_current_outfit, cb);                      }                      else if (move_is_into_my_outfits && LLAssetType::AT_CATEGORY == obj->getType()) @@ -4016,7 +4115,23 @@ void LLFolderBridge::perform_pasteFromClipboard()                          U32 max_items_to_wear = gSavedSettings.getU32("WearFolderLimit");                          if (cat && can_move_to_my_outfits(model, cat, max_items_to_wear))                          { -                            dropToMyOutfits(cat, cb); +                            if (mUUID == my_outifts_id) +                            { +                                dropToMyOutfits(cat, cb); +                            } +                            else if (move_is_into_my_outfits) +                            { +                                EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id); +                                if (res == MY_OUTFITS_SUBFOLDER) +                                { +                                    // turn it into outfit +                                    dropToMyOutfitsSubfolder(cat, mUUID, LLFolderType::FT_OUTFIT, cb); +                                } +                                else +                                { +                                    dropToMyOutfitsSubfolder(cat, mUUID, LLFolderType::FT_NONE, cb); +                                } +                            }                          }                          else                          { @@ -4256,6 +4371,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items      if (outfits_id == mUUID)      { +        items.push_back(std::string("New Outfit Folder"));          items.push_back(std::string("New Outfit"));      } @@ -4349,63 +4465,83 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items      else if(isAgentInventory()) // do not allow creating in library      {          LLViewerInventoryCategory *cat = getCategory(); -        // BAP removed protected check to re-enable standard ops in untyped folders. -        // Not sure what the right thing is to do here. -        if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT)) -        { -            if (!isInboxFolder() // don't allow creation in inbox -                && outfits_id != mUUID) -            { -                bool menu_items_added = false; -                // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. -                if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) -                { -                    items.push_back(std::string("New Folder")); -                    menu_items_added = true; -                } -                if (!isMarketplaceListingsFolder()) -                { -                    items.push_back(std::string("upload_def")); -                    items.push_back(std::string("create_new")); -                    items.push_back(std::string("New Script")); -                    items.push_back(std::string("New Note")); -                    items.push_back(std::string("New Gesture")); -                    items.push_back(std::string("New Material")); -                    items.push_back(std::string("New Clothes")); -                    items.push_back(std::string("New Body Parts")); -                    items.push_back(std::string("New Settings")); -                    if (!LLEnvironment::instance().isInventoryEnabled()) -                    { -                        disabled_items.push_back("New Settings"); -                    } -                } -                else -                { -                    items.push_back(std::string("New Listing Folder")); -                } -                if (menu_items_added) -                { -                    items.push_back(std::string("Create Separator")); -                } -            } -            getClipboardEntries(false, items, disabled_items, flags); -        } -        else + +        if (cat)          { -            // Want some but not all of the items from getClipboardEntries for outfits. -            if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT)) +            if (cat->getPreferredType() == LLFolderType::FT_OUTFIT)              { +                // Want some but not all of the items from getClipboardEntries for outfits.                  items.push_back(std::string("Rename"));                  items.push_back(std::string("thumbnail"));                  addDeleteContextMenuOptions(items, disabled_items);                  // EXT-4030: disallow deletion of currently worn outfit -                const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); +                const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();                  if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory()))                  {                      disabled_items.push_back(std::string("Delete"));                  }              } +            else if (outfits_id == mUUID) +            { +                getClipboardEntries(false, items, disabled_items, flags); +            } +            else if (!isCOFFolder()) +            { +                EMyOutfitsSubfolderType in_my_outfits = myoutfit_object_subfolder_type(model, mUUID, outfits_id); +                if (in_my_outfits != MY_OUTFITS_NO) +                { +                    if (in_my_outfits == MY_OUTFITS_SUBFOLDER) +                    { +                        // Not inside an outfit, but inside 'my outfits' +                        items.push_back(std::string("New Outfit")); +                        items.push_back(std::string("New Outfit Folder")); +                    } +                    items.push_back(std::string("Rename")); +                    items.push_back(std::string("thumbnail")); + +                    addDeleteContextMenuOptions(items, disabled_items); +                } +                else +                { +                    if (!isInboxFolder() // don't allow creation in inbox +                        && outfits_id != mUUID) +                    { +                        bool menu_items_added = false; +                        // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. +                        if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) +                        { +                            items.push_back(std::string("New Folder")); +                            menu_items_added = true; +                        } +                        if (!isMarketplaceListingsFolder()) +                        { +                            items.push_back(std::string("upload_def")); +                            items.push_back(std::string("create_new")); +                            items.push_back(std::string("New Script")); +                            items.push_back(std::string("New Note")); +                            items.push_back(std::string("New Gesture")); +                            items.push_back(std::string("New Material")); +                            items.push_back(std::string("New Clothes")); +                            items.push_back(std::string("New Body Parts")); +                            items.push_back(std::string("New Settings")); +                            if (!LLEnvironment::instance().isInventoryEnabled()) +                            { +                                disabled_items.push_back("New Settings"); +                            } +                        } +                        else +                        { +                            items.push_back(std::string("New Listing Folder")); +                        } +                        if (menu_items_added) +                        { +                            items.push_back(std::string("Create Separator")); +                        } +                    } +                    getClipboardEntries(false, items, disabled_items, flags); +                } +            }          }          if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID) @@ -4560,7 +4696,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&          if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren() && (type != LLFolderType::FT_OUTFIT))          { -            items.push_back(std::string("Ungroup folder items")); +            const LLUUID my_outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +            if (!gInventory.isObjectDescendentOf(mUUID, my_outfits)) +            { +                items.push_back(std::string("Ungroup folder items")); +            }          }      }      else @@ -5333,13 +5473,24 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI      // Note: creation will take time, so passing folder id to callback is slightly unreliable,      // but so is collecting and passing descendants' ids      inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel); -    gInventory.createNewCategory(dest_id, +    getInventoryModel()->createNewCategory(dest_id,                                   LLFolderType::FT_OUTFIT,                                   inv_cat->getName(),                                   func,                                   inv_cat->getThumbnailUUID());  } +void LLFolderBridge::dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLFolderType::EType preferred_type, LLPointer<LLInventoryCallback> cb) +{ +    const LLUUID outfits_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +    inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel); +    getInventoryModel()->createNewCategory(dest_id, +        preferred_type, +        inv_cat->getName(), +        func, +        inv_cat->getThumbnailUUID()); +} +  void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id,                                                   LLUUID cat_dest_id,                                                   LLPointer<LLInventoryCallback> cb, @@ -5513,7 +5664,9 @@ bool LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,          }          else if (user_confirm && (move_is_into_current_outfit || move_is_into_outfit))          { -            accept = can_move_to_outfit(inv_item, move_is_into_current_outfit); +            EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id); +            // don't allow items in my outfits' subfodlers, only in outfits and outfit's subfolders +            accept = res != MY_OUTFITS_SUBFOLDER && can_move_to_outfit(inv_item, move_is_into_current_outfit);          }          else if (user_confirm && (move_is_into_favorites || move_is_into_landmarks))          { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 3e7f74384b..a101c7368a 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -369,6 +369,7 @@ protected:      void dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb = NULL);      void dropToOutfit(LLInventoryItem* inv_item, bool move_is_into_current_outfit, LLPointer<LLInventoryCallback> cb = NULL);      void dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLInventoryCallback> cb = NULL); +    void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest, LLFolderType::EType preferred_type, LLPointer<LLInventoryCallback> cb = NULL);      //--------------------------------------------------------------------      // Messy hacks for handling folder options diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 1ccefa3212..7fff88fba7 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2493,6 +2493,40 @@ bool can_share_item(const LLUUID& item_id)      return can_share;  } + +EMyOutfitsSubfolderType myoutfit_object_subfolder_type( +    LLInventoryModel* model, +    const LLUUID& obj_id, +    const LLUUID& my_outfits_id) +{ +    if (obj_id == my_outfits_id) return MY_OUTFITS_NO; + +    const LLViewerInventoryCategory* test_cat = model->getCategory(obj_id); +    if (test_cat->getPreferredType() == LLFolderType::FT_OUTFIT) +    { +        return MY_OUTFITS_OUTFIT; +    } +    while (test_cat) +    { +        if (test_cat->getPreferredType() == LLFolderType::FT_OUTFIT) +        { +            return MY_OUTFITS_SUBOUTFIT; +        } + +        const LLUUID& parent_id = test_cat->getParentUUID(); +        if (parent_id.isNull()) +        { +            return MY_OUTFITS_NO; +        } +        if (parent_id == my_outfits_id) +        { +            return MY_OUTFITS_SUBFOLDER; +        } +        test_cat = model->getCategory(parent_id); +    } + +    return MY_OUTFITS_NO; +}  ///----------------------------------------------------------------------------  /// LLMarketplaceValidator implementations  ///---------------------------------------------------------------------------- @@ -2621,6 +2655,11 @@ bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(const LLInventoryIte      return false;  } +bool LLIsFolderType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ +    return cat && cat->getPreferredType() == mType; +} +  bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)  {      if(mType == LLAssetType::AT_CATEGORY) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 13a64f21dc..0ab045f2a0 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -121,6 +121,18 @@ std::string get_searchable_creator_name(LLInventoryModel* model, const LLUUID& i  std::string get_searchable_UUID(LLInventoryModel* model, const LLUUID& item_id);  bool can_share_item(const LLUUID& item_id); +enum EMyOutfitsSubfolderType +{ +    MY_OUTFITS_NO, +    MY_OUTFITS_SUBFOLDER, +    MY_OUTFITS_OUTFIT, +    MY_OUTFITS_SUBOUTFIT, +}; +EMyOutfitsSubfolderType myoutfit_object_subfolder_type( +    LLInventoryModel* model, +    const LLUUID& obj_id, +    const LLUUID& my_outfits_id); +  /**                    Miscellaneous global functions   **                                                                            **   *******************************************************************************/ @@ -234,6 +246,24 @@ protected:  // the type is the type passed in during construction.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLIsFolderType : public LLInventoryCollectFunctor +{ +public: +    LLIsFolderType(LLFolderType::EType type) : mType(type) {} +    virtual ~LLIsFolderType() {} +    virtual bool operator()(LLInventoryCategory* cat, +        LLInventoryItem* item); +protected: +    LLFolderType::EType mType; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLIsType +// +// Implementation of a LLInventoryCollectFunctor which returns true if +// the type is the type passed in during construction. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +  class LLIsType : public LLInventoryCollectFunctor  {  public: diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index c4f93cee98..eb47af85fd 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -60,10 +60,12 @@ static LLPanelInjector<LLInventoryGallery> t_inventory_gallery("inventory_galler  const S32 GALLERY_ITEMS_PER_ROW_MIN = 2;  const S32 FAST_LOAD_THUMBNAIL_TRSHOLD = 50; // load folders below this value immediately +  // Helper dnd functions  bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, bool drop, std::string& tooltip_msg, bool is_link);  bool dragItemIntoFolder(LLUUID folder_id, LLInventoryItem* inv_item, bool drop, std::string& tooltip_msg, bool user_confirm);  void dropToMyOutfits(LLInventoryCategory* inv_cat); +void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLFolderType::EType preferred_type);  class LLGalleryPanel: public LLPanel  { @@ -3745,7 +3747,12 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat,          U32 max_items_to_wear = gSavedSettings.getU32("WearFolderLimit");          if (is_movable && move_is_into_outfit)          { -            if (dest_id == my_outifts_id) +            if ((inv_cat->getPreferredType() != LLFolderType::FT_NONE) && (inv_cat->getPreferredType() != LLFolderType::FT_OUTFIT)) +            { +                tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                is_movable = false; +            } +            else if (dest_id == my_outifts_id)              {                  if (source != LLToolDragAndDrop::SOURCE_AGENT || move_is_from_marketplacelistings)                  { @@ -3762,13 +3769,39 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat,                      is_movable = false;                  }              } -            else if (dest_cat && dest_cat->getPreferredType() == LLFolderType::FT_NONE) +            else if (!dest_cat)              { -                is_movable = ((inv_cat->getPreferredType() == LLFolderType::FT_NONE) || (inv_cat->getPreferredType() == LLFolderType::FT_OUTFIT)); +                is_movable = false; +                tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit");              }              else              { -                is_movable = false; +                EMyOutfitsSubfolderType dest_res = myoutfit_object_subfolder_type(model, dest_id, my_outifts_id); +                EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); +                if ((dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) && inv_res == MY_OUTFITS_OUTFIT) +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantMoveOutfitIntoOutfit"); +                } +                else if (dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                } +                else if (dest_res == MY_OUTFITS_SUBFOLDER && inv_res == MY_OUTFITS_SUBOUTFIT) +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                } +                else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) +                { +                    is_movable = true; +                } +                else +                { +                    is_movable = false; +                    tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); +                }              }          }          if (is_movable && move_is_into_current_outfit && is_link) @@ -3894,9 +3927,70 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat,              if (dest_id == my_outifts_id)              { -                // Category can contains objects, -                // create a new folder and populate it with links to original objects -                dropToMyOutfits(inv_cat); +                EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); +                if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT) +                { +                    gInventory.changeCategoryParent( +                        (LLViewerInventoryCategory*)inv_cat, +                        dest_id, +                        move_is_into_trash); +                } +                else +                { +                    // Category can contains objects, +                    // create a new folder and populate it with links to original objects +                    dropToMyOutfits(inv_cat); +                } +            } +            else if (move_is_into_my_outfits) +            { +                EMyOutfitsSubfolderType dest_res = myoutfit_object_subfolder_type(model, dest_id, my_outifts_id); +                EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); +                switch (inv_res) +                { +                case MY_OUTFITS_NO: +                    // Moning from outside outfits into outfits +                    if (dest_res == MY_OUTFITS_SUBFOLDER) +                    { +                        // turn it into outfit +                        dropToMyOutfitsSubfolder(inv_cat, dest_id, LLFolderType::FT_OUTFIT); +                    } +                    else +                    { +                        dropToMyOutfitsSubfolder(inv_cat, dest_id, LLFolderType::FT_NONE); +                    } +                    break; +                case MY_OUTFITS_SUBFOLDER: +                case MY_OUTFITS_OUTFIT: +                    // only permit moving subfodlers and outfits into other subfolders +                    if (dest_res == MY_OUTFITS_SUBFOLDER) +                    { +                        gInventory.changeCategoryParent( +                            (LLViewerInventoryCategory*)inv_cat, +                            dest_id, +                            move_is_into_trash); +                    } +                    else +                    { +                        assert(false); // mot permitted, shouldn't have accepted +                    } +                    break; +                case MY_OUTFITS_SUBOUTFIT: +                    if (dest_res == MY_OUTFITS_SUBOUTFIT || dest_res == MY_OUTFITS_OUTFIT) +                    { +                        gInventory.changeCategoryParent( +                            (LLViewerInventoryCategory*)inv_cat, +                            dest_id, +                            move_is_into_trash); +                    } +                    else +                    { +                        assert(false); // mot permitted, shouldn't have accepted +                    } +                    break; +                default: +                    break; +                }              }              // if target is current outfit folder we use link              else if (move_is_into_current_outfit && @@ -4041,3 +4135,11 @@ void dropToMyOutfits(LLInventoryCategory* inv_cat)      inventory_func_type func = boost::bind(&outfitFolderCreatedCallback, inv_cat->getUUID(), _1);      gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID());  } + +void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID &dest_id, LLFolderType::EType preferred_type) +{ +    // Note: creation will take time, so passing folder id to callback is slightly unreliable, +    // but so is collecting and passing descendants' ids +    inventory_func_type func = boost::bind(&outfitFolderCreatedCallback, inv_cat->getUUID(), _1); +    gInventory.createNewCategory(dest_id, preferred_type, inv_cat->getName(), func, inv_cat->getThumbnailUUID()); +} diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 0c35a7f695..3fede1a001 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -607,7 +607,9 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men      bool is_trash = (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH));      bool is_in_trash = gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH));      bool is_lost_and_found = (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND)); -    bool is_outfits= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS)); +    const LLUUID my_outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +    bool is_outfits= (selected_id == my_outfits); +    bool is_in_outfits = is_outfits || gInventory.isObjectDescendentOf(selected_id, my_outfits);      bool is_in_favorites = gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));      //bool is_favorites= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)); @@ -746,7 +748,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men      }      else      { -        if (is_agent_inventory && !is_inbox && !is_cof && !is_in_favorites && !is_outfits) +        if (is_agent_inventory && !is_inbox && !is_cof && !is_in_favorites && !is_outfits && !is_in_outfits)          {              LLViewerInventoryCategory* category = gInventory.getCategory(selected_id);              if (!category || !LLFriendCardsManager::instance().isCategoryInFriendFolder(category)) @@ -792,15 +794,26 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men              items.push_back(std::string("Set favorite folder")); -            if(is_outfits && !isRootFolder()) +            if(is_outfits)              { -                items.push_back(std::string("New Outfit")); +                EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(&gInventory, selected_id, my_outfits); +                if (res != MY_OUTFITS_OUTFIT && res != MY_OUTFITS_SUBOUTFIT) +                { +                    items.push_back(std::string("New Outfit")); +                    items.push_back(std::string("New Outfit Folder")); +                } +                items.push_back(std::string("Delete")); +                items.push_back(std::string("Rename")); +                if (!get_is_category_and_children_removable(&gInventory, selected_id, false)) +                { +                    disabled_items.push_back(std::string("Delete")); +                }              }              items.push_back(std::string("Subfolder Separator")); -            if (!is_system_folder && !isRootFolder()) +            if (!is_system_folder && !isRootFolder() && !is_outfits)              { -                if(has_children && (folder_type != LLFolderType::FT_OUTFIT)) +                if(has_children && (folder_type != LLFolderType::FT_OUTFIT) && !is_in_outfits)                  {                      items.push_back(std::string("Ungroup folder items"));                  } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b6ff31a7ed..de1c7a7ed8 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1007,7 +1007,8 @@ void LLInventoryModel::createNewCategory(const LLUUID& parent_id,          return;      } -    if (preferred_type != LLFolderType::FT_NONE) +    if (preferred_type != LLFolderType::FT_NONE +        && preferred_type != LLFolderType::FT_OUTFIT)      {          // Ultimately this should only be done for non-singleton          // types. Requires back-end changes to guarantee that others @@ -3525,7 +3526,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename,          fileXML.close(); -        LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL; +        LL_INFOS(LOG_INV) << "Inventory saved: " << (S32)cat_count << " categories, " << (S32)it_count << " items." << LL_ENDL;      }      catch (...)      { diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 101ee215cb..e31fbb188a 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -38,6 +38,7 @@  /* image compression headers. */  #include "llimagebmp.h"  #include "llimagetga.h" +#include "llimagej2c.h"  #include "llimagejpeg.h"  #include "llimagepng.h" @@ -106,6 +107,10 @@ LLLocalBitmap::LLLocalBitmap(std::string filename)      {          mExtension = ET_IMG_JPG;      } +    else if (temp_exten == "j2c" || temp_exten == "jp2") +    { +        mExtension = ET_IMG_J2C; +    }      else if (temp_exten == "png")      {          mExtension = ET_IMG_PNG; @@ -354,6 +359,21 @@ bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg)              break;          } +        case ET_IMG_J2C: +        { +            LLPointer<LLImageJ2C> jpeg_image = new LLImageJ2C; +            if (jpeg_image->load(mFilename)) +            { +                jpeg_image->setDiscardLevel(0); +                if (jpeg_image->decode(rawimg, 0.0f)) +                { +                    rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +                    decode_successful = true; +                } +            } +            break; +        } +          case ET_IMG_PNG:          {              LLPointer<LLImagePNG> png_image = new LLImagePNG; diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index de2dcb3467..6c9d65e3b6 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -89,6 +89,7 @@ class LLLocalBitmap              ET_IMG_BMP,              ET_IMG_TGA,              ET_IMG_JPG, +            ET_IMG_J2C,              ET_IMG_PNG          }; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a8c6f69425..48c80842b9 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1210,6 +1210,12 @@ void LLMeshRepoThread::run()          LL_WARNS(LOG_MESH) << "Convex decomposition unable to be quit." << LL_ENDL;      }  } +void LLMeshRepoThread::cleanup() +{ +    mShuttingDown = true; +    mSignal->broadcast(); +    mMeshThreadPool->close(); +}  // Mutex:  LLMeshRepoThread::mMutex must be held on entry  void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) @@ -1493,6 +1499,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)                          [mesh_id, buffer, size]                          ()                      { +                        if (gMeshRepo.mThread->isShuttingDown()) +                        { +                            delete[] buffer; +                            return; +                        }                          if (!gMeshRepo.mThread->skinInfoReceived(mesh_id, buffer, size))                          {                              // either header is faulty or something else overwrote the cache @@ -1993,6 +2004,11 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)                          [params, mesh_id, lod, buffer, size]                          ()                      { +                        if (gMeshRepo.mThread->isShuttingDown()) +                        { +                            delete[] buffer; +                            return; +                        }                          if (gMeshRepo.mThread->lodReceived(params, lod, buffer, size) == MESH_OK)                          {                              LL_DEBUGS(LOG_MESH) << "Mesh/Cache: Mesh body for ID " << mesh_id << " - was retrieved from the cache." << LL_ENDL; @@ -3792,6 +3808,11 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body              [shrd_handler, data, data_size]              ()          { +            if (gMeshRepo.mThread->isShuttingDown()) +            { +                delete[] data; +                return; +            }              LLMeshLODHandler* handler = (LLMeshLODHandler * )shrd_handler.get();              handler->processLod(data, data_size);              delete[] data; @@ -3905,6 +3926,11 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /*              [shrd_handler, data, data_size]              ()          { +            if (gMeshRepo.mThread->isShuttingDown()) +            { +                delete[] data; +                return; +            }              LLMeshSkinInfoHandler* handler = (LLMeshSkinInfoHandler*)shrd_handler.get();              handler->processSkin(data, data_size);              delete[] data; @@ -4127,8 +4153,7 @@ void LLMeshRepository::shutdown()          mUploads[i]->discard() ; //discard the uploading requests.      } -    mThread->mSignal->broadcast(); -    mThread->mMeshThreadPool->close(); +    mThread->cleanup();      while (!mThread->isStopped())      { diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 0d9da32e27..b9acb3573f 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -515,6 +515,8 @@ public:      ~LLMeshRepoThread();      virtual void run(); +    void cleanup(); +    bool isShuttingDown() { return mShuttingDown; }      void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);      void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -583,6 +585,7 @@ private:      U8* getDiskCacheBuffer(S32 size);      S32 mDiskCacheBufferSize = 0;      U8* mDiskCacheBuffer = nullptr; +    bool mShuttingDown = false;  }; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 64ea1710f5..d8e05e1d01 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -132,20 +132,21 @@ std::string getLodSuffix(S32 lod)      return suffix;  } -void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut) +static bool FindModel(const LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut)  { -    for (auto scene_iter = scene.begin(); scene_iter != scene.end(); scene_iter++) +    for (const auto& scene_pair : scene)      { -        for (auto model_iter = scene_iter->second.begin(); model_iter != scene_iter->second.end(); model_iter++) +        for (const auto& model_iter : scene_pair.second)          { -            if (model_iter->mModel && (model_iter->mModel->mLabel == name_to_match)) +            if (model_iter.mModel && (model_iter.mModel->mLabel == name_to_match))              { -                baseModelOut = model_iter->mModel; -                matOut = scene_iter->first; -                return; +                baseModelOut = model_iter.mModel; +                matOut = scene_pair.first; +                return true;              }          }      } +    return false;  }  //----------------------------------------------------------------------------- @@ -319,10 +320,8 @@ void LLModelPreview::rebuildUploadData()          mat *= scale_mat; -        for (auto model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) -        { // for each instance with said transform applied -            LLModelInstance instance = *model_iter; - +        for (LLModelInstance& instance : iter->second) +        { //for each instance with said transform applied              LLModel* base_model = instance.mModel;              if (base_model && !requested_name.empty()) @@ -354,7 +353,7 @@ void LLModelPreview::rebuildUploadData()                      }                      else                      { -                        //Physics can be inherited from other LODs or loaded, so we need to adjust what extension we are searching for +                        // Physics can be inherited from other LODs or loaded, so we need to adjust what extension we are searching for                          extensionLOD = mPhysicsSearchLOD;                      } @@ -365,9 +364,9 @@ void LLModelPreview::rebuildUploadData()                          name_to_match += toAdd;                      } -                    FindModel(mScene[i], name_to_match, lod_model, transform); +                    bool found = FindModel(mScene[i], name_to_match, lod_model, transform); -                    if (!lod_model && i != LLModel::LOD_PHYSICS) +                    if (!found && i != LLModel::LOD_PHYSICS)                      {                          if (mImporterDebug)                          { @@ -380,7 +379,7 @@ void LLModelPreview::rebuildUploadData()                          }                          int searchLOD = (i > LLModel::LOD_HIGH) ? LLModel::LOD_HIGH : i; -                        while ((searchLOD <= LLModel::LOD_HIGH) && !lod_model) +                        for (; searchLOD <= LLModel::LOD_HIGH; ++searchLOD)                          {                              std::string name_to_match = instance.mLabel;                              llassert(!name_to_match.empty()); @@ -394,8 +393,8 @@ void LLModelPreview::rebuildUploadData()                              // See if we can find an appropriately named model in LOD 'searchLOD'                              // -                            FindModel(mScene[searchLOD], name_to_match, lod_model, transform); -                            searchLOD++; +                            if (FindModel(mScene[searchLOD], name_to_match, lod_model, transform)) +                                break;                          }                      }                  } @@ -1174,8 +1173,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)                          LLModel* found_model = NULL;                          LLMatrix4 transform; -                        FindModel(mBaseScene, loaded_name, found_model, transform); -                        if (found_model) +                        if (FindModel(mBaseScene, loaded_name, found_model, transform))                          { // don't rename correctly named models (even if they are placed in a wrong order)                              name_based = true;                          } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 6e666b8a4b..9d8493549d 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -819,6 +819,50 @@ void LLOutfitListBase::observerCallback(const LLUUID& category_id)      refreshList(category_id);  } +class LLIsOutfitListFolder : public LLInventoryCollectFunctor +{ +public: +    LLIsOutfitListFolder() +    { +        mOutfitsId = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +    } +    virtual ~LLIsOutfitListFolder() {} + +    bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override +    { +        if (cat) +        { +            if (cat->getPreferredType() == LLFolderType::FT_OUTFIT) +            { +                return true; +            } +            if (cat->getPreferredType() == LLFolderType::FT_NONE +                && cat->getParentUUID() == mOutfitsId) +            { +                LLViewerInventoryCategory* inv_cat = dynamic_cast<LLViewerInventoryCategory*>(cat); +                if (inv_cat && inv_cat->getDescendentCount() > 3) +                { +                    LLInventoryModel::cat_array_t* cats; +                    LLInventoryModel::item_array_t* items; +                    gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items); +                    if (cats->empty() // protection against outfits inside +                        && items->size() > 3) // eyes, skin, hair and shape are required +                    { +                        // For now assume this to be an old style outfit, not a subfolder +                        // but ideally no such 'outfits' should be left in My Outfits +                        // Todo: stop counting FT_NONE as outfits, +                        // convert obvious outfits into FT_OUTFIT +                        return true; +                    } +                } +            } +        } +        return false; +    } +protected: +    LLUUID mOutfitsId; +}; +  void LLOutfitListBase::refreshList(const LLUUID& category_id)  {      bool wasNull = mRefreshListState.CategoryUUID.isNull(); @@ -828,13 +872,13 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)      LLInventoryModel::item_array_t item_array;      // Collect all sub-categories of a given category. -    LLIsType is_category(LLAssetType::AT_CATEGORY); +    LLIsOutfitListFolder is_outfit;      gInventory.collectDescendentsIf(          category_id,          cat_array,          item_array,          LLInventoryModel::EXCLUDE_TRASH, -        is_category); +        is_outfit);      // Memorize item names for each UUID      std::map<LLUUID, std::string> names; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 4ada9c445c..3a164ec94b 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3644,7 +3644,7 @@ void LLPanelFace::onCommitRepeatsPerMeter()      bool identical_scale_t = false;      LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); -    LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); +    LLSelectedTE::getObjectScaleT(obj_scale_t, identical_scale_t);      if (gSavedSettings.getBOOL("SyncMaterialSettings"))      { @@ -5151,6 +5151,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool              LLMaterial* mat = object->getTE(face)->getMaterialParams().get();              U32 s_axis = VX;              U32 t_axis = VY; +            LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);              F32 repeats_s = 1.0f;              F32 repeats_t = 1.0f;              if (mat) @@ -5175,6 +5176,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool&              LLMaterial* mat = object->getTE(face)->getMaterialParams().get();              U32 s_axis = VX;              U32 t_axis = VY; +            LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);              F32 repeats_s = 1.0f;              F32 repeats_t = 1.0f;              if (mat) diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 7b562337a3..b1c8b5f36a 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -777,7 +777,7 @@ void LLPanelPrimMediaControls::draw()      else if(mFadeTimer.getStarted())      {          F32 time = mFadeTimer.getElapsedTimeF32(); -        alpha *= llmax(lerp(1.0f, 0.0f, time / mControlFadeTime), 0.0f); +        alpha *= llmax(lerp(1.f, 0.f, time / mControlFadeTime), 0.0f);          if(time >= mControlFadeTime)          { diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h index 42cd5f8975..2e6b7c4428 100644 --- a/indra/newview/llpanelprofileclassifieds.h +++ b/indra/newview/llpanelprofileclassifieds.h @@ -157,17 +157,17 @@ public:      void setParcelId(const LLUUID& id) { mParcelId = id; } -    LLUUID getParcelId() { return mParcelId; } +    LLUUID getParcelId() const { return mParcelId; }      void setSimName(const std::string& sim_name) { mSimName = sim_name; } -    std::string getSimName() { return mSimName; } +    std::string getSimName() const { return mSimName; }      void setFromSearch(bool val) { mFromSearch = val; } -    bool fromSearch() { return mFromSearch; } +    bool fromSearch() const { return mFromSearch; } -    bool getInfoLoaded() { return mInfoLoaded; } +    bool getInfoLoaded() const { return mInfoLoaded; }      void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; } @@ -175,9 +175,9 @@ public:      void resetDirty() override; -    bool isNew() { return mIsNew; } +    bool isNew() const { return mIsNew; } -    bool isNewWithErrors() { return mIsNewWithErrors; } +    bool isNewWithErrors() const { return mIsNewWithErrors; }      bool canClose(); @@ -191,10 +191,10 @@ public:      bool getAutoRenew(); -    S32 getPriceForListing() { return mPriceForListing; } +    S32 getPriceForListing() const { return mPriceForListing; }      void setEditMode(bool edit_mode); -    bool getEditMode() {return mEditMode;} +    bool getEditMode() const { return mEditMode; }      static void setClickThrough(          const LLUUID& classified_id, diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp index 32c9f6f402..56c0294dbe 100644 --- a/indra/newview/llpanelsnapshot.cpp +++ b/indra/newview/llpanelsnapshot.cpp @@ -37,6 +37,7 @@  // newview  #include "llsidetraypanelcontainer.h" +#include "llsnapshotlivepreview.h"  #include "llviewercontrol.h" // gSavedSettings  #include "llagentbenefits.h" @@ -99,6 +100,17 @@ void LLPanelSnapshot::onOpen(const LLSD& key)      {          getParentByType<LLFloater>()->notify(LLSD().with("image-format-change", true));      } + +    // If resolution is set to "Current Window", force a snapshot update +    // each time a snapshot panel is opened to determine the correct +    // image size (and upload fee) depending on the snapshot type. +    if (mSnapshotFloater && getChild<LLUICtrl>(getImageSizeComboName())->getValue().asString() == "[i0,i0]") +    { +        if (LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView()) +        { +            preview->mForceUpdateSnapshot = true; +        } +    }  }  LLSnapshotModel::ESnapshotFormat LLPanelSnapshot::getImageFormat() const diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp index 96b17acc40..b81b891685 100644 --- a/indra/newview/llpanelsnapshotinventory.cpp +++ b/indra/newview/llpanelsnapshotinventory.cpp @@ -42,77 +42,35 @@  /**   * The panel provides UI for saving snapshot as an inventory texture.   */ -class LLPanelSnapshotInventoryBase -    : public LLPanelSnapshot -{ -    LOG_CLASS(LLPanelSnapshotInventoryBase); - -public: -    LLPanelSnapshotInventoryBase(); - -    /*virtual*/ bool postBuild(); -protected: -    void onSend(); -    /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); -}; -  class LLPanelSnapshotInventory -    : public LLPanelSnapshotInventoryBase +    : public LLPanelSnapshot  {      LOG_CLASS(LLPanelSnapshotInventory);  public:      LLPanelSnapshotInventory(); -    /*virtual*/ bool postBuild(); -    /*virtual*/ void onOpen(const LLSD& key); +    bool postBuild() override; +    void onOpen(const LLSD& key) override;      void onResolutionCommit(LLUICtrl* ctrl);  private: -    /*virtual*/ std::string getWidthSpinnerName() const     { return "inventory_snapshot_width"; } -    /*virtual*/ std::string getHeightSpinnerName() const    { return "inventory_snapshot_height"; } -    /*virtual*/ std::string getAspectRatioCBName() const    { return "inventory_keep_aspect_check"; } -    /*virtual*/ std::string getImageSizeComboName() const   { return "texture_size_combo"; } -    /*virtual*/ std::string getImageSizePanelName() const   { return LLStringUtil::null; } -    /*virtual*/ void updateControls(const LLSD& info); - -}; - -class LLPanelOutfitSnapshotInventory -    : public LLPanelSnapshotInventoryBase -{ -    LOG_CLASS(LLPanelOutfitSnapshotInventory); - -public: -    LLPanelOutfitSnapshotInventory(); -        /*virtual*/ bool postBuild(); -        /*virtual*/ void onOpen(const LLSD& key); +    std::string getWidthSpinnerName() const override   { return "inventory_snapshot_width"; } +    std::string getHeightSpinnerName() const override  { return "inventory_snapshot_height"; } +    std::string getAspectRatioCBName() const override  { return "inventory_keep_aspect_check"; } +    std::string getImageSizeComboName() const override { return "texture_size_combo"; } +    std::string getImageSizePanelName() const override { return LLStringUtil::null; } +    LLSnapshotModel::ESnapshotType getSnapshotType() override; +    void updateControls(const LLSD& info) override; -private: -    /*virtual*/ std::string getWidthSpinnerName() const     { return ""; } -    /*virtual*/ std::string getHeightSpinnerName() const    { return ""; } -    /*virtual*/ std::string getAspectRatioCBName() const    { return ""; } -    /*virtual*/ std::string getImageSizeComboName() const   { return "texture_size_combo"; } -    /*virtual*/ std::string getImageSizePanelName() const   { return LLStringUtil::null; } -    /*virtual*/ void updateControls(const LLSD& info); - -    /*virtual*/ void cancel(); +    void onSend(); +    void updateUploadCost(); +    S32 calculateUploadCost();  };  static LLPanelInjector<LLPanelSnapshotInventory> panel_class1("llpanelsnapshotinventory"); -static LLPanelInjector<LLPanelOutfitSnapshotInventory> panel_class2("llpaneloutfitsnapshotinventory"); - -LLPanelSnapshotInventoryBase::LLPanelSnapshotInventoryBase() -{ -} - -bool LLPanelSnapshotInventoryBase::postBuild() -{ -    return LLPanelSnapshot::postBuild(); -} - -LLSnapshotModel::ESnapshotType LLPanelSnapshotInventoryBase::getSnapshotType() +LLSnapshotModel::ESnapshotType LLPanelSnapshotInventory::getSnapshotType()  {      return LLSnapshotModel::SNAPSHOT_TEXTURE;  } @@ -130,12 +88,14 @@ bool LLPanelSnapshotInventory::postBuild()      getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(false);      getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshotInventory::onResolutionCommit, this, _1)); -    return LLPanelSnapshotInventoryBase::postBuild(); +    return LLPanelSnapshot::postBuild();  }  // virtual  void LLPanelSnapshotInventory::onOpen(const LLSD& key)  { +    updateUploadCost(); +      LLPanelSnapshot::onOpen(key);  } @@ -144,6 +104,8 @@ void LLPanelSnapshotInventory::updateControls(const LLSD& info)  {      const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true;      getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot); + +    updateUploadCost();  }  void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl) @@ -153,21 +115,9 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)      getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected);  } -void LLPanelSnapshotInventoryBase::onSend() +void LLPanelSnapshotInventory::onSend()  { -    S32 w = 0; -    S32 h = 0; - -    if( mSnapshotFloater ) -    { -        LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView(); -        if( preview ) -        { -            preview->getSize(w, h); -        } -    } - -    S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(w, h); +    S32 expected_upload_cost = calculateUploadCost();      if (can_afford_transaction(expected_upload_cost))      {          if (mSnapshotFloater) @@ -188,36 +138,24 @@ void LLPanelSnapshotInventoryBase::onSend()      }  } -LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory() +void LLPanelSnapshotInventory::updateUploadCost()  { -    mCommitCallbackRegistrar.add("Inventory.SaveOutfitPhoto", boost::bind(&LLPanelOutfitSnapshotInventory::onSend, this)); -    mCommitCallbackRegistrar.add("Inventory.SaveOutfitCancel", boost::bind(&LLPanelOutfitSnapshotInventory::cancel, this)); +    getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", calculateUploadCost()));  } -// virtual -bool LLPanelOutfitSnapshotInventory::postBuild() +S32 LLPanelSnapshotInventory::calculateUploadCost()  { -    return LLPanelSnapshotInventoryBase::postBuild(); -} - -// virtual -void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key) -{ -    getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost())); -    LLPanelSnapshot::onOpen(key); -} - -// virtual -void LLPanelOutfitSnapshotInventory::updateControls(const LLSD& info) -{ -    const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true; -    getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot); -} +    S32 w = 0; +    S32 h = 0; -void LLPanelOutfitSnapshotInventory::cancel() -{      if (mSnapshotFloater)      { -        mSnapshotFloater->closeFloater(); +        if (LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView()) +        { +            w = preview->getEncodedImageWidth(); +            h = preview->getEncodedImageHeight(); +        }      } + +    return LLAgentBenefitsMgr::current().getTextureUploadCost(w, h);  } diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp index 366030c0fa..57759fbcaa 100644 --- a/indra/newview/llpanelsnapshotlocal.cpp +++ b/indra/newview/llpanelsnapshotlocal.cpp @@ -47,18 +47,18 @@ class LLPanelSnapshotLocal  public:      LLPanelSnapshotLocal(); -    /*virtual*/ bool postBuild(); -    /*virtual*/ void onOpen(const LLSD& key); +    bool postBuild() override; +    void onOpen(const LLSD& key) override;  private: -    /*virtual*/ std::string getWidthSpinnerName() const     { return "local_snapshot_width"; } -    /*virtual*/ std::string getHeightSpinnerName() const    { return "local_snapshot_height"; } -    /*virtual*/ std::string getAspectRatioCBName() const    { return "local_keep_aspect_check"; } -    /*virtual*/ std::string getImageSizeComboName() const   { return "local_size_combo"; } -    /*virtual*/ std::string getImageSizePanelName() const   { return "local_image_size_lp"; } -    /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const; -    /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); -    /*virtual*/ void updateControls(const LLSD& info); +    std::string getWidthSpinnerName() const  override  { return "local_snapshot_width"; } +    std::string getHeightSpinnerName() const override  { return "local_snapshot_height"; } +    std::string getAspectRatioCBName() const override  { return "local_keep_aspect_check"; } +    std::string getImageSizeComboName() const override { return "local_size_combo"; } +    std::string getImageSizePanelName() const override { return "local_image_size_lp"; } +    LLSnapshotModel::ESnapshotFormat getImageFormat() const override; +    LLSnapshotModel::ESnapshotType getSnapshotType() override; +    void updateControls(const LLSD& info) override;      S32 mLocalFormat; diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp index 962d3bba16..05cd9e7b3a 100644 --- a/indra/newview/llpanelsnapshotoptions.cpp +++ b/indra/newview/llpanelsnapshotoptions.cpp @@ -30,12 +30,8 @@  #include "llsidetraypanelcontainer.h"  #include "llfloatersnapshot.h" // FIXME: create a snapshot model -#include "llsnapshotlivepreview.h"  #include "llfloaterreg.h" -#include "llagentbenefits.h" - -  /**   * Provides several ways to save a snapshot.   */ @@ -46,12 +42,9 @@ class LLPanelSnapshotOptions  public:      LLPanelSnapshotOptions(); -    ~LLPanelSnapshotOptions(); -    /*virtual*/ bool postBuild(); -    /*virtual*/ void onOpen(const LLSD& key); +    bool postBuild() override;  private: -    void updateUploadCost();      void openPanel(const std::string& panel_name);      void onSaveToProfile();      void onSaveToEmail(); @@ -71,10 +64,6 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()      mCommitCallbackRegistrar.add("Snapshot.SaveToComputer",     boost::bind(&LLPanelSnapshotOptions::onSaveToComputer,  this));  } -LLPanelSnapshotOptions::~LLPanelSnapshotOptions() -{ -} -  // virtual  bool LLPanelSnapshotOptions::postBuild()  { @@ -82,30 +71,6 @@ bool LLPanelSnapshotOptions::postBuild()      return LLPanel::postBuild();  } -// virtual -void LLPanelSnapshotOptions::onOpen(const LLSD& key) -{ -    updateUploadCost(); -} - -void LLPanelSnapshotOptions::updateUploadCost() -{ -    S32 w = 0; -    S32 h = 0; - -    if( mSnapshotFloater ) -    { -        LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView(); -        if( preview ) -        { -            preview->getSize(w, h); -        } -    } - -    S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(w, h); -    getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost)); -} -  void LLPanelSnapshotOptions::openPanel(const std::string& panel_name)  {      LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp index 23e8789e3f..f3dfdc9250 100644 --- a/indra/newview/llpanelsnapshotpostcard.cpp +++ b/indra/newview/llpanelsnapshotpostcard.cpp @@ -56,18 +56,18 @@ class LLPanelSnapshotPostcard  public:      LLPanelSnapshotPostcard(); -    /*virtual*/ bool postBuild(); -    /*virtual*/ void onOpen(const LLSD& key); +    bool postBuild() override; +    void onOpen(const LLSD& key) override;  private: -    /*virtual*/ std::string getWidthSpinnerName() const     { return "postcard_snapshot_width"; } -    /*virtual*/ std::string getHeightSpinnerName() const    { return "postcard_snapshot_height"; } -    /*virtual*/ std::string getAspectRatioCBName() const    { return "postcard_keep_aspect_check"; } -    /*virtual*/ std::string getImageSizeComboName() const   { return "postcard_size_combo"; } -    /*virtual*/ std::string getImageSizePanelName() const   { return "postcard_image_size_lp"; } -    /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; } -    /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); -    /*virtual*/ void updateControls(const LLSD& info); +    std::string getWidthSpinnerName() const override   { return "postcard_snapshot_width"; } +    std::string getHeightSpinnerName() const override  { return "postcard_snapshot_height"; } +    std::string getAspectRatioCBName() const override  { return "postcard_keep_aspect_check"; } +    std::string getImageSizeComboName() const override { return "postcard_size_combo"; } +    std::string getImageSizePanelName() const override { return "postcard_image_size_lp"; } +    LLSnapshotModel::ESnapshotFormat getImageFormat() const override { return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; } +    LLSnapshotModel::ESnapshotType getSnapshotType() override; +    void updateControls(const LLSD& info) override;      bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);      static void sendPostcardFinished(LLSD result); diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp index aa257dea9e..b533d7bbbc 100644 --- a/indra/newview/llpanelsnapshotprofile.cpp +++ b/indra/newview/llpanelsnapshotprofile.cpp @@ -49,17 +49,17 @@ class LLPanelSnapshotProfile  public:      LLPanelSnapshotProfile(); -    /*virtual*/ bool postBuild(); -    /*virtual*/ void onOpen(const LLSD& key); +    bool postBuild() override; +    void onOpen(const LLSD& key) override;  private: -    /*virtual*/ std::string getWidthSpinnerName() const     { return "profile_snapshot_width"; } -    /*virtual*/ std::string getHeightSpinnerName() const    { return "profile_snapshot_height"; } -    /*virtual*/ std::string getAspectRatioCBName() const    { return "profile_keep_aspect_check"; } -    /*virtual*/ std::string getImageSizeComboName() const   { return "profile_size_combo"; } -    /*virtual*/ std::string getImageSizePanelName() const   { return "profile_image_size_lp"; } -    /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; } -    /*virtual*/ void updateControls(const LLSD& info); +    std::string getWidthSpinnerName() const override   { return "profile_snapshot_width"; } +    std::string getHeightSpinnerName() const override  { return "profile_snapshot_height"; } +    std::string getAspectRatioCBName() const override  { return "profile_keep_aspect_check"; } +    std::string getImageSizeComboName() const override { return "profile_size_combo"; } +    std::string getImageSizePanelName() const override { return "profile_image_size_lp"; } +    LLSnapshotModel::ESnapshotFormat getImageFormat() const override { return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; } +    void updateControls(const LLSD& info) override;      void onSend();  }; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 951dc45a78..2fbdbeaf59 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -576,32 +576,48 @@ void LLPanelVolume::getState( )              return object->getMaterial();          }      } func; -    bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); +    LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); +    bool material_same = selection->getSelectedTEValue( &func, material_code );      std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); -    if (editable && single_volume && material_same) + +    bool enable_material = editable && single_volume && material_same; +    LLCachedControl<bool> edit_linked(gSavedSettings, "EditLinkedParts", false); +    if (!enable_material && !edit_linked())      { -        mComboMaterial->setEnabled( true ); -        if (material_code == LL_MCODE_LIGHT) +        LLViewerObject* root = selection->getPrimaryObject(); +        while (root && !root->isAvatar() && root->getParent())          { -            if (mComboMaterial->getItemCount() == mComboMaterialItemCount) +            LLViewerObject* parent = (LLViewerObject*)root->getParent(); +            if (parent->isAvatar())              { -                mComboMaterial->add(LEGACY_FULLBRIGHT_DESC); +                break;              } -            mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC); +            root = parent;          } -        else +        if (root)          { -            if (mComboMaterial->getItemCount() != mComboMaterialItemCount) -            { -                mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC); -            } +            material_code = root->getMaterial(); +        } +    } -            mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code))); +    mComboMaterial->setEnabled(enable_material); + +    if (material_code == LL_MCODE_LIGHT) +    { +        if (mComboMaterial->getItemCount() == mComboMaterialItemCount) +        { +            mComboMaterial->add(LEGACY_FULLBRIGHT_DESC);          } +        mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC);      }      else      { -        mComboMaterial->setEnabled( false ); +        if (mComboMaterial->getItemCount() != mComboMaterialItemCount) +        { +            mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC); +        } + +        mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code)));      }      // Physics properties diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 86291708b0..e5c84728fe 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -646,18 +646,17 @@ bool LLPhysicsMotion::onUpdate(F32 time)              velocity_new_local = 0;          } -        // Check for NaN values.  A NaN value is detected if the variables doesn't equal itself. -        // If NaN, then reset everything. -        if ((mPosition_local != mPosition_local) || -            (mVelocity_local != mVelocity_local) || -            (position_new_local != position_new_local)) +        // Check for NaN values. If NaN, then reset everything. +        if (llisnan(mPosition_local) || +            llisnan(mVelocity_local) || +            llisnan(position_new_local))          { -            position_new_local = 0; -            mVelocity_local = 0; -            mVelocityJoint_local = 0; -            mAccelerationJoint_local = 0; -            mPosition_local = 0; -            mPosition_world = LLVector3(0,0,0); +            position_new_local = 0.f; +            mVelocity_local = 0.f; +            mVelocityJoint_local = 0.f; +            mAccelerationJoint_local = 0.f; +            mPosition_local = 0.f; +            mPosition_world = LLVector3(0.f,0.f,0.f);          }          const F32 position_new_local_clamped = llclamp(position_new_local, diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 02a4c7fb26..c2aa4925bd 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -703,9 +703,10 @@ void LLScriptEdCore::sync()      }  } -bool LLScriptEdCore::hasChanged() +bool LLScriptEdCore::hasChanged() const  { -    if (!mEditor) return false; +    if (!mEditor) +        return false;      return ((!mEditor->isPristine() || mEnableSave) && mHasScriptData);  } diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 70ee1a4274..0bbe540207 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -143,7 +143,7 @@ public:      void            setItemRemoved(bool script_removed){mScriptRemoved = script_removed;};      void            setAssetID( const LLUUID& asset_id){ mAssetID = asset_id; }; -    LLUUID          getAssetID() { return mAssetID; } +    LLUUID          getAssetID() const { return mAssetID; }      bool isFontSizeChecked(const LLSD &userdata);      void onChangeFontSize(const LLSD &size_name); @@ -155,7 +155,7 @@ public:      void        onBtnDynamicHelp();      void        onBtnUndoChanges(); -    bool        hasChanged(); +    bool        hasChanged() const;      void selectFirstError(); @@ -211,7 +211,6 @@ class LLScriptEdContainer : public LLPreview  public:      LLScriptEdContainer(const LLSD& key); -    LLScriptEdContainer(const LLSD& key, const bool live);      bool handleKeyHere(KEY key, MASK mask); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 1876cd3086..41895d7d6a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3139,6 +3139,8 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch)                      F32 scale_x = 1;                      F32 scale_y = 1; +                    F32 offset_x = 0; +                    F32 offset_y = 0;                      for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)                      { @@ -3155,6 +3157,21 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch)                              scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis];                          }                          material->mTextureTransform[i].mScale.set(scale_x, scale_y); + +                        LLVector2 scales = selectNode->mGLTFScales[te_num][i]; +                        LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; +                        F64 int_part = 0; +                        offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); +                        if (offset_x < 0) +                        { +                            offset_x++; +                        } +                        offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); +                        if (offset_y < 0) +                        { +                            offset_y++; +                        } +                        material->mTextureTransform[i].mOffset.set(offset_x, offset_y);                      }                      const LLGLTFMaterial* base_material = tep->getGLTFMaterial(); @@ -6909,6 +6926,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)  {      mTextureScaleRatios.clear();      mGLTFScaleRatios.clear(); +    mGLTFScales.clear(); +    mGLTFOffsets.clear();      if (mObject.notNull())      { @@ -6949,6 +6968,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)              F32 scale_x = 1;              F32 scale_y = 1;              std::vector<LLVector3> material_v_vec; +            std::vector<LLVector2> material_scales_vec; +            std::vector<LLVector2> material_offset_vec;              for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)              {                  if (material) @@ -6956,12 +6977,16 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)                      LLGLTFMaterial::TextureTransform& transform = material->mTextureTransform[i];                      scale_x = transform.mScale[VX];                      scale_y = transform.mScale[VY]; +                    material_scales_vec.push_back(transform.mScale); +                    material_offset_vec.push_back(transform.mOffset);                  }                  else                  {                      // Not having an override doesn't mean that there is no material                      scale_x = 1;                      scale_y = 1; +                    material_scales_vec.emplace_back(scale_x, scale_y); +                    material_offset_vec.emplace_back(0.f, 0.f);                  }                  if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR) @@ -6977,6 +7002,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)                  material_v_vec.push_back(material_v);              }              mGLTFScaleRatios.push_back(material_v_vec); +            mGLTFScales.push_back(material_scales_vec); +            mGLTFOffsets.push_back(material_offset_vec);          }      }  } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 0dbdc133e3..792a37297f 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -242,6 +242,8 @@ public:      gltf_materials_vec_t mSavedGLTFOverrideMaterials;      std::vector<LLVector3>  mTextureScaleRatios;      std::vector< std::vector<LLVector3> >  mGLTFScaleRatios; +    std::vector< std::vector<LLVector2> >  mGLTFScales; +    std::vector< std::vector<LLVector2> >  mGLTFOffsets;      std::vector<LLVector3>  mSilhouetteVertices;    // array of vertices to render silhouette of object      std::vector<LLVector3>  mSilhouetteNormals; // array of normals to render silhouette of object      bool                    mSilhouetteExists;  // need to generate silhouette? diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index ea95d71b27..68b4ab381a 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -694,6 +694,7 @@ bool LLSnapshotLivePreview::onIdle( void* snapshot_preview )      static LLCachedControl<bool> freeze_time(gSavedSettings, "FreezeTime", false);      static LLCachedControl<bool> use_freeze_frame(gSavedSettings, "UseFreezeFrame", false);      static LLCachedControl<bool> render_ui(gSavedSettings, "RenderUIInSnapshot", false); +    static LLCachedControl<bool> render_balance(gSavedSettings, "RenderBalanceInSnapshot", false);      static LLCachedControl<bool> render_hud(gSavedSettings, "RenderHUDInSnapshot", false);      static LLCachedControl<bool> render_no_post(gSavedSettings, "RenderSnapshotNoPost", false); @@ -750,6 +751,7 @@ bool LLSnapshotLivePreview::onIdle( void* snapshot_preview )                  render_hud,                  false,                  render_no_post, +                render_balance,                  previewp->mSnapshotBufferType,                  previewp->getMaxImageSize()))          { diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 1bab602364..bda75c16e7 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -759,6 +759,10 @@ void LLStatusBar::updateBalancePanelPosition()      balance_bg_view->setShape(balance_bg_rect);  } +void LLStatusBar::setBalanceVisible(bool visible) +{ +    mBoxBalance->setVisible(visible); +}  // Implements secondlife:///app/balance/request to request a L$ balance  // update via UDP message system. JC diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 7e1ecf08ca..86c1ccd051 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -93,6 +93,8 @@ public:      S32 getSquareMetersCommitted() const;      S32 getSquareMetersLeft() const; +    void setBalanceVisible(bool visible); +      LLPanelNearByMedia* getNearbyMediaPanel() { return mPanelNearByMedia; }  private: diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 4315c4c6b0..6f99da5957 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -201,7 +201,7 @@ LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const  void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal, -                          LLVector2 *tex1) const +                          LLVector2* tex0, LLVector2 *tex1) const  {      if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge() || !mVObjp)      { @@ -210,6 +210,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3      llassert_always(vertex && normal && tex1);      U32 surface_stride = mSurfacep->getGridsPerEdge(); +    U32 texture_stride = mSurfacep->getGridsPerEdge() - 1;      U32 point_offset = x + y*surface_stride;      *normal = getNormal(x, y); @@ -220,6 +221,12 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3      pos_agent.mV[VZ]  = *(mDataZ + point_offset);      *vertex     = pos_agent-mVObjp->getRegion()->getOriginAgent(); +    // tex0 is used for ownership overlay +    LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); +    LLVector3 tex_pos = rel_pos * (1.f / (texture_stride * mSurfacep->getMetersPerGrid())); +    tex0->mV[0] = tex_pos.mV[0]; +    tex0->mV[1] = tex_pos.mV[1]; +      tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y);      const F32 xyScale = 4.9215f*7.f; //0.93284f; diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index f4831487c1..505fc8c24c 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -116,7 +116,7 @@ public:      void calcNormalFlat(LLVector3& normal_out, const U32 x, const U32 y, const U32 index /* 0 or 1 */);      void eval(const U32 x, const U32 y, const U32 stride, -                LLVector3 *vertex, LLVector3 *normal, LLVector2 *tex1) const; +                LLVector3 *vertex, LLVector3 *normal, LLVector2* tex0, LLVector2 *tex1) const; diff --git a/indra/newview/llterrainpaintmap.cpp b/indra/newview/llterrainpaintmap.cpp index 8ccde74c93..c7a82013e4 100644 --- a/indra/newview/llterrainpaintmap.cpp +++ b/indra/newview/llterrainpaintmap.cpp @@ -204,8 +204,9 @@ bool LLTerrainPaintMap::bakeHeightNoiseIntoPBRPaintMapRGB(const LLViewerRegion&                      {                          LLVector3 scratch3;                          LLVector3 pos3; +                        LLVector2 tex0_temp;                          LLVector2 tex1_temp; -                        patch->eval(i, j, stride, &pos3, &scratch3, &tex1_temp); +                        patch->eval(i, j, stride, &pos3, &scratch3, &tex0_temp, &tex1_temp);                          (*pos++).set(pos3.mV[VX], pos3.mV[VY], pos3.mV[VZ]);                          *tex1++ = tex1_temp;                          vertex_total++; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index be7653c011..442c627d07 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1347,27 +1347,39 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)      }      for (U32 idx=0; idx<num_entries; idx++)      { -        Entry entry; -        S32 bytes_read = aprfile->read((void*)(&entry), (S32)sizeof(Entry)); -        if (bytes_read < sizeof(Entry)) +        try +        { +            Entry entry; +            S32 bytes_read = aprfile->read((void*)(&entry), (S32)sizeof(Entry)); +            if (bytes_read < sizeof(Entry)) +            { +                LL_WARNS() << "Corrupted header entries, failed at " << idx << " / " << num_entries << LL_ENDL; +                return 0; +            } +            entries.push_back(entry); +            //      LL_INFOS() << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << LL_ENDL; +            if (entry.mImageSize > entry.mBodySize) +            { +                mHeaderIDMap[entry.mID] = idx; +                mTexturesSizeMap[entry.mID] = entry.mBodySize; +                mTexturesSizeTotal += entry.mBodySize; +            } +            else +            { +                mFreeList.insert(idx); +            } +        } +        catch (std::bad_alloc&)          { -            LL_WARNS() << "Corrupted header entries, failed at " << idx << " / " << num_entries << LL_ENDL; +            // Too little ram yet very large cache? +            // Should this actually crash viewer? +            entries.clear(); +            LL_WARNS() << "Bad alloc trying to read texture entries from cache, mFreeList: " << (S32)mFreeList.size() +                << ", added entries: " << idx << ", total entries: " << num_entries << LL_ENDL;              closeHeaderEntriesFile();              purgeAllTextures(false);              return 0;          } -        entries.push_back(entry); -//      LL_INFOS() << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << LL_ENDL; -        if(entry.mImageSize > entry.mBodySize) -        { -            mHeaderIDMap[entry.mID] = idx; -            mTexturesSizeMap[entry.mID] = entry.mBodySize; -            mTexturesSizeTotal += entry.mBodySize; -        } -        else -        { -            mFreeList.insert(idx); -        }      }      closeHeaderEntriesFile();      return num_entries; diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index b3b4f43e57..404297c58f 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -541,8 +541,8 @@ void audio_update_wind(bool force_update)          // whereas steady-state avatar walk velocity is only 3.2 m/s.          // Without this the world feels desolate on first login when you are          // standing still. -        const F32 WIND_LEVEL = 0.5f; -        LLVector3 scaled_wind_vec = gWindVec * WIND_LEVEL; +        static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f); +        LLVector3 scaled_wind_vec = gWindVec * wind_level;          // Mix in the avatar's motion, subtract because when you walk north,          // the apparent wind moves south. diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 24f1be3d1c..10fa0fd3cd 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -215,11 +215,15 @@ void display_update_camera()          final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance");      }      else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) -      {          final_far *= 0.5f;      } +    else if (LLViewerTexture::sDesiredDiscardBias > 2.f) +    { +        final_far = llmax(32.f, final_far / (LLViewerTexture::sDesiredDiscardBias - 1.f)); +    }      LLViewerCamera::getInstance()->setFar(final_far); +    LLVOAvatar::sRenderDistance = llclamp(final_far, 16.f, 256.f);      gViewerWindow->setup3DRender();      if (!gCubeSnapshot) diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index ce66dbc03f..9743ec0c59 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -932,6 +932,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t          bool render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");          bool render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");          bool render_no_post = gSavedSettings.getBOOL("RenderSnapshotNoPost"); +        bool render_balance = gSavedSettings.getBOOL("RenderBalanceInSnapshot");          bool high_res = gSavedSettings.getBOOL("HighResSnapshot");          if (high_res) @@ -952,6 +953,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t                                         render_hud,                                         false,                                         render_no_post, +                                       render_balance,                                         LLSnapshotModel::SNAPSHOT_TYPE_COLOR,                                         high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side          { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5fd820f91d..bdcfec34f6 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2137,6 +2137,21 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)      EInstantMessage dialog = (EInstantMessage)d;      LLHost sender = msg->getSender(); +    LLSD metadata; +    if (msg->getNumberOfBlocksFast(_PREHASH_MetaData) > 0) +    { +        S32 metadata_size = msg->getSizeFast(_PREHASH_MetaData, 0, _PREHASH_Data); +        std::string metadata_buffer; +        metadata_buffer.resize(metadata_size, 0); + +        msg->getBinaryDataFast(_PREHASH_MetaData, _PREHASH_Data, &metadata_buffer[0], metadata_size, 0, metadata_size ); +        std::stringstream metadata_stream(metadata_buffer); +        if (LLSDSerialize::fromBinary(metadata, metadata_stream, metadata_size) == LLSDParser::PARSE_FAILURE) +        { +            metadata.clear(); +        } +    } +      LLIMProcessing::processNewMessage(from_id,          from_group,          to_id, @@ -2151,7 +2166,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)          position,          binary_bucket,          binary_bucket_size, -        sender); +        sender, +        metadata);  }  void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id) @@ -5039,6 +5055,7 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)                                          false, //UI                                          gSavedSettings.getBOOL("RenderHUDInSnapshot"),                                          false, +                                        false,                                          LLSnapshotModel::SNAPSHOT_TYPE_COLOR,                                          LLSnapshotModel::SNAPSHOT_FORMAT_PNG);          } @@ -5144,6 +5161,7 @@ static void process_special_alert_messages(const std::string & message)                                      false,                                      gSavedSettings.getBOOL("RenderHUDInSnapshot"),                                      false, +                                    false,                                      LLSnapshotModel::SNAPSHOT_TYPE_COLOR,                                      LLSnapshotModel::SNAPSHOT_FORMAT_PNG);      } @@ -6641,7 +6659,6 @@ void process_initiate_download(LLMessageSystem* msg, void**)          (void**)new std::string(viewer_filename));  } -  void process_script_teleport_request(LLMessageSystem* msg, void**)  {      if (!gSavedSettings.getBOOL("ScriptsCanShowUI")) return; @@ -6655,6 +6672,11 @@ void process_script_teleport_request(LLMessageSystem* msg, void**)      msg->getString("Data", "SimName", sim_name);      msg->getVector3("Data", "SimPosition", pos);      msg->getVector3("Data", "LookAt", look_at); +    U32 flags = (BEACON_SHOW_MAP | BEACON_FOCUS_MAP); +    if (msg->has("Options")) +    { +        msg->getU32("Options", "Flags", flags); +    }      LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();      if(instance) @@ -6665,7 +6687,13 @@ void process_script_teleport_request(LLMessageSystem* msg, void**)              << LL_ENDL;          instance->trackURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]); -        LLFloaterReg::showInstance("world_map", "center"); +        if (flags & BEACON_SHOW_MAP) +        { +            bool old_auto_focus = instance->getAutoFocus(); +            instance->setAutoFocus(flags & BEACON_FOCUS_MAP); +            instance->openFloater("center"); +            instance->setAutoFocus(old_auto_focus); +        }      }      // remove above two lines and replace with below line diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index c5e81dd179..8d90187e91 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2325,6 +2325,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,          // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega)          setRotation(new_rot * mAngularVelocityRot); +        if ((mFlags & FLAGS_SERVER_AUTOPILOT) && asAvatar() && asAvatar()->isSelf()) +        { +            gAgent.resetAxes(); +            gAgent.rotate(new_rot); +            gAgentCamera.resetView(); +        }          setChanged(ROTATED | SILHOUETTE);      } diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 8e6657b4b9..432da2e990 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -42,6 +42,7 @@  // Viewer includes  #include "llagent.h"  #include "llagentaccess.h" +#include "llcallbacklist.h"  #include "llviewerparcelaskplay.h"  #include "llviewerwindow.h"  #include "llviewercontrol.h" @@ -1327,12 +1328,12 @@ const S32 LLViewerParcelMgr::getAgentParcelId() const      return INVALID_PARCEL_ID;  } -void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region) +void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel)  {      if(!parcel)          return; -    LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); +    LLViewerRegion *region = LLWorld::getInstance()->getRegionFromID(parcel->getRegionID());      if (!region)          return; @@ -1676,10 +1677,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use      // Actually extract the data.      if (parcel)      { +        // store region_id in the parcel so we can find it again later +        LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion(msg->getSender()); +        if (parcel_region) +        { +            parcel->setRegionID(parcel_region->getRegionID()); +        } +          if (local_id == parcel_mgr.mAgentParcel->getLocalID())          {              // Parcels in different regions can have same ids. -            LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion(msg->getSender());              LLViewerRegion* agent_region = gAgent.getRegion();              if (parcel_region && agent_region && parcel_region->getRegionID() == agent_region->getRegionID())              { @@ -1750,6 +1757,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use                  {                      instance->mTeleportFinishedSignal(instance->mTeleportInProgressPosition, false);                  } +                instance->postTeleportFinished(instance->mTeleportWithinRegion); +                instance->mTeleportWithinRegion = false;              }              parcel->setParcelEnvironmentVersion(parcel_environment_version);              LL_DEBUGS("ENVIRONMENT") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL; @@ -2719,6 +2728,8 @@ void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos          // Local teleport. We already have the agent parcel data.          // Emit the signal immediately.          getInstance()->mTeleportFinishedSignal(new_pos, local); + +        postTeleportFinished(true);      }      else      { @@ -2727,12 +2738,14 @@ void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos          // Let's wait for the update and then emit the signal.          mTeleportInProgressPosition = new_pos;          mTeleportInProgress = true; +        mTeleportWithinRegion = local;      }  }  void LLViewerParcelMgr::onTeleportFailed()  {      mTeleportFailedSignal(); +    LLEventPumps::instance().obtain("LLTeleport").post(llsd::map("success", false));  }  bool  LLViewerParcelMgr::getTeleportInProgress() @@ -2740,3 +2753,20 @@ bool  LLViewerParcelMgr::getTeleportInProgress()      return mTeleportInProgress // case where parcel data arrives after teleport          || gAgent.getTeleportState() > LLAgent::TELEPORT_NONE; // For LOCAL, no mTeleportInProgress  } + +void LLViewerParcelMgr::postTeleportFinished(bool local) +{ +    auto post = []() +    { +        LLEventPumps::instance().obtain("LLTeleport").post(llsd::map("success", true)); +    }; +    if (local) +    { +        static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay"); +        doAfterInterval(post, teleport_local_delay + 0.5f); +    } +    else +    { +        post(); +    } +} diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 974ea39359..1925cd23ed 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -219,7 +219,7 @@ public:      // containing the southwest corner of the selection.      // If want_reply_to_update, simulator will send back a ParcelProperties      // message. -    void    sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region = false); +    void    sendParcelPropertiesUpdate(LLParcel* parcel);      // Takes an Access List flag, like AL_ACCESS or AL_BAN      void    sendParcelAccessListUpdate(U32 which); @@ -295,6 +295,8 @@ public:      void onTeleportFailed();      bool getTeleportInProgress(); +    void postTeleportFinished(bool local); +      static bool isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power);      static bool isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power); @@ -344,7 +346,9 @@ private:      std::vector<LLParcelObserver*> mObservers; +    // Used to communicate between onTeleportFinished() and processParcelProperties()      bool                        mTeleportInProgress; +    bool                        mTeleportWithinRegion{ false };      LLVector3d                  mTeleportInProgressPosition;      teleport_finished_signal_t  mTeleportFinishedSignal;      teleport_failed_signal_t    mTeleportFailedSignal; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 40daac887d..f174e16624 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1447,6 +1447,15 @@ bool LLViewerTextureList::createUploadFile(const std::string& filename,          image->setLastError("Couldn't load the image to be uploaded.");          return false;      } + +    // calcDataSizeJ2C assumes maximum size is 2048 and for bigger images can +    // assign discard to bring imige to needed size, but upload does the scaling +    // as needed, so just reset discard. +    // Assume file is full and has 'discard' 0 data. +    // Todo: probably a better idea to have some setMaxDimentions in J2C +    // called when loading from a local file +    image->setDiscardLevel(0); +      // Decompress or expand it in a raw image structure      LLPointer<LLImageRaw> raw_image = new LLImageRaw;      if (!image->decode(raw_image, 0.0f)) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ef6409c23b..d32e3f4cbd 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4862,12 +4862,12 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height)      }  } -bool LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, bool show_ui, bool show_hud, bool do_rebuild, LLSnapshotModel::ESnapshotLayerType type, LLSnapshotModel::ESnapshotFormat format) +bool LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, bool show_ui, bool show_hud, bool do_rebuild, bool show_balance, LLSnapshotModel::ESnapshotLayerType type, LLSnapshotModel::ESnapshotFormat format)  {      LL_INFOS() << "Saving snapshot to: " << filepath << LL_ENDL;      LLPointer<LLImageRaw> raw = new LLImageRaw; -    bool success = rawSnapshot(raw, image_width, image_height, true, false, show_ui, show_hud, do_rebuild); +    bool success = rawSnapshot(raw, image_width, image_height, true, false, show_ui, show_hud, do_rebuild, show_balance);      if (success)      { @@ -4928,14 +4928,14 @@ void LLViewerWindow::resetSnapshotLoc() const  bool LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, bool show_ui, bool show_hud, bool do_rebuild, bool no_post, LLSnapshotModel::ESnapshotLayerType type)  { -    return rawSnapshot(raw, preview_width, preview_height, false, false, show_ui, show_hud, do_rebuild, no_post, type); +    return rawSnapshot(raw, preview_width, preview_height, false, false, show_ui, show_hud, do_rebuild, no_post, gSavedSettings.getBOOL("RenderBalanceInSnapshot"), type);  }  // Saves the image from the screen to a raw image  // Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy  // the results over to the final raw image.  bool LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, -    bool keep_window_aspect, bool is_texture, bool show_ui, bool show_hud, bool do_rebuild, bool no_post, LLSnapshotModel::ESnapshotLayerType type, S32 max_size) +    bool keep_window_aspect, bool is_texture, bool show_ui, bool show_hud, bool do_rebuild, bool no_post, bool show_balance, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)  {      if (!raw)      { @@ -4993,6 +4993,8 @@ bool LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei          // If the user wants the UI, limit the output size to the available screen size          image_width  = llmin(image_width, window_width);          image_height = llmin(image_height, window_height); + +        setBalanceVisible(show_balance);      }      S32 original_width = 0; @@ -5070,11 +5072,13 @@ bool LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei      }      else      { +        setBalanceVisible(true);          return false;      }      if (raw->isBufferInvalid())      { +        setBalanceVisible(true);          return false;      } @@ -5250,6 +5254,7 @@ bool LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei      {          send_agent_resume();      } +    setBalanceVisible(true);      return ret;  } @@ -5715,6 +5720,14 @@ void LLViewerWindow::setProgressCancelButtonVisible( bool b, const std::string&      }  } +void LLViewerWindow::setBalanceVisible(bool visible) +{ +    if (gStatusBar) +    { +        gStatusBar->setBalanceVisible(visible); +    } +} +  LLProgressView *LLViewerWindow::getProgressView() const  {      return mProgressView; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index ac0dfa3fe4..d55c2d3817 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -364,9 +364,11 @@ public:      // snapshot functionality.      // perhaps some of this should move to llfloatershapshot?  -MG -    bool            saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, bool show_ui = true, bool show_hud = true, bool do_rebuild = false, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP); -    bool            rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, bool keep_window_aspect = true, bool is_texture = false, -        bool show_ui = true, bool show_hud = true, bool do_rebuild = false, bool no_post = false, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE); +    bool saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, bool show_ui = true, bool show_hud = true, bool do_rebuild = false, bool show_balance = true, +                     LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP); +    bool rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, bool keep_window_aspect = true, bool is_texture = false, +                     bool show_ui = true, bool show_hud = true, bool do_rebuild = false, bool no_post = false, bool show_balance = true, +                     LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);      bool            simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes); @@ -462,6 +464,8 @@ public:      void            calcDisplayScale();      static LLRect   calcScaledRect(const LLRect & rect, const LLVector2& display_scale); +    void setBalanceVisible(bool visible); +      static std::string getLastSnapshotDir();      LLView* getFloaterSnapRegion() { return mFloaterSnapRegion; } diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp index da7e18af5c..3119c31613 100644 --- a/indra/newview/llviewerwindowlistener.cpp +++ b/indra/newview/llviewerwindowlistener.cpp @@ -100,7 +100,7 @@ void LLViewerWindowListener::saveSnapshot(const LLSD& event) const          }          type = found->second;      } -    bool ok = mViewerWindow->saveSnapshot(event["filename"], width, height, showui, showhud, rebuild, type); +    bool ok = mViewerWindow->saveSnapshot(event["filename"], width, height, showui, showhud, rebuild, true /*L$ Balance*/, type);      sendReply(LLSDMap("ok", ok), event);  } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1cca2161fe..3a52908b8a 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -123,8 +123,8 @@ extern F32 ANIM_SPEED_MAX;  extern F32 ANIM_SPEED_MIN;  extern U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG; -const F32 MAX_HOVER_Z = 2.0; -const F32 MIN_HOVER_Z = -2.0; +const F32 MAX_HOVER_Z = 3.0; +const F32 MIN_HOVER_Z = -3.0;  const F32 MIN_ATTACHMENT_COMPLEXITY = 0.f;  const F32 DEFAULT_MAX_ATTACHMENT_COMPLEXITY = 1.0e6f; @@ -11006,8 +11006,7 @@ void LLVOAvatar::idleUpdateRenderComplexity()      bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();      if (autotune && !isDead())      { -        static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); -        F32 radius = render_far_clip * render_far_clip; +        F32 radius = sRenderDistance * sRenderDistance;          bool is_nearby = true;          if ((dist_vec_squared(getPositionGlobal(), gAgent.getPositionGlobal()) > radius) && @@ -11039,8 +11038,7 @@ void LLVOAvatar::updateNearbyAvatarCount()      if (agent_update_timer.getElapsedTimeF32() > 1.0f)      {          S32 avs_nearby = 0; -        static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); -        F32 radius = render_far_clip * render_far_clip; +        F32 radius = sRenderDistance * sRenderDistance;          for (LLCharacter* character : LLCharacter::sInstances)          {              LLVOAvatar* avatar = (LLVOAvatar*)character; diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 294d36b0a9..bc326a74a8 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -245,6 +245,7 @@ bool LLVOSurfacePatch::updateLOD()  void LLVOSurfacePatch::getTerrainGeometry(LLStrider<LLVector3> &verticesp,                                                LLStrider<LLVector3> &normalsp, +                                              LLStrider<LLVector2> &texCoords0p,                                                LLStrider<LLVector2> &texCoords1p,                                                LLStrider<U16> &indicesp)  { @@ -259,18 +260,21 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider<LLVector3> &verticesp,      updateMainGeometry(facep,                      verticesp,                      normalsp, +                    texCoords0p,                      texCoords1p,                      indicesp,                      index_offset);      updateNorthGeometry(facep,                          verticesp,                          normalsp, +                        texCoords0p,                          texCoords1p,                          indicesp,                          index_offset);      updateEastGeometry(facep,                          verticesp,                          normalsp, +                        texCoords0p,                          texCoords1p,                          indicesp,                          index_offset); @@ -279,6 +283,7 @@ void LLVOSurfacePatch::getTerrainGeometry(LLStrider<LLVector3> &verticesp,  void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,                                          LLStrider<LLVector3> &verticesp,                                          LLStrider<LLVector3> &normalsp, +                                        LLStrider<LLVector2> &texCoords0p,                                          LLStrider<LLVector2> &texCoords1p,                                          LLStrider<U16> &indicesp,                                          U32 &index_offset) @@ -317,9 +322,10 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,              {                  x = i * render_stride;                  y = j * render_stride; -                mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +                mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());                  verticesp++;                  normalsp++; +                texCoords0p++;                  texCoords1p++;              }          } @@ -381,6 +387,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,  void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,                                          LLStrider<LLVector3> &verticesp,                                          LLStrider<LLVector3> &normalsp, +                                        LLStrider<LLVector2> &texCoords0p,                                          LLStrider<LLVector2> &texCoords1p,                                          LLStrider<U16> &indicesp,                                          U32 &index_offset) @@ -414,9 +421,10 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,              x = i * render_stride;              y = 16 - render_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -425,9 +433,10 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,          {              x = i * render_stride;              y = 16; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -460,9 +469,10 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,              x = i * render_stride;              y = 16 - render_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -472,9 +482,10 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,              x = i * render_stride;              y = 16; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -514,9 +525,10 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,              x = i * north_stride;              y = 16 - render_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -526,9 +538,10 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,              x = i * north_stride;              y = 16; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -564,6 +577,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,  void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,                                            LLStrider<LLVector3> &verticesp,                                            LLStrider<LLVector3> &normalsp, +                                          LLStrider<LLVector2> &texCoords0p,                                            LLStrider<LLVector2> &texCoords1p,                                            LLStrider<U16> &indicesp,                                            U32 &index_offset) @@ -592,9 +606,10 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,              x = 16 - render_stride;              y = i * render_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -603,9 +618,10 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,          {              x = 16;              y = i * render_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -638,9 +654,10 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,              x = 16 - render_stride;              y = i * render_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          }          // Iterate through the east patch's points @@ -649,9 +666,10 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,              x = 16;              y = i * render_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -690,9 +708,10 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,              x = 16 - render_stride;              y = i * east_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          }          // Iterate through the east patch's points @@ -701,9 +720,10 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,              x = 16;              y = i * east_stride; -            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords1p.get()); +            mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());              verticesp++;              normalsp++; +            texCoords0p++;              texCoords1p++;          } @@ -1022,12 +1042,14 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group)      LLStrider<LLVector3> vertices_start;      LLStrider<LLVector3> normals_start;      LLStrider<LLVector4a> tangents_start; +    LLStrider<LLVector2> texcoords0_start; // ownership overlay      LLStrider<LLVector2> texcoords2_start;      LLStrider<U16> indices_start;      llassert_always(buffer->getVertexStrider(vertices_start));      llassert_always(buffer->getNormalStrider(normals_start));      llassert_always(buffer->getTangentStrider(tangents_start)); +    llassert_always(buffer->getTexCoord0Strider(texcoords0_start));      llassert_always(buffer->getTexCoord1Strider(texcoords2_start));      llassert_always(buffer->getIndexStrider(indices_start)); @@ -1037,6 +1059,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group)      {          LLStrider<LLVector3> vertices = vertices_start;          LLStrider<LLVector3> normals = normals_start; +        LLStrider<LLVector2> texcoords0 = texcoords0_start;          LLStrider<LLVector2> texcoords2 = texcoords2_start;          LLStrider<U16> indices = indices_start; @@ -1049,7 +1072,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group)              facep->setVertexBuffer(buffer);              LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); -            patchp->getTerrainGeometry(vertices, normals, texcoords2, indices); +            patchp->getTerrainGeometry(vertices, normals, texcoords0, texcoords2, indices);              indices_index += facep->getIndicesCount();              index_offset += facep->getGeomCount(); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index af5f05774b..c93a58d2d9 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -57,6 +57,7 @@ public:      /*virtual*/ void        updateFaceSize(S32 idx);      void getTerrainGeometry(LLStrider<LLVector3> &verticesp,                                  LLStrider<LLVector3> &normalsp, +                                LLStrider<LLVector2> &texCoords0p,                                  LLStrider<LLVector2> &texCoords1p,                                  LLStrider<U16> &indicesp); @@ -109,18 +110,21 @@ protected:      void updateMainGeometry(LLFace *facep,                         LLStrider<LLVector3> &verticesp,                         LLStrider<LLVector3> &normalsp, +                       LLStrider<LLVector2> &texCoords0p,                         LLStrider<LLVector2> &texCoords1p,                         LLStrider<U16> &indicesp,                         U32 &index_offset);      void updateNorthGeometry(LLFace *facep,                         LLStrider<LLVector3> &verticesp,                         LLStrider<LLVector3> &normalsp, +                       LLStrider<LLVector2> &texCoords0p,                         LLStrider<LLVector2> &texCoords1p,                         LLStrider<U16> &indicesp,                         U32 &index_offset);      void updateEastGeometry(LLFace *facep,                         LLStrider<LLVector3> &verticesp,                         LLStrider<LLVector3> &normalsp, +                       LLStrider<LLVector2> &texCoords0p,                         LLStrider<LLVector2> &texCoords1p,                         LLStrider<U16> &indicesp,                         U32 &index_offset); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 8ce1a745c3..c708e804b2 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -33,7 +33,6 @@  #include "llagentwearables.h"  #include "llappearancemgr.h" -#include "llinventoryfunctions.h"  #include "llinventoryicon.h"  #include "llgesturemgr.h"  #include "lltransutil.h" @@ -41,15 +40,6 @@  #include "llviewermenu.h"  #include "llvoavatarself.h" -class LLFindOutfitItems : public LLInventoryCollectFunctor -{ -public: -    LLFindOutfitItems() {} -    virtual ~LLFindOutfitItems() {} -    virtual bool operator()(LLInventoryCategory* cat, -                            LLInventoryItem* item); -}; -  bool LLFindOutfitItems::operator()(LLInventoryCategory* cat,                                     LLInventoryItem* item)  { diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 3fe1059176..7a5f29020e 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -32,6 +32,7 @@  #include "llsingleton.h"  // newview +#include "llinventoryfunctions.h"  #include "llinventoryitemslist.h"  #include "llinventorylistitem.h"  #include "lllistcontextmenu.h" @@ -507,4 +508,12 @@ protected:      LLWearableType::EType mMenuWearableType;  }; +class LLFindOutfitItems : public LLInventoryCollectFunctor +{ +public: +    LLFindOutfitItems() {} +    virtual ~LLFindOutfitItems() {} +    virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +}; +  #endif //LL_LLWEARABLEITEMSLIST_H diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 899733ccc3..47e1815bc2 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1372,10 +1372,8 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi  F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLVOAvatar*> &valid_nearby_avs)  { -    static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); -      F32 nearby_max_complexity = 0; -    F32 radius = render_far_clip * render_far_clip; +    F32 radius = LLVOAvatar::sRenderDistance * LLVOAvatar::sRenderDistance;      for (LLCharacter* character : LLCharacter::sInstances)      { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 076459a7b2..6b3a5b1892 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -121,7 +121,7 @@  #include "SMAAAreaTex.h"  #include "SMAASearchTex.h" - +#include "llerror.h"  #ifndef LL_WINDOWS  #define A_GCC 1  #pragma GCC diagnostic ignored "-Wunused-function" @@ -601,7 +601,6 @@ void LLPipeline::init()      connectRefreshCachedSettingsSafe("RenderMirrors");      connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate");      connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier"); -    connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");      LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl("CollectFontVertexBuffers");      if (cntrl_ptr.notNull()) @@ -1291,8 +1290,11 @@ void LLPipeline::createGLBuffers()      }      allocateScreenBuffer(resX, resY); -    mRT->width = 0; -    mRT->height = 0; +    // Do not zero out mRT dimensions here. allocateScreenBuffer() above +    // already sets the correct dimensions. Zeroing them caused resizeShadowTexture() +    // to fail if called immediately after createGLBuffers (e.g., post graphics change). +    // mRT->width = 0; +    // mRT->height = 0;      if (!mNoiseMap) diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index 604eb7c58f..4ea34975e1 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -5,7 +5,7 @@  [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]  	</floater.string>  	<floater.string name="AboutPosition"> -		Du er ved [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] i regionen [REGION] lokaliseret ved <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Du er ved [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] i regionen [REGION] lokaliseret ved <nolink>[HOSTNAME]</nolink>  [SERVER_VERSION]  [SERVER_RELEASE_NOTES_URL]  	</floater.string> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index a7dff91311..038a2e0fcd 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -3723,6 +3723,10 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE].  	<string name="conference-title-incoming">  		Konference med [AGENT_NAME]  	</string> +	<string name="bot_warning"> +Du chatter med en bot, [NAME]. Del ikke personlige oplysninger. +Læs mere på https://second.life/scripted-agents. +	</string>  	<string name="no_session_message">  		(IM session eksisterer ikke)  	</string> diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml index 602424821f..09447cbbaf 100644 --- a/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		<combo_box.item label="Klein (128x128)" name="Small(128x128)"/>  		<combo_box.item label="Mittel (256x256)" name="Medium(256x256)"/>  		<combo_box.item label="Groß (512x512)" name="Large(512x512)"/> -		<combo_box.item label="Aktuelles Fenster (512x512)" name="CurrentWindow"/> +		<combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>  		<combo_box.item label="Benutzerdefiniert" name="Custom"/>  	</combo_box>  	<spinner label="Breite x Höhe" name="inventory_snapshot_width"/> diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_options.xml b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml index dab20d63eb..2a51f10894 100644 --- a/indra/newview/skins/default/xui/de/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="Auf Datenträger speichern" name="save_to_computer_btn"/> -	<button label="In Inventar speichern ([AMOUNT] L$)" name="save_to_inventory_btn"/> +	<button label="In Inventar speichern" name="save_to_inventory_btn"/>  	<button label="Im Profil-Feed teilen" name="save_to_profile_btn"/>  	<button label="Auf Facebook teilen" name="send_to_facebook_btn"/>  	<button label="Auf Twitter teilen" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 4bed43dd1d..9057821414 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -12,7 +12,7 @@  	<string name="StartupRequireDriverUpdate">Grafikinitialisierung fehlgeschlagen. Bitte aktualisieren Sie Ihren Grafiktreiber.</string>  	<string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]Bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string>  	<string name="BuildConfig">Build-Konfiguration [BUILD_CONFIG]</string> -	<string name="AboutPosition">Sie befinden sich an [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +	<string name="AboutPosition">Sie befinden sich an [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink>  SLURL: <nolink>[SLURL]</nolink>  (globale Koordinaten [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -1613,6 +1613,10 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_  	<string name="conference-title-incoming">Konferenz mit [AGENT_NAME]</string>  	<string name="inventory_item_offered-im">Inventarobjekt „[ITEM_NAME]“ angeboten</string>  	<string name="inventory_folder_offered-im">Inventarordner „[ITEM_NAME]“ angeboten</string> +	<string name="bot_warning"> +	Sie chatten mit einem Bot, [NAME]. Geben Sie keine persönlichen Informationen weiter. +Erfahren Sie mehr unter https://second.life/scripted-agents. +	</string>  	<string name="share_alert">Objekte aus dem Inventar hier her ziehen</string>  	<string name="facebook_post_success">Sie haben auf Facebook gepostet.</string>  	<string name="flickr_post_success">Sie haben auf Flickr gepostet.</string> diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index e6b780728c..acdccdc03a 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -167,8 +167,19 @@           left="30"  		 height="16"           top_pad="8" -         width="180" +         width="80" +         control_name="RenderUIInSnapshot"           name="ui_check" /> +       <check_box +         label="L$ Balance" +         layout="topleft" +         left_pad="16" +         height="16" +         top_delta="0" +         width="80" +         control_name="RenderBalanceInSnapshot" +         enabled_control="RenderUIInSnapshot" +         name="balance_check" />          <check_box           label="HUDs"           layout="topleft" @@ -176,6 +187,7 @@           left="30"           top_pad="1"           width="180" +         control_name="RenderHUDInSnapshot"           name="hud_check" />          <check_box           label="Freeze frame (fullscreen)" diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index e0f380e074..d672ffbc94 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -152,6 +152,14 @@           parameter="category" />      </menu_item_call>      <menu_item_call +     label="New Folder" +     layout="topleft" +     name="New Outfit Folder"> +        <menu_item_call.on_click +         function="Inventory.DoCreate" +         parameter="category" /> +    </menu_item_call> +    <menu_item_call       label="New Outfit"       layout="topleft"       name="New Outfit"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 4245b22e88..bcca3ce495 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -10336,6 +10336,14 @@ You are now the owner of object [OBJECT_NAME]    <notification     icon="alertmodal.tga" +   name="NowOwnObjectInv" +   type="notify"> +   <tag>fail</tag> +You are now the owner of object [OBJECT_NAME] and it has been placed in your inventory. +  </notification> + +    <notification +   icon="alertmodal.tga"     name="CantRezOnLand"     type="notify">     <tag>fail</tag> diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml index 7687f7cd96..23bbf45e88 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml @@ -139,7 +139,7 @@                      max_val_x="30"                      min_val_y="-30"                      max_val_y="30"  -                    logarithmic="1"/> +                    logarithmic="true"/>              <text                      name="cloud_image_label" diff --git a/indra/newview/skins/default/xui/en/panel_settings_water.xml b/indra/newview/skins/default/xui/en/panel_settings_water.xml index 5e65b0e8a2..e062f1710b 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_water.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_water.xml @@ -378,7 +378,7 @@                              initial_value="0"                              layout="topleft"                              left_delta="5" -                            min_val="-0.5" +                            min_val="0"                              max_val="0.5"                              name="water_blur_multip"                              top_pad="5" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml index f8040b9a65..0cac1b410f 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml @@ -60,7 +60,7 @@           name="Large(512x512)"           value="[i512,i512]" />          <combo_box.item -         label="Current Window(512x512)" +         label="Current Window"           name="CurrentWindow"           value="[i0,i0]" />          <combo_box.item @@ -119,6 +119,8 @@       type="string"       word_wrap="true">          To save your image as a texture select one of the square formats. + +Upload cost: L$[UPLOAD_COST]      </text>      <button       follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml index 3a7731d235..2fb02af61c 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml @@ -31,7 +31,7 @@     image_overlay_alignment="left"     image_top_pad="-1"     imgoverlay_label_space="10" -   label="Save to Inventory (L$[AMOUNT])" +   label="Save to Inventory"     layout="topleft"     left_delta="0"     name="save_to_inventory_btn" diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 9a19d06432..af6a9b94d9 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -729,8 +729,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="-100" -             max_val="100" +             min_val="-10000" +             max_val="10000"               name="TexScaleU"               top_pad="5"               width="265" /> @@ -742,8 +742,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="-100" -             max_val="100" +             min_val="-10000" +             max_val="10000"               name="TexScaleV"               width="265" />              <spinner @@ -805,8 +805,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="-100" -             max_val="100" +             min_val="-10000" +             max_val="10000"               name="bumpyScaleU"               top_delta="-115"               width="265" /> @@ -818,8 +818,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="-100" -             max_val="100" +             min_val="-10000" +             max_val="10000"               name="bumpyScaleV"               width="265" />             <spinner @@ -869,8 +869,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="-100" -             max_val="100" +             min_val="-10000" +             max_val="10000"               name="shinyScaleU"               top_delta="-115"               width="265" /> @@ -882,8 +882,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="-100" -             max_val="100" +             min_val="-10000" +             max_val="10000"               name="shinyScaleV"               width="265" />             <spinner diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 44da9a8dac..14123de82c 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -13,7 +13,6 @@  	<string name="SUPPORT_SITE">Second Life Support Portal</string>  	<!-- starting up --> -	<string name="StartupDetectingHardware">Detecting hardware...</string>  	<string name="StartupLoading">Loading [APP_NAME]...</string>  	<string name="StartupClearingCache">Clearing cache...</string>  	<string name="StartupInitializingTextureCache">Initializing texture cache...</string> @@ -71,7 +70,7 @@ Voice Server Version: [VOICE_VERSION]    <string name="LocalTime">[month, datetime, local] [day, datetime, local] [year, datetime, local] [hour, datetime, local]:[min, datetime, local]:[second,datetime, local]</string>  	<string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string>  	<string name="BuildConfiguration">Build Configuration</string> - +	  	<!--  progress -->  	<string name="ProgressRestoring">Restoring...</string>  	<string name="ProgressChangingResolution">Changing resolution...</string> @@ -114,10 +113,10 @@ Voice Server Version: [VOICE_VERSION]  	<string name="LoginFailedHeader">Login failed.</string>  	<string name="Quit">Quit</string>  	<string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - +	  	<string name="AgniGridLabel">Second Life Main Grid (Agni)</string>  	<string name="AditiGridLabel">Second Life Beta Test Grid (Aditi)</string> - +	  	<string name="ViewerDownloadURL">http://secondlife.com/download</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: @@ -209,7 +208,7 @@ If you feel this is an error, please contact support@secondlife.com</string>  	<string name="YouHaveBeenDisconnected">You have been disconnected from the region you were in.</string>  	<string name="SentToInvalidRegion">You were sent to an invalid region.</string>  	<string name="TestingDisconnect">Testing viewer disconnect</string> - +    	<!-- SLShare: User Friendly Filter Names Translation -->      <string name="BlackAndWhite">Black & White</string>      <string name="Colors1970">1970's Colors</string> @@ -222,7 +221,7 @@ If you feel this is an error, please contact support@secondlife.com</string>      <string name="LensFlare">Lens Flare</string>      <string name="Miniature">Miniature</string>      <string name="Toycamera">Toy Camera</string> - +	      <!-- Tooltip -->  	<string name="TooltipPerson">Person</string><!-- Object under mouse pointer is an avatar -->  	<string name="TooltipNoName">(no name)</string> <!-- No name on an object --> @@ -259,10 +258,11 @@ If you feel this is an error, please contact support@secondlife.com</string>  	<string name="TooltipOutboxMixedStock">All items in a stock folder must have the same type and permission</string>  	<string name="TooltipOutfitNotInInventory">You can only put items or outfits from your personal inventory into "My outfits"</string>  	<string name="TooltipCantCreateOutfit">One or more items can't be used inside "My outfits"</string> - +    <string name="TooltipCantMoveOutfitIntoOutfit">Can not move an outfit into another outfit</string> +	  	<string name="TooltipDragOntoOwnChild">You can't move a folder into its child</string>  	<string name="TooltipDragOntoSelf">You can't move a folder into itself</string> - +	  	<!-- tooltips for Urls -->  	<string name="TooltipHttpUrl">Click to view this web page</string>  	<string name="TooltipSLURL">Click to view this location's information</string> @@ -370,7 +370,7 @@ are allowed.  	<string name="AssetUploadServerDifficulties">The server is experiencing unexpected difficulties.</string>  	<string name="AssetUploadServerUnavaliable">Service not available or upload timeout was reached.</string>  	<string name="AssetUploadRequestInvalid"> -Error in upload request.  Please visit +Error in upload request.  Please visit   http://secondlife.com/support for help fixing this problem.  </string> @@ -534,7 +534,7 @@ http://secondlife.com/support for help fixing this problem.  	<string name="ChangeYourDefaultAnimations">Change your default animations</string>  	<string name="ForceSitAvatar">Force your avatar to sit</string>  	<string name="ChangeEnvSettings">Change your environment settings</string> - +	  	<string name="NotConnected">Not Connected</string>  	<string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name -->  	<string name="JoinAnExperience"/><!-- intentionally blank --> @@ -2320,7 +2320,7 @@ For AI Character: Get the closest navigable point to the point provided.  	<!-- inventory -->  	<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> -	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> +	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>	  	<string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string>  	<string name="FavoritesNoMatchingItems">To add a place to your favorites, click the star to the right of the location name, then save the landmark to "Favorites bar".</string>  	<string name="MarketplaceNoListing">You have no listings yet.</string> @@ -2503,7 +2503,7 @@ If you continue to receive this message, please contact Second Life support for    <string name="InvFolder Materials">Materials</string>    <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694--> -	<string name="InvFolder Friends">Friends</string> +	<string name="InvFolder Friends">Friends</string>	  	<string name="InvFolder All">All</string>  	<string name="no_attachments">No attachments worn</string> @@ -2672,7 +2672,7 @@ If you continue to receive this message, please contact Second Life support for  	<string name="UploadFailed">File upload failed: </string>  	<string name="ObjectOutOfRange">Script (object out of range)</string>  	<string name="ScriptWasDeleted">Script (deleted from inventory)</string> - +	  	<!-- god tools -->  	<string name="GodToolsObjectOwnedBy">Object [OBJECT] owned by [OWNER]</string> @@ -2942,14 +2942,12 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim  	<string name="Linden Location">Linden Location</string>  	<string name="Adult">Adult</string>  	<string name="Arts&Culture">Arts & Culture</string> -	<string name="Arts and Culture">Arts & Culture</string>  	<string name="Business">Business</string>  	<string name="Educational">Educational</string>  	<string name="Gaming">Gaming</string>  	<string name="Hangout">Hangout</string>  	<string name="Newcomer Friendly">Newcomer Friendly</string>  	<string name="Parks&Nature">Parks & Nature</string> -	<string name="Parks and Nature">Parks & Nature</string>  	<string name="Residential">Residential</string>  	<!--<string name="Shopping">Shopping</string>	-->  	<string name="Stage">Stage</string> @@ -3719,6 +3717,10 @@ Please reinstall viewer from  https://secondlife.com/support/downloads/ and cont    <string name="inventory_folder_offered-im">      Inventory folder '[ITEM_NAME]' offered    </string> +  <string name="bot_warning"> +  You are chatting with a bot, [NAME]. Do not share any personal information. +Learn more at https://second.life/scripted-agents. +  </string>    <string name="share_alert">      Drag items from inventory here    </string> @@ -3851,7 +3853,7 @@ Please reinstall viewer from  https://secondlife.com/support/downloads/ and cont    <string name="uploading_costs">Uploading costs L$ [AMOUNT]</string>    <string name="this_costs">This costs L$ [AMOUNT]</string> - +      <string name="buying_selected_land">This land costs</string>    <string name="this_object_costs">This item costs</string>    <string name="giving">You want to give</string> @@ -3932,7 +3934,7 @@ Abuse Report</string>    <string name="New Daycycle">New Daycycle</string>    <string name="New Water">New Water</string>    <string name="New Sky">New Sky</string> - +      <string name="/bow">/bow</string>    <string name="/clap">/clap</string> @@ -4014,7 +4016,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem    <string name="Accounting">Accounting</string>    <string name="Notices">Notices</string>    <string name="Chat">Chat</string> - +      <!-- SL Membership -->    <string name="BaseMembership">Base</string>    <string name="PremiumMembership">Premium</string> @@ -4180,7 +4182,7 @@ Try enclosing path to the editor with double quotes.    <!-- commands --> -  <string +  <string   name="Command_360_Capture_Label">360 snapshot</string>    <string name="Command_AboutLand_Label">About land</string>    <string name="Command_Appearance_Label">Outfits</string> @@ -4213,9 +4215,9 @@ name="Command_360_Capture_Label">360 snapshot</string>    <string name="Command_View_Label">Camera controls</string>    <string name="Command_Voice_Label">Voice settings</string>    <string name="Command_FavoriteFolder_Label">Favorite folder</string> -	<string name="Command_ResyncAnimations_Label">Resync animations</string> +  <string name="Command_ResyncAnimations_Label">Resync animations</string> -  <string +  <string   name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>    <string name="Command_AboutLand_Tooltip">Information about the land you're visiting</string>    <string name="Command_Appearance_Tooltip">Change your avatar</string> @@ -4248,7 +4250,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>    <string name="Command_View_Tooltip">Changing camera angle</string>    <string name="Command_Voice_Tooltip">Volume controls for calls and people near you in world</string>    <string name="Command_FavoriteFolder_Tooltip">Open your favorite inventory folder</string> -	<string name="Command_ResyncAnimations_Tooltip">Synchronizes avatar animations</string> +  <string name="Command_ResyncAnimations_Tooltip">Synchronizes avatar animations</string>    <string name="Toolbar_Bottom_Tooltip">currently in your bottom toolbar</string>    <string name="Toolbar_Left_Tooltip"  >currently in your left toolbar</string> @@ -4282,7 +4284,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>    <!-- Spell check settings floater -->    <string name="UserDictionary">[User]</string> - +      <!-- Experience Tools strings -->    <string name="experience_tools_experience">Experience</string>    <string name="ExperienceNameNull">(no experience)</string> @@ -4344,7 +4346,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>    <string name="Default">Default</string>    <string name="none_paren_cap">(None)</string>    <string name="no_limit">No limit</string> - +      <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">        The physics shape contains triangles which are too small. Try simplifying the physics model.    </string> diff --git a/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml b/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml index cdeff6ab05..f246ff764a 100644 --- a/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml +++ b/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml @@ -3,7 +3,6 @@      name="virtualtrackball"      width="150"      height="150" -    user_resize="false"           increment_angle_mouse="1.5f"      increment_angle_btn="1.0f"          image_sphere="VirtualTrackball_Sphere" diff --git a/indra/newview/skins/default/xui/en/widgets/xy_vector.xml b/indra/newview/skins/default/xui/en/widgets/xy_vector.xml index 23cde55f30..923895be5e 100644 --- a/indra/newview/skins/default/xui/en/widgets/xy_vector.xml +++ b/indra/newview/skins/default/xui/en/widgets/xy_vector.xml @@ -3,11 +3,9 @@      name="xyvector"      width="120"      height="140" -    decimal_digits="1"      label_width="16"      padding="4" -    edit_bar_height="18" -    user_resize="false"> +    edit_bar_height="18">      <xy_vector.border          visible="true"/> diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml index b5cf57ade7..c9eea9a58e 100644 --- a/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		Guardar una imagen en el inventario cuesta [UPLOAD_COST] L$. Para guardar una imagen como una textura, selecciona uno de los formatos cuadrados.  	</text>  	<combo_box label="Resolución" name="texture_size_combo"> -		<combo_box.item label="Ventana actual (512 × 512)" name="CurrentWindow"/> +		<combo_box.item label="Ventana actual" name="CurrentWindow"/>  		<combo_box.item label="Pequeña (128x128)" name="Small(128x128)"/>  		<combo_box.item label="Mediana (256x256)" name="Medium(256x256)"/>  		<combo_box.item label="Grande (512x512)" name="Large(512x512)"/> diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_options.xml b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml index 4eb9ecf28f..f3119c739e 100644 --- a/indra/newview/skins/default/xui/es/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="Guardar en disco" name="save_to_computer_btn"/> -	<button label="Guardar en inventario (L$[AMOUNT])" name="save_to_inventory_btn"/> +	<button label="Guardar en inventario" name="save_to_inventory_btn"/>  	<button label="Compartir en los comentarios de Mi perfil" name="save_to_profile_btn"/>  	<button label="Compartir en Facebook" name="send_to_facebook_btn"/>  	<button label="Compartir en Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index cf86427477..4ec72d0409 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -10,7 +10,7 @@  	<string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit)   [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string>  	<string name="BuildConfig">Configuración de constitución [BUILD_CONFIG]</string> -	<string name="AboutPosition">Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +	<string name="AboutPosition">Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink>  SLURL: <nolink>[SLURL]</nolink>  (coordenadas globales [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -1584,6 +1584,10 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].</string>  	<string name="conference-title-incoming">Conferencia con [AGENT_NAME]</string>  	<string name="inventory_item_offered-im">Ítem del inventario '[ITEM_NAME]' ofrecido</string>  	<string name="inventory_folder_offered-im">Carpeta del inventario '[ITEM_NAME]' ofrecida</string> +	<string name="bot_warning"> +Estás conversando con un bot, [NAME]. No compartas información personal. +Más información en https://second.life/scripted-agents. +	</string>  	<string name="share_alert">Arrastra los ítems desde el invenbtario hasta aquí</string>  	<string name="facebook_post_success">Has publicado en Facebook.</string>  	<string name="flickr_post_success">Has publicado en Flickr.</string> 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 3cf64583d2..a560ff8d5e 100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		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 (512x512)" name="CurrentWindow"/> +		<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>  		<combo_box.item label="Petite (128 x 128)" name="Small(128x128)"/>  		<combo_box.item label="Moyenne (256 x 256)" name="Medium(256x256)"/>  		<combo_box.item label="Grande (512 x 512)" name="Large(512x512)"/> 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 bdedb9162f..52fa318f8e 100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="Enreg. sur le disque" name="save_to_computer_btn"/> -	<button label="Enreg. dans l'inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/> +	<button label="Enreg. dans l'inventaire" name="save_to_inventory_btn"/>  	<button label="Partager sur le flux de profil" name="save_to_profile_btn"/>  	<button label="Partager sur Facebook" name="send_to_facebook_btn"/>  	<button label="Partager sur Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 3889e26aee..5ea33591fc 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -13,7 +13,7 @@  	<string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit)   [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string>  	<string name="BuildConfig">Configuration de la construction [BUILD_CONFIG]</string> -	<string name="AboutPosition">Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +	<string name="AboutPosition">Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink>  SLURL : <nolink>[SLURL]</nolink>  (coordonnées globales [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -1614,6 +1614,10 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].</string>  	<string name="conference-title-incoming">Conférence avec [AGENT_NAME]</string>  	<string name="inventory_item_offered-im">Objet de l’inventaire [ITEM_NAME] offert</string>  	<string name="inventory_folder_offered-im">Dossier de l’inventaire [ITEM_NAME] offert</string> +	<string name="bot_warning"> +Vous discutez avec un bot, [NAME]. Ne partagez pas d’informations personnelles. +En savoir plus sur https://second.life/scripted-agents. +	</string>  	<string name="share_alert">Faire glisser les objets de l'inventaire ici</string>  	<string name="facebook_post_success">Vous avez publié sur Facebook.</string>  	<string name="flickr_post_success">Vous avez publié sur Flickr.</string> diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml index 75b5d64660..21b65e8e69 100644 --- a/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		Salvare un'immagine nell'inventario costa L$[UPLOAD_COST]. Per salvare l'immagine come texture, selezionare uno dei formati quadrati.  	</text>  	<combo_box label="Risoluzione" name="texture_size_combo"> -		<combo_box.item label="Finestra corrente (512x512)" name="CurrentWindow"/> +		<combo_box.item label="Finestra corrente" name="CurrentWindow"/>  		<combo_box.item label="Piccola (128x128)" name="Small(128x128)"/>  		<combo_box.item label="Media (256x256)" name="Medium(256x256)"/>  		<combo_box.item label="Grande (512x512)" name="Large(512x512)"/> diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_options.xml b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml index 50fb3d39fa..7fce171326 100644 --- a/indra/newview/skins/default/xui/it/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="Salva sul disco" name="save_to_computer_btn"/> -	<button label="Salva nell'inventario (L$[AMOUNT])" name="save_to_inventory_btn"/> +	<button label="Salva nell'inventario" name="save_to_inventory_btn"/>  	<button label="Condividi sul feed del profilo" name="save_to_profile_btn"/>  	<button label="Condividi su Facebook" name="send_to_facebook_btn"/>  	<button label="Condividi su Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 270e7ac3a1..61377a7d9d 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -12,7 +12,7 @@  	<string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit)   [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string>  	<string name="BuildConfig">Configurazione struttura [BUILD_CONFIG]</string> -	<string name="AboutPosition">Tu sei a [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +	<string name="AboutPosition">Tu sei a [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink>  SLURL: <nolink>[SLURL]</nolink>  (coordinate globali [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -1586,6 +1586,10 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].</string>  	<string name="conference-title-incoming">Chiamata in conferenza con [AGENT_NAME]</string>  	<string name="inventory_item_offered-im">Offerto oggetto di inventario "[ITEM_NAME]"</string>  	<string name="inventory_folder_offered-im">Offerta cartella di inventario "[ITEM_NAME]"</string> +	<string name="bot_warning"> +Stai parlando con un bot, [NAME]. Non condividere informazioni personali. +Scopri di più su https://second.life/scripted-agents. +	</string>  	<string name="facebook_post_success">Hai pubblicato su Facebook.</string>  	<string name="flickr_post_success">Hai pubblicato su Flickr.</string>  	<string name="twitter_post_success">Hai pubblicato su Twitter.</string> diff --git a/indra/newview/skins/default/xui/ja/panel_settings_water.xml b/indra/newview/skins/default/xui/ja/panel_settings_water.xml index ead1ca9b2f..2510523897 100644 --- a/indra/newview/skins/default/xui/ja/panel_settings_water.xml +++ b/indra/newview/skins/default/xui/ja/panel_settings_water.xml @@ -63,7 +63,7 @@  					<text follows="left|top|right" font="SansSerif" height="16" layout="topleft" left_delta="-5" top_pad="5" width="215">  						ブラー乗数  					</text> -					<slider control_name="water_blur_multip" follows="left|top" height="16" increment="0.001" initial_value="0" layout="topleft" left_delta="5" min_val="-0.5" max_val="0.5" name="water_blur_multip" top_pad="5" width="200" can_edit_text="true"/> +					<slider control_name="water_blur_multip" follows="left|top" height="16" increment="0.001" initial_value="0" layout="topleft" left_delta="5" min_val="0" max_val="0.5" name="water_blur_multip" top_pad="5" width="200" can_edit_text="true"/>  				</layout_panel>  			</layout_stack>  		</layout_panel> diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml index c55c11e928..04ecba4264 100644 --- a/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml @@ -6,7 +6,7 @@  	</text>  	<view_border name="hr"/>  	<combo_box label="解像度" name="texture_size_combo"> -		<combo_box.item label="現在のウィンドウ (512✕512)" name="CurrentWindow"/> +		<combo_box.item label="現在のウィンドウ" name="CurrentWindow"/>  		<combo_box.item label="小(128✕128)" name="Small(128x128)"/>  		<combo_box.item label="中(256✕256)" name="Medium(256x256)"/>  		<combo_box.item label="大(512✕512)" name="Large(512x512)"/> @@ -16,7 +16,7 @@  	<spinner label="" name="inventory_snapshot_height"/>  	<check_box label="縦横比の固定" name="inventory_keep_aspect_check"/>  	<text name="hint_lbl"> -		画像をテクスチャとして保存する場合は、いずれかの正方形を選択してください。 +		画像をインベントリに保存するには L$[UPLOAD_COST] の費用がかかります。画像をテクスチャとして保存するには平方形式の 1 つを選択してください。  	</text>  	<button label="キャンセル" name="cancel_btn"/>  	<button label="保存" name="save_btn"/> diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml index 7a1aa280ec..a979e31c9a 100644 --- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="ディスクに保存" name="save_to_computer_btn"/> -	<button label="インベントリに保存(L$ [AMOUNT])" name="save_to_inventory_btn"/> +	<button label="インベントリに保存" name="save_to_inventory_btn"/>  	<button label="プロフィールフィードで共有する" name="save_to_profile_btn"/>  	<button label="メールで送信" name="save_to_email_btn"/>  	<text name="fee_hint_lbl"> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 106bf91d0c..4f7e34774f 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -39,7 +39,7 @@  	</string>  	<string name="AboutPosition">  		あなたは、現在[REGION]の[POSITION_LOCAL_0,number,1],[POSITION_LOCAL_1,number,1],[POSITION_LOCAL_2,number,1]にいます。 -位置は、<nolink>[HOSTNAME]</nolink>です。([HOSTIP]) +位置は、<nolink>[HOSTNAME]</nolink>です。  SLURL:<nolink>[SLURL]</nolink>  (グローバル座標は、[POSITION_0,number,1],[POSITION_1,number,1],[POSITION_2,number,1]です。)  [SERVER_VERSION] @@ -6149,6 +6149,10 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ  	<string name="inventory_folder_offered-im">  		フォルダ「[ITEM_NAME]」がインベントリに送られてきました。  	</string> +	<string name="bot_warning"> +[NAME]とチャットしています。個人情報を共有しないでください。 +詳細は https://second.life/scripted-agents をご覧ください。 +	</string>  	<string name="share_alert">  		インベントリからここにアイテムをドラッグします。  	</string> diff --git a/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml b/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml index 016b9ca197..04c01940e1 100644 --- a/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel name="panel_snapshot_options">  	<button label="Zapisz na dysku twardym" name="save_to_computer_btn" /> -	<button label="Zapisz do Szafy ([AMOUNT]L$)" name="save_to_inventory_btn" /> +	<button label="Zapisz do Szafy" name="save_to_inventory_btn" />  	<button label="Wyślij na mój Kanał" name="save_to_profile_btn" />  	<button label="Załaduj na Facebook" name="send_to_facebook_btn" />  	<button label="Załaduj na Twitter" name="send_to_twitter_btn" /> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 8032443020..65b487e1b3 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -4412,6 +4412,10 @@ Jeżeli nadal otrzymujesz ten komunikat, skontaktuj się z [SUPPORT_SITE].  	<string name="inventory_folder_offered-im">  		Zaoferowano folder: '[ITEM_NAME]'  	</string> +	<string name="bot_warning"> +Rozmawiasz z botem [NAME]. Nie udostępniaj żadnych danych osobowych. +Dowiedz się więcej na https://second.life/scripted-agents. +	</string>  	<string name="share_alert">  		Przeciągaj tutaj rzeczy z Szafy  	</string> diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml index f3357026d5..28a5142baa 100644 --- a/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		Salvar uma imagem em seu inventário custa L$[UPLOAD_COST]. Para salvar sua imagem como uma textura, selecione um dos formatos quadrados.  	</text>  	<combo_box label="Resolução" name="texture_size_combo"> -		<combo_box.item label="Janela ativa (512x512)" name="CurrentWindow"/> +		<combo_box.item label="Janela ativa" name="CurrentWindow"/>  		<combo_box.item label="Pequeno (128x128)" name="Small(128x128)"/>  		<combo_box.item label="Médio (256x256)" name="Medium(256x256)"/>  		<combo_box.item label="Grande (512x512)" name="Large(512x512)"/> diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml index 067e5dbd76..f71bc7cd12 100644 --- a/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="Salvar no disco" name="save_to_computer_btn"/> -	<button label="Salvar em inventário (L$[AMOUNT])" name="save_to_inventory_btn"/> +	<button label="Salvar em inventário" name="save_to_inventory_btn"/>  	<button label="Compartilhar no feed do perfil" name="save_to_profile_btn"/>  	<button label="Compartilhar no Facebook" name="send_to_facebook_btn"/>  	<button label="Compartilhar no Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 3e33744b85..3798431d90 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -10,7 +10,7 @@  	<string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit)   [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string>  	<string name="BuildConfig">Configuração do corpo [BUILD_CONFIG]</string> -	<string name="AboutPosition">Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +	<string name="AboutPosition">Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em <nolink>[HOSTNAME]</nolink>  SLURL: <nolink>[SLURL]</nolink>  (coordenadas globais [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -1549,6 +1549,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].</string>  	<string name="conference-title-incoming">Conversa com [AGENT_NAME]</string>  	<string name="inventory_item_offered-im">Item do inventário '[ITEM_NAME]' oferecido</string>  	<string name="inventory_folder_offered-im">Pasta do inventário '[ITEM_NAME]' oferecida</string> +	<string name="bot_warning"> +Você está conversando com um bot, [NAME]. Não compartilhe informações pessoais. +Saiba mais em https://second.life/scripted-agents. +	</string>  	<string name="facebook_post_success">Você publicou no Facebook.</string>  	<string name="flickr_post_success">Você publicou no Flickr.</string>  	<string name="twitter_post_success">Você publicou no Twitter.</string> diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml index f07e12e0ed..adc612dfd8 100644 --- a/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		Сохранение изображения в инвентаре стоит L$[UPLOAD_COST]. Чтобы сохранить его как текстуру, выберите один из квадратных форматов.  	</text>  	<combo_box label="Размер" name="texture_size_combo"> -		<combo_box.item label="Текущее окно (512x512)" name="CurrentWindow"/> +		<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)"/> diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml index 7ba03ee0c9..f7fda0b1dc 100644 --- a/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="Сохранить на диске" name="save_to_computer_btn"/> -	<button label="Сохранить в инвентаре (L$[AMOUNT])" name="save_to_inventory_btn"/> +	<button label="Сохранить в инвентаре" name="save_to_inventory_btn"/>  	<button label="Поделиться в профиле" name="save_to_profile_btn"/>  	<button label="Поделиться в Facebook" name="send_to_facebook_btn"/>  	<button label="Поделиться в Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 10b0d3578f..0e6ddb0e34 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -42,7 +42,7 @@  		Конфигурация построения [BUILD_CONFIG]  	</string>  	<string name="AboutPosition"> -		Вы в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», расположенном на <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		Вы в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», расположенном на <nolink>[HOSTNAME]</nolink>  SLURL: <nolink>[SLURL]</nolink>  (глобальные координаты [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -4576,6 +4576,10 @@ support@secondlife.com.  	<string name="inventory_folder_offered-im">  		Предложена папка инвентаря «[ITEM_NAME]»  	</string> +	<string name="bot_warning"> +Вы общаетесь с ботом [NAME]. Не передавайте личные данные. +Подробнее на https://second.life/scripted-agents. +	</string>  	<string name="share_alert">  		Перетаскивайте вещи из инвентаря сюда  	</string> diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml index be5940c4b9..160cba8700 100644 --- a/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		Bir görüntüyü envanterinize kaydetmenin maliyeti L$[UPLOAD_COST] olur. Görüntünüzü bir doku olarak kaydetmek için kare formatlardan birini seçin.  	</text>  	<combo_box label="Çözünürlük" name="texture_size_combo"> -		<combo_box.item label="Mevcut Pencere(512x512)" name="CurrentWindow"/> +		<combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>  		<combo_box.item label="Küçük (128x128)" name="Small(128x128)"/>  		<combo_box.item label="Orta (256x256)" name="Medium(256x256)"/>  		<combo_box.item label="Büyük (512x512)" name="Large(512x512)"/> diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml index 1b48bbeec2..a028710b98 100644 --- a/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="Diske Kaydet" name="save_to_computer_btn"/> -	<button label="Envantere Kaydet (L$[AMOUNT])" name="save_to_inventory_btn"/> +	<button label="Envantere Kaydet" name="save_to_inventory_btn"/>  	<button label="Profil Akışında Paylaş" name="save_to_profile_btn"/>  	<button label="Facebook'ta Paylaş" name="send_to_facebook_btn"/>  	<button label="Twitter'da Paylaş" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index d992788e13..32cf1e14ff 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -42,7 +42,7 @@  		Yapı Konfigürasyonu [BUILD_CONFIG]  	</string>  	<string name="AboutPosition"> -		<nolink>[HOSTNAME]</nolink> ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız +		<nolink>[HOSTNAME]</nolink> üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız  SLURL: <nolink>[SLURL]</nolink>  (küresel koordinatlar [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -4579,6 +4579,10 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.  	<string name="inventory_folder_offered-im">  		"[ITEM_NAME]" envanter klasörü sunuldu  	</string> +	<string name="bot_warning"> +Bir bot ile sohbet ediyorsunuz, [NAME]. Kişisel bilgilerinizi paylaşmayın. +Daha fazla bilgi için: https://second.life/scripted-agents. +	</string>  	<string name="share_alert">  		Envanterinizden buraya öğeler sürükleyin  	</string> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml index 094bf019b4..9c45c54a5e 100644 --- a/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml @@ -7,7 +7,7 @@  		將圖像儲存到收納區的費用為 L$[UPLOAD_COST]。 若要將圖像存為材質,請選擇一個正方格式。  	</text>  	<combo_box label="解析度" name="texture_size_combo"> -		<combo_box.item label="目前視窗(512x512)" name="CurrentWindow"/> +		<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)"/> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml index d7c65bb25e..d9536882ac 100644 --- a/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="panel_snapshot_options">  	<button label="儲存到硬碟" name="save_to_computer_btn"/> -	<button label="儲存到收納區(L$[AMOUNT])" name="save_to_inventory_btn"/> +	<button label="儲存到收納區" name="save_to_inventory_btn"/>  	<button label="分享至檔案訊息發佈" name="save_to_profile_btn"/>  	<button label="分享到臉書" name="send_to_facebook_btn"/>  	<button label="分享到推特" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index d053d2b30d..dee48b3d58 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -42,7 +42,7 @@  		建製設置 [BUILD_CONFIG]  	</string>  	<string name="AboutPosition"> -		你的方位是 [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地區名:[REGION],主機:<nolink>[HOSTNAME]</nolink> ([HOSTIP]) +		你的方位是 [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地區名:[REGION],主機:<nolink>[HOSTNAME]</nolink>  第二人生URL:<nolink>[SLURL]</nolink>  (全域坐標:[POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])  [SERVER_VERSION] @@ -4572,6 +4572,10 @@ http://secondlife.com/support 求助解決問題。  	<string name="inventory_folder_offered-im">  		收納區資料夾'[ITEM_NAME]'已向人提供  	</string> +	<string name="bot_warning"> +您正在与人工智能机器人 [NAME] 聊天。请勿分享任何个人信息。 +了解更多:https://second.life/scripted-agents。 +	</string>  	<string name="share_alert">  		將收納區物品拖曳到這裡  	</string> | 
