From a4c795f87b4a9026e850474cfd51b6b4253e31a4 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Mon, 9 Jul 2018 18:06:16 +0300 Subject: [PATCH 1/6] MAINT-8848 FIXED Object name in the llGiveInventory chat message is represented as a hyperlink --- indra/newview/llviewermessage.cpp | 21 +++++++++++++++++++-- indra/newview/llviewermessage.h | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6cba7dd70c..a89b1220de 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1732,7 +1732,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& //don't spam them if they are getting flooded if (check_offer_throttle(mFromName, true)) { - log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString("."); + log_message = "" + chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString("."); LLSD args; args["MESSAGE"] = log_message; LLNotificationsUtil::add("SystemMessageTip", args); @@ -1917,7 +1917,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const //don't spam them if they are getting flooded if (check_offer_throttle(mFromName, true)) { - log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString("."); + log_message = "" + chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString("."); LLSD args; args["MESSAGE"] = log_message; LLNotificationsUtil::add("SystemMessageTip", args); @@ -1990,6 +1990,23 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const return false; } +std::string LLOfferInfo::getSanitizedDescription() +{ + // currently we get description from server as: 'Object' ( Location ) + // object name shouldn't be shown as a hyperlink + std::string description = mDesc; + + std::size_t start = mDesc.find_first_of("'"); + std::size_t end = mDesc.find_last_of("'"); + if ((start != std::string::npos) && (end != std::string::npos)) + { + description.insert(start, ""); + description.insert(end + 8, ""); + } + return description; +} + + void LLOfferInfo::initRespondFunctionMap() { if(mRespondFunctions.empty()) diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index b0eaa37541..424aae1229 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -257,6 +257,7 @@ public: private: void initRespondFunctionMap(); + std::string getSanitizedDescription(); typedef boost::function respond_function_t; typedef std::map respond_function_map_t; From 4e84a7f9517e9e10287490d3b96ed3c9cb24f45e Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Tue, 10 Jul 2018 18:06:52 +0300 Subject: [PATCH 2/6] MAINT-8855 FIXED Location SLURL gets truncated when using Help -> Report Bug to file JIRA --- indra/newview/llviewermenu.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f7250ffb66..ec851ddaf9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -134,6 +134,7 @@ #include "llpathfindingmanager.h" #include "llstartup.h" #include "boost/unordered_map.hpp" +#include #include "llcleanup.h" using namespace LLAvatarAppearanceDefines; @@ -8025,7 +8026,12 @@ void handle_report_bug(const LLSD& param) LLUIString url(param.asString()); LLStringUtil::format_map_t replace; - replace["[ENVIRONMENT]"] = LLURI::escape(LLAppViewer::instance()->getViewerInfoString(true)); + std::string environment = LLAppViewer::instance()->getViewerInfoString(true); + boost::regex regex; + regex.assign(""); + std::string stripped_env = boost::regex_replace(environment, regex, ""); + + replace["[ENVIRONMENT]"] = LLURI::escape(stripped_env); LLSLURL location_url; LLAgentUI::buildSLURL(location_url); replace["[LOCATION]"] = LLURI::escape(location_url.getSLURLString()); From 00f89e52ce8333b485c3bf9213b6c6b3ae96e615 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 11 Jul 2018 16:39:22 +0300 Subject: [PATCH 3/6] MAINT-8849 Fixed Viewer displays 'Conneting to region...' screen forever --- indra/newview/llstartup.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 7a4c41779a..cc02642203 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -246,6 +246,7 @@ static bool mLoginStatePastUI = false; const S32 DEFAULT_MAX_AGENT_GROUPS = 42; const S32 ALLOWED_MAX_AGENT_GROUPS = 500; +const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds boost::scoped_ptr LLStartUp::sStateWatcher(new LLEventStream("StartupState")); boost::scoped_ptr LLStartUp::sListener(new LLStartupListener()); @@ -1615,6 +1616,13 @@ bool idle_startup() LLStartUp::setStartupState( STATE_INVENTORY_SEND ); } display_startup(); + + if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT) + { + LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL; + LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); + reset_login(); + } return FALSE; } From bb904e2f35a87f716ad57cbaf55039f297a0db7c Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Wed, 11 Jul 2018 17:39:39 +0300 Subject: [PATCH 4/6] MAINT-8856 FIXED URL in Group Name is represented as a hyperlink in group notice --- indra/newview/skins/default/xui/en/panel_group_notify.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml index 4121acdfb0..60e5a03d51 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notify.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml @@ -43,6 +43,7 @@ layout="topleft" left_pad="10" name="title" + parse_urls="false" text_color="GroupNotifyTextColor" top="5" use_ellipses="true" From 14c65a2c9e8c2017a62aacf2e276b42c1f2b0873 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Thu, 12 Jul 2018 17:57:40 +0300 Subject: [PATCH 5/6] MAINT-8862 mailto URIs should be loaded in the external browser --- indra/newview/llweb.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index b816225b07..768db047a4 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -268,6 +268,12 @@ bool LLWeb::useExternalBrowser(const std::string &url) boost::match_results matches; return !(boost::regex_search(uri_string, matches, pattern)); } + else + { + boost::regex pattern = boost::regex("^mailto:", boost::regex::perl | boost::regex::icase); + boost::match_results matches; + return boost::regex_search(url, matches, pattern); + } return false; #endif } From dc0bd05717106522eb350b02dbac663eaebb8eef Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 26 Jun 2018 14:47:30 +0300 Subject: [PATCH 6/6] SL-927 Add new groups caps to viewer (offline messages only) --- .../newview/llfloaternotificationstabbed.cpp | 3 +- indra/newview/llimprocessing.cpp | 11 +- indra/newview/llnotificationlistitem.cpp | 31 +--- indra/newview/llnotificationlistitem.h | 1 + indra/newview/llviewermessage.cpp | 159 +++++++++++++----- indra/newview/llviewermessage.h | 5 + indra/newview/llviewerregion.cpp | 4 +- 7 files changed, 142 insertions(+), 72 deletions(-) diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp index 4b5fe4989a..d1679fd936 100644 --- a/indra/newview/llfloaternotificationstabbed.cpp +++ b/indra/newview/llfloaternotificationstabbed.cpp @@ -387,7 +387,8 @@ void LLFloaterNotificationsTabbed::onStoreToast(LLPanel* info_panel, LLUUID id) p.notification_name = notify->getName(); p.transaction_id = payload["transaction_id"]; p.group_id = payload["group_id"]; - p.fee = payload["fee"]; + p.fee = payload["fee"]; + p.use_offline_cap = payload["use_offline_cap"].asInteger(); p.subject = payload["subject"].asString(); p.message = payload["message"].asString(); p.sender = payload["sender_name"].asString(); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 491671c46f..e76b3d118e 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -814,10 +814,11 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, LLSD payload; payload["transaction_id"] = session_id; - payload["group_id"] = from_id; + payload["group_id"] = from_group ? from_id : aux_id; payload["name"] = name; payload["message"] = message; payload["fee"] = membership_fee; + payload["use_offline_cap"] = session_id.isNull() && (offline == IM_OFFLINE); LLSD args; args["MESSAGE"] = message; @@ -1459,8 +1460,12 @@ void LLIMProcessing::requestOfflineMessages() // Auto-accepted inventory items may require the avatar object // to build a correct name. Likewise, inventory offers from // muted avatars require the mute list to properly mute. - if (cap_url.empty()) + if (cap_url.empty() + || gAgent.getRegionCapability("AcceptFriendship").empty() + || gAgent.getRegionCapability("AcceptGroupInvite").empty()) { + // Offline messages capability provides no session/transaction ids for message AcceptFriendship and IM_GROUP_INVITATION to work + // So make sure we have the caps before using it. requestOfflineMessagesLegacy(); } else @@ -1561,7 +1566,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) message_data["to_agent_id"].asUUID(), IM_OFFLINE, (EInstantMessage)message_data["dialog"].asInteger(), - LLUUID::null, // session id, fix this for friendship offers to work + LLUUID::null, // session id, since there is none we can only use frienship/group invite caps message_data["timestamp"].asInteger(), message_data["from_agent_name"].asString(), message_data["message"].asString(), diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index f2de8e54a0..a5bc75e6bd 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -312,38 +312,15 @@ void LLGroupInviteNotificationListItem::onClickJoinBtn() return; } - if(mParams.fee > 0) - { - LLSD args; - args["COST"] = llformat("%d", mParams.fee); - // Set the fee for next time to 0, so that we don't keep - // asking about a fee. - LLSD next_payload; - next_payload["group_id"]= mParams.group_id; - next_payload["transaction_id"]= mParams.transaction_id; - next_payload["fee"] = 0; - LLNotificationsUtil::add("JoinGroupCanAfford", args, next_payload); - } - else - { - send_improved_im(mParams.group_id, - std::string("name"), - std::string("message"), - IM_ONLINE, - IM_GROUP_INVITATION_ACCEPT, - mParams.transaction_id); - } + send_join_group_response(mParams.group_id, mParams.transaction_id, true, mParams.fee, mParams.use_offline_cap); + LLNotificationListItem::onClickCloseBtn(); } void LLGroupInviteNotificationListItem::onClickDeclineBtn() { - send_improved_im(mParams.group_id, - std::string("name"), - std::string("message"), - IM_ONLINE, - IM_GROUP_INVITATION_DECLINE, - mParams.transaction_id); + send_join_group_response(mParams.group_id, mParams.transaction_id, false, mParams.fee, mParams.use_offline_cap); + LLNotificationListItem::onClickCloseBtn(); } diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h index 3dd52986b0..3d564fed0e 100644 --- a/indra/newview/llnotificationlistitem.h +++ b/indra/newview/llnotificationlistitem.h @@ -56,6 +56,7 @@ public: std::string message; std::string sender; S32 fee; + U8 use_offline_cap; LLDate time_stamp; LLDate received_time; LLSD inventory_offer; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a89b1220de..211d7b8c64 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -198,15 +198,15 @@ void accept_friendship_coro(std::string url, LLSD notification) void decline_friendship_coro(std::string url, LLSD notification, S32 option) { - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); if (url.empty()) { LL_WARNS() << "Empty capability!" << LL_ENDL; return; } + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLSD payload = notification["payload"]; url += "?from=" + payload["from_id"].asString(); @@ -724,6 +724,119 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain) static LLSD sSavedGroupInvite; static LLSD sSavedResponse; +void response_group_invitation_coro(std::string url, LLUUID group_id, bool notify_and_update) +{ + if (url.empty()) + { + LL_WARNS("GroupInvite") << "Empty capability!" << LL_ENDL; + return; + } + + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("friendshipResponceErrorProcessing", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD payload; + payload["group"] = group_id; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, payload); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("GroupInvite") << "HTTP status, " << status.toTerseString() << + ". Group " << group_id << " invitation response processing failed." << LL_ENDL; + } + else + { + if (!result.has("success") || result["success"].asBoolean() == false) + { + LL_WARNS("GroupInvite") << "Server failed to process group " << group_id << " invitation response. " << httpResults << LL_ENDL; + } + else + { + LL_DEBUGS("GroupInvite") << "Successfully sent response to group " << group_id << " invitation" << LL_ENDL; + if (notify_and_update) + { + LLNotificationsUtil::add("JoinGroupSuccess"); + gAgent.sendAgentDataUpdateRequest(); + + LLGroupMgr::getInstance()->clearGroupData(group_id); + // refresh the floater for this group, if any. + LLGroupActions::refresh(group_id); + } + } + } +} + +void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accept_invite, S32 fee, bool use_offline_cap, LLSD &payload) +{ + if (accept_invite && fee > 0) + { + // If there is a fee to join this group, make + // sure the user is sure they want to join. + LLSD args; + args["COST"] = llformat("%d", fee); + // Set the fee for next time to 0, so that we don't keep + // asking about a fee. + LLSD next_payload = payload; + next_payload["fee"] = 0; + LLNotificationsUtil::add("JoinGroupCanAfford", + args, + next_payload); + } + else if (use_offline_cap) + { + std::string url; + if (accept_invite) + { + url = gAgent.getRegionCapability("AcceptGroupInvite"); + } + else + { + url = gAgent.getRegionCapability("DeclineGroupInvite"); + } + + if (!url.empty()) + { + LLCoros::instance().launch("LLMessageSystem::acceptGroupInvitation", + boost::bind(response_group_invitation_coro, url, group_id, accept_invite)); + } + else + { + // if sim has no this cap, we can do nothing - regular request will fail + LL_WARNS("GroupInvite") << "No capability, can't reply to offline invitation!" << LL_ENDL; + } + } + else + { + EInstantMessage type = accept_invite ? IM_GROUP_INVITATION_ACCEPT : IM_GROUP_INVITATION_DECLINE; + + send_improved_im(group_id, + std::string("name"), + std::string("message"), + IM_ONLINE, + type, + transaction_id); + } +} + +void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accept_invite, S32 fee, bool use_offline_cap) +{ + LLSD payload; + if (accept_invite) + { + payload["group_id"] = group_id; + payload["transaction_id"] = transaction_id; + payload["fee"] = fee; + payload["use_offline_cap"] = use_offline_cap; + } + send_join_group_response(group_id, transaction_id, accept_invite, fee, use_offline_cap, payload); +} + bool join_group_response(const LLSD& notification, const LLSD& response) { // A bit of variable saving and restoring is used to deal with the case where your group list is full and you @@ -762,6 +875,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response) std::string name = notification_adjusted["payload"]["name"].asString(); std::string message = notification_adjusted["payload"]["message"].asString(); S32 fee = notification_adjusted["payload"]["fee"].asInteger(); + U8 use_offline_cap = notification_adjusted["payload"]["use_offline_cap"].asInteger(); if (option == 2 && !group_id.isNull()) { @@ -790,42 +904,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response) return false; } } - - if (accept_invite) - { - // If there is a fee to join this group, make - // sure the user is sure they want to join. - if (fee > 0) - { - LLSD args; - args["COST"] = llformat("%d", fee); - // Set the fee for next time to 0, so that we don't keep - // asking about a fee. - LLSD next_payload = notification_adjusted["payload"]; - next_payload["fee"] = 0; - LLNotificationsUtil::add("JoinGroupCanAfford", - args, - next_payload); - } - else - { - send_improved_im(group_id, - std::string("name"), - std::string("message"), - IM_ONLINE, - IM_GROUP_INVITATION_ACCEPT, - transaction_id); - } - } - else - { - send_improved_im(group_id, - std::string("name"), - std::string("message"), - IM_ONLINE, - IM_GROUP_INVITATION_DECLINE, - transaction_id); - } + send_join_group_response(group_id, transaction_id, accept_invite, fee, use_offline_cap, notification_adjusted["payload"]); sSavedGroupInvite[id] = LLSD::emptyMap(); sSavedResponse[id] = LLSD::emptyMap(); diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index 424aae1229..913abef2be 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -66,6 +66,11 @@ enum InventoryOfferResponse BOOL can_afford_transaction(S32 cost); void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE, S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null); +void send_join_group_response(LLUUID group_id, + LLUUID transaction_id, + bool accept_invite, + S32 fee, + bool use_offline_cap); void process_logout_reply(LLMessageSystem* msg, void**); void process_layer_data(LLMessageSystem *mesgsys, void **user_data); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 832dcc2dd8..e1437e28f7 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2818,6 +2818,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { capabilityNames.append("AbuseCategories"); capabilityNames.append("AcceptFriendship"); + capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!! capabilityNames.append("AgentPreferences"); capabilityNames.append("AgentState"); capabilityNames.append("AttachmentResources"); @@ -2828,6 +2829,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("CreateInventoryCategory"); capabilityNames.append("DeclineFriendship"); + capabilityNames.append("DeclineGroupInvite"); // ReadOfflineMsgs recieved messages only!!! capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("DirectDelivery"); capabilityNames.append("EnvironmentSettings"); @@ -2878,7 +2880,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); - //capabilityNames.append("ReadOfflineMsgs"); + capabilityNames.append("ReadOfflineMsgs"); // Only use with AcceptGroupInvite AcceptFriendship capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload");