summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2025-08-02 06:56:07 +0800
committerErik Kundiman <erik@megapahit.org>2025-08-02 06:56:07 +0800
commit51743334b81e5aa4be59417a80149d5f416b51f3 (patch)
tree5600f9f58389fe31b71e570bac7867d991408cf1
parentcb759bf9e0580b0c0799e33b8e7af1ea46a4c336 (diff)
parent7588afc86a016c00e6263284bc0db6d684c43895 (diff)
Merge branch 'main' into 2025.05
-rw-r--r--indra/newview/llagent.cpp6
-rw-r--r--indra/newview/llagent.h3
-rw-r--r--indra/newview/llappviewer.cpp123
-rw-r--r--indra/newview/llappviewer.h4
-rw-r--r--indra/newview/llavatarlist.cpp67
-rw-r--r--indra/newview/llavatarlist.h2
-rw-r--r--indra/newview/llfloaterpreference.cpp2
-rw-r--r--indra/newview/llpanelpeople.cpp8
-rw-r--r--indra/newview/llspeakers.cpp4
-rw-r--r--indra/newview/llstartup.cpp4
-rw-r--r--indra/newview/llviewermessage.cpp3
-rw-r--r--indra/newview/llvoavatar.cpp53
12 files changed, 156 insertions, 123 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 9ce14eb0ab..8422294ac7 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1305,6 +1305,12 @@ const LLVector3 &LLAgent::getPositionAgent()
return mFrameAgent.getOrigin();
}
+void LLAgent::setAvatarsPositions(const std::map<LLUUID, LLVector3d>& avatarsPositions)
+{
+ mAvatarsPositions.clear();
+ mAvatarsPositions = avatarsPositions;
+}
+
boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot_type fn)
{
return mOnPositionChanged.connect(fn);
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index b475782946..a2d2ecea9f 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -195,6 +195,8 @@ public:
// Call once per frame to update position, angles (radians).
void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y);
void setPositionAgent(const LLVector3 &center);
+ void setAvatarsPositions(const std::map<LLUUID, LLVector3d>& avatarsPositions);
+ const std::map<LLUUID, LLVector3d>& getAvatarsPositions() const { return mAvatarsPositions;}
boost::signals2::connection whenPositionChanged(position_signal_t::slot_type fn);
@@ -205,6 +207,7 @@ private:
position_signal_t mOnPositionChanged;
LLVector3d mLastTestGlobal;
+ std::map<LLUUID, LLVector3d> mAvatarsPositions;
//--------------------------------------------------------------------
// Velocity
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 8eabf0a5d1..c13fd397b1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -283,6 +283,9 @@ using namespace LL;
#include <discordpp.h>
static std::shared_ptr<discordpp::Client> gDiscordClient;
static uint64_t gDiscordTimestampsStart;
+static std::string gDiscordActivityDetails;
+static int32_t gDiscordPartyCurrentSize;
+static int32_t gDiscordPartyMaxSize;
#endif
static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
@@ -1356,7 +1359,10 @@ bool LLAppViewer::doFrame()
TimePoint fpsLimitFrameStartTime = std::chrono::steady_clock::now();
#ifdef LL_DISCORD
- discordpp::RunCallbacks();
+ {
+ LL_PROFILE_ZONE_NAMED("discord_callbacks");
+ discordpp::RunCallbacks();
+ }
#endif
LL_RECORD_BLOCK_TIME(FTM_FRAME);
@@ -5950,6 +5956,8 @@ void LLAppViewer::metricsSend(bool enable_reporting)
void LLAppViewer::initDiscordSocial()
{
+ gDiscordPartyCurrentSize = 1;
+ gDiscordPartyMaxSize = 0;
gDiscordTimestampsStart = time(nullptr);
gDiscordClient = std::make_shared<discordpp::Client>();
gDiscordClient->SetStatusChangedCallback([](discordpp::Client::Status status, discordpp::Client::Error, int32_t) {
@@ -5960,14 +5968,25 @@ void LLAppViewer::initDiscordSocial()
});
if (gSavedSettings.getBOOL("EnableDiscord"))
{
- gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, gSecAPIHandler->loadCredential("Discord")->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) {
- if (result.Successful())
- gDiscordClient->Connect();
- });
+ auto credential = gSecAPIHandler->loadCredential("Discord");
+ if (credential.notNull())
+ {
+ gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) {
+ if (result.Successful())
+ gDiscordClient->Connect();
+ else
+ LL_WARNS("Discord") << result.Error() << LL_ENDL;
+ });
+ }
+ else
+ {
+ LL_WARNS("Discord") << "Integration was enabled, but no credentials. Disabling integration." << LL_ENDL;
+ gSavedSettings.setBOOL("EnableDiscord", false);
+ }
}
}
-void LLAppViewer::handleDiscordSocial(const LLSD& value)
+void LLAppViewer::toggleDiscordIntegration(const LLSD& value)
{
static const uint64_t APPLICATION_ID = 1393451183741599796;
if (value.asBoolean())
@@ -5981,34 +6000,60 @@ void LLAppViewer::handleDiscordSocial(const LLSD& value)
if (result.Successful())
{
gDiscordClient->GetToken(APPLICATION_ID, code, codeVerifier.Verifier(), redirectUri, [](discordpp::ClientResult result, std::string accessToken, std::string, discordpp::AuthorizationTokenType, int32_t, std::string) {
- gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [](discordpp::ClientResult result) {
- if (result.Successful())
- gDiscordClient->Connect();
- });
- LLSD authenticator = LLSD::emptyMap();
- authenticator["token"] = accessToken;
- gSecAPIHandler->saveCredential(gSecAPIHandler->createCredential("Discord", LLSD::emptyMap(), authenticator), true);
+ if (result.Successful())
+ {
+ gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [accessToken](discordpp::ClientResult result) {
+ if (result.Successful())
+ {
+ LLSD authenticator = LLSD::emptyMap();
+ authenticator["token"] = accessToken;
+ gSecAPIHandler->saveCredential(gSecAPIHandler->createCredential("Discord", LLSD::emptyMap(), authenticator), true);
+ gDiscordClient->Connect();
+ }
+ else
+ {
+ LL_WARNS("Discord") << result.Error() << LL_ENDL;
+ }
+ });
+ }
+ else
+ {
+ LL_WARNS("Discord") << result.Error() << LL_ENDL;
+ }
});
}
else
{
+ LL_WARNS("Discord") << result.Error() << LL_ENDL;
gSavedSettings.setBOOL("EnableDiscord", false);
}
});
}
else
{
- gDiscordClient->RevokeToken(APPLICATION_ID, gSecAPIHandler->loadCredential("Discord")->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) {
- if (result.Successful())
- gDiscordClient->Disconnect();
+ gDiscordClient->Disconnect();
+ auto credential = gSecAPIHandler->loadCredential("Discord");
+ if (credential.notNull())
+ {
+ gDiscordClient->RevokeToken(APPLICATION_ID, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) {
+ if (result.Successful())
+ LL_INFOS("Discord") << "Access token successfully revoked." << LL_ENDL;
+ else
+ LL_WARNS("Discord") << "No access token to revoke." << LL_ENDL;
+ });
auto cred = new LLCredential("Discord");
gSecAPIHandler->deleteCredential(cred);
- });
+ }
+ else
+ {
+ LL_WARNS("Discord") << "Credentials are already nonexistent." << LL_ENDL;
+ }
}
}
void LLAppViewer::updateDiscordActivity()
{
+ LL_PROFILE_ZONE_SCOPED;
discordpp::Activity activity;
activity.SetType(discordpp::ActivityTypes::Playing);
discordpp::ActivityTimestamps timestamps;
@@ -6021,18 +6066,23 @@ void LLAppViewer::updateDiscordActivity()
return;
}
- if (gSavedSettings.getBOOL("ShowDiscordActivityDetails"))
+ static LLCachedControl<bool> show_details(gSavedSettings, "ShowDiscordActivityDetails", false);
+ if (show_details)
{
- LLAvatarName av_name;
- LLAvatarNameCache::get(gAgent.getID(), &av_name);
- auto name = av_name.getUserName();
- auto displayName = av_name.getDisplayName();
- if (name != displayName)
- name = displayName + " (" + name + ")";
- activity.SetDetails(name);
+ if (gDiscordActivityDetails.empty())
+ {
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(gAgent.getID(), &av_name);
+ gDiscordActivityDetails = av_name.getUserName();
+ auto displayName = av_name.getDisplayName();
+ if (gDiscordActivityDetails != displayName)
+ gDiscordActivityDetails = displayName + " (" + gDiscordActivityDetails + ")";
+ }
+ activity.SetDetails(gDiscordActivityDetails);
}
- if (gSavedSettings.getBOOL("ShowDiscordActivityState"))
+ static LLCachedControl<bool> show_state(gSavedSettings, "ShowDiscordActivityState", false);
+ if (show_state)
{
auto agent_pos_region = gAgent.getPositionAgent();
S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f);
@@ -6056,19 +6106,26 @@ void LLAppViewer::updateDiscordActivity()
auto location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z);
activity.SetState(location);
- auto world = LLWorld::getInstance();
- uuid_vec_t chat_radius_uuids, near_me_uuids;
- auto position = gAgent.getPositionGlobal();
- world->getAvatars(&chat_radius_uuids, NULL, position, CHAT_NORMAL_RADIUS);
- world->getAvatars(&near_me_uuids, NULL, position, gSavedSettings.getF32("MPVNearMeRange"));
discordpp::ActivityParty party;
party.SetId(location);
- party.SetCurrentSize(chat_radius_uuids.size());
- party.SetMaxSize(near_me_uuids.size());
+ party.SetCurrentSize(gDiscordPartyCurrentSize);
+ party.SetMaxSize(gDiscordPartyMaxSize);
activity.SetParty(party);
}
gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {});
}
+void LLAppViewer::updateDiscordPartyCurrentSize(int32_t size)
+{
+ gDiscordPartyCurrentSize = size;
+ updateDiscordActivity();
+}
+
+void LLAppViewer::updateDiscordPartyMaxSize(int32_t size)
+{
+ gDiscordPartyMaxSize = size;
+ updateDiscordActivity();
+}
+
#endif
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 3b6488dade..14e96afe94 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -253,8 +253,10 @@ public:
#ifdef LL_DISCORD
static void initDiscordSocial();
- static void handleDiscordSocial(const LLSD& value);
+ static void toggleDiscordIntegration(const LLSD& value);
static void updateDiscordActivity();
+ static void updateDiscordPartyCurrentSize(int32_t size);
+ static void updateDiscordPartyMaxSize(int32_t size);
#endif
protected:
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 5f9d03ca66..e29be0c757 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -48,12 +48,11 @@
#include "llvoiceclient.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "lltooldraganddrop.h"
-#include "llworld.h"
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
// Last interaction time update period.
-static const F32 LIT_UPDATE_PERIOD = 1;
+static const F32 LIT_UPDATE_PERIOD = 5;
// Maximum number of avatars that can be added to a list in one pass.
// Used to limit time spent for avatar list update per frame.
@@ -205,13 +204,25 @@ void LLAvatarList::draw()
if ((mShowLastInteractionTime || mAvatarDistance || mAvatarArrivalTime) && mLITUpdateTimer->hasExpired())
{
- if (mAvatarArrivalTime)
+ if (mAvatarArrivalTime || mAvatarDistance)
{
- updateAvatarArrivalTime();
- }
- if (mAvatarDistance)
- {
- updateAvatarDistance();
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for (auto it = items.begin(); it != items.end(); it++)
+ {
+ auto item = static_cast<LLAvatarListItem*>(*it);
+ if (mAvatarArrivalTime)
+ {
+ auto secs_since = LLDate::now().secondsSinceEpoch() - LLRecentPeople::instance().getArrivalTimeByID(item->getAvatarId());
+ if (secs_since >= 0)
+ item->setAvatarArrivalTime(secs_since);
+ }
+ if (mAvatarDistance)
+ {
+ auto avatarsPositions = gAgent.getAvatarsPositions();
+ item->setAvatarDistance(dist_vec(avatarsPositions[item->getAvatarId()], gAgent.getPositionGlobal()));
+ }
+ }
}
if (mShowLastInteractionTime)
{
@@ -554,46 +565,6 @@ void LLAvatarList::computeDifference(
LLCommonUtils::computeDifference(vnew_unsorted, vcur, vadded, vremoved);
}
-void LLAvatarList::updateAvatarArrivalTime()
-{
- std::vector<LLPanel*> items;
- getItems(items);
- auto uuids = getIDs();
- std::vector<LLVector3d> positions;
- auto me_pos = gAgent.getPositionGlobal();
- LLWorld::getInstance()->getAvatars(&uuids, &positions, me_pos, gSavedSettings.getF32("MPVNearMeRange"));
- LLRecentPeople::instance().updateAvatarsArrivalTime(uuids);
- for (auto it = items.begin(); it != items.end(); it++)
- {
- auto item = static_cast<LLAvatarListItem*>(*it);
- auto secs_since = LLDate::now().secondsSinceEpoch() - LLRecentPeople::instance().getArrivalTimeByID(item->getAvatarId());
- if (secs_since >= 0)
- item->setAvatarArrivalTime(secs_since);
- }
-}
-
- void LLAvatarList::updateAvatarDistance()
-{
- std::vector<LLPanel*> items;
- getItems(items);
- auto uuids = getIDs();
- std::vector<LLVector3d> positions;
- auto me_pos = gAgent.getPositionGlobal();
- LLWorld::getInstance()->getAvatars(&uuids, &positions, me_pos, gSavedSettings.getF32("MPVNearMeRange"));
- std::map <LLUUID, LLVector3d> avatarsPositions;
- auto pos_it = positions.begin();
- auto id_it = uuids.begin();
- for (;pos_it != positions.end() && id_it != uuids.end(); ++pos_it, ++id_it)
- {
- avatarsPositions[*id_it] = *pos_it;
- }
- for (auto it = items.begin(); it != items.end(); it++)
- {
- auto item = static_cast<LLAvatarListItem*>(*it);
- item->setAvatarDistance(dist_vec(avatarsPositions[item->getAvatarId()], me_pos));
- }
-}
-
// Refresh shown time of our last interaction with all listed avatars.
void LLAvatarList::updateLastInteractionTimes()
{
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 97b4f05985..e6e0728a3f 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -114,8 +114,6 @@ protected:
const uuid_vec_t& vnew,
uuid_vec_t& vadded,
uuid_vec_t& vremoved);
- void updateAvatarArrivalTime();
- void updateAvatarDistance();
void updateLastInteractionTimes();
void rebuildNames();
void onItemDoubleClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 4c8122bf71..2a6360cef8 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -367,7 +367,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering
#ifdef LL_DISCORD
- gSavedSettings.getControl("EnableDiscord")->getCommitSignal()->connect(boost::bind(&LLAppViewer::handleDiscordSocial, _2));
+ gSavedSettings.getControl("EnableDiscord")->getCommitSignal()->connect(boost::bind(&LLAppViewer::toggleDiscordIntegration, _2));
gSavedSettings.getControl("ShowDiscordActivityDetails")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity));
gSavedSettings.getControl("ShowDiscordActivityState")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity));
#endif
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 72fa553023..aca8cf189b 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -160,6 +160,7 @@ public:
mAvatarsPositions[*id_it] = *pos_it;
}
};
+ const id_to_pos_map_t& getAvatarsPositions() const { return mAvatarsPositions; }
protected:
virtual bool doCompare(const LLAvatarListItem* item1, const LLAvatarListItem* item2) const
@@ -843,8 +844,13 @@ void LLPanelPeople::updateNearbyList()
LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("MPVNearMeRange"));
mNearbyList->setDirty();
+#ifdef LL_DISCORD
+ if (gSavedSettings.getBOOL("EnableDiscord"))
+ LLAppViewer::updateDiscordPartyMaxSize(mNearbyList->getIDs().size());
+#endif
DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs());
+ gAgent.setAvatarsPositions(DISTANCE_COMPARATOR.getAvatarsPositions());
LLActiveSpeakerMgr::instance().update(true);
}
@@ -1565,7 +1571,7 @@ bool LLPanelPeople::updateNearbyArrivalTime()
{
std::vector<LLVector3d> positions;
std::vector<LLUUID> uuids;
- static LLCachedControl<F32> range(gSavedSettings, "NearMeRange");
+ static LLCachedControl<F32> range(gSavedSettings, "MPVNearMeRange");
LLWorld::getInstance()->getAvatars(&uuids, &positions, gAgent.getPositionGlobal(), range);
LLRecentPeople::instance().updateAvatarsArrivalTime(uuids);
return LLApp::isExiting();
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 4956c188fb..12a9d5e9b7 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -1026,6 +1026,10 @@ void LLLocalSpeakerMgr::updateSpeakerList()
uuid_vec_t avatar_ids;
std::vector<LLVector3d> positions;
LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS);
+#ifdef LL_DISCORD
+ if (gSavedSettings.getBOOL("EnableDiscord"))
+ LLAppViewer::updateDiscordPartyCurrentSize(avatar_ids.size());
+#endif
for(U32 i=0; i<avatar_ids.size(); i++)
{
setSpeaker(avatar_ids[i]);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index dfad169813..8d010553a0 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2327,10 +2327,6 @@ bool idle_startup()
do_startup_frame();
}
-#ifdef LL_DISCORD
- LLAppViewer::updateDiscordActivity();
-#endif
-
return true;
}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index d6f1b96a7b..86bd11d1eb 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3073,7 +3073,8 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
}
#ifdef LL_DISCORD
- LLAppViewer::updateDiscordActivity();
+ if (gSavedSettings.getBOOL("EnableDiscord"))
+ LLAppViewer::updateDiscordActivity();
#endif
if ( LLTracker::isTracking(NULL) )
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 8c3f219182..d7f6852c38 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -818,15 +818,14 @@ LLVOAvatar::~LLVOAvatar()
{
sInstances.remove(this);
- if (gSavedSettings.getBOOL("IMShowArrivalsDepartures"))
+ static LLCachedControl<bool> show_arrival_departures(gSavedSettings, "IMShowArrivalsDepartures", false);
+ if (show_arrival_departures)
{
- LLAvatarName av_name;
- LLAvatarNameCache::get(getID(), &av_name);
- auto display_name = av_name.getDisplayName();
- if (!display_name.empty())
+ auto full_name = getFullname();
+ if (!full_name.empty())
{
- LLChat chat{llformat("%s left.", display_name.c_str())};
- chat.mFromName = display_name;
+ LLChat chat{llformat("%s left.", full_name.c_str())};
+ chat.mFromName = full_name;
chat.mFromID = getID();
LLSD args;
args["COLOR"] = "ChatHistoryTextColor";
@@ -2583,31 +2582,21 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
{
mDebugExistenceTimer.reset();
debugAvatarRezTime("AvatarRezArrivedNotification", "avatar arrived");
- if (gSavedSettings.getBOOL("IMShowArrivalsDepartures"))
- {
- uuid_vec_t uuids;
- std::vector<LLVector3d> positions;
- LLWorld::getInstance()->getAvatars(&uuids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("MPVNearMeRange"));
- auto pos_it = positions.begin();
- auto id_it = uuids.begin();
- for (;pos_it != positions.end() && id_it != uuids.end(); ++pos_it, ++id_it)
- {
- if (*id_it == getID() && !isSelf())
- {
- LLAvatarName av_name;
- LLAvatarNameCache::get(getID(), &av_name);
- auto display_name = av_name.getDisplayName();
- if (!display_name.empty())
- {
- LLChat chat{llformat("%s arrived (%.1f m).", display_name.c_str(), dist_vec(*pos_it, gAgent.getPositionGlobal()))};
- chat.mFromName = display_name;
- chat.mFromID = getID();
- LLSD args;
- args["COLOR"] = "ChatHistoryTextColor";
- LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
- }
- break;
- }
+ static LLCachedControl<bool> show_arrival_departures(gSavedSettings, "IMShowArrivalsDepartures", false);
+ if (show_arrival_departures)
+ {
+ auto full_name = getFullname();
+ if (!full_name.empty())
+ {
+ auto avatarsPositions = gAgent.getAvatarsPositions();
+ auto id = getID();
+ auto avatarPosition = avatarsPositions[id];
+ LLChat chat{std::string{full_name + " arrived" + (avatarPosition.isExactlyZero() ? "" : llformat(" (%.1f m)", dist_vec(avatarPosition, gAgent.getPositionGlobal()))) + "."}};
+ chat.mFromName = full_name;
+ chat.mFromID = id;
+ LLSD args;
+ args["COLOR"] = "ChatHistoryTextColor";
+ LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
}
}
}