From afd726979aa544571addc94226155d6ab4e6c5ed Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 11 May 2024 09:58:22 -0400 Subject: Turn on GH Windows ReleaseOS build --- .github/workflows/build.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4785273b78..1a2b914e9a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -16,6 +16,9 @@ jobs: include: - runner: macos-12-xl developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer" + include: + - runner: windows-large + configuration: ReleaseOS runs-on: ${{ matrix.runner }} outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} -- cgit v1.2.3 From 4f70946048def860e54117ce03f4e9e57c415491 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 11 May 2024 10:14:49 -0400 Subject: Fix syntax error in build.yaml to enable Windows ReleaseOS --- .github/workflows/build.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1a2b914e9a..c500b3592d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -16,7 +16,6 @@ jobs: include: - runner: macos-12-xl developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer" - include: - runner: windows-large configuration: ReleaseOS runs-on: ${{ matrix.runner }} -- cgit v1.2.3 From a4d2574df2af19f5baa57bf27b5c5f888b765ede Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 13 May 2024 13:46:42 -0400 Subject: Run ReleaseOS builds, but only when a release page is requested. --- .github/workflows/build.yaml | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c500b3592d..3bf7964ba2 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -7,17 +7,24 @@ on: branches: ["main", "release/*", "project/*"] tags: ["Second_Life*"] +env: + # Build with a tag like "Second_Life#abcdef0" to generate a release page + # (used for builds we are planning to deploy). + RELEASE_RUN: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') && 'Y' }} + jobs: build: strategy: matrix: runner: [windows-large, macos-12-xl] configuration: [Release] + Linden: [true] include: - runner: macos-12-xl developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer" - runner: windows-large configuration: ReleaseOS + Linden: false runs-on: ${{ matrix.runner }} outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} @@ -39,7 +46,10 @@ jobs: AUTOBUILD_VSVER: "170" DEVELOPER_DIR: ${{ matrix.developer_dir }} # Ensure that Linden viewer builds engage Bugsplat. - BUGSPLAT_DB: ${{ matrix.configuration != 'ReleaseOS' && 'SecondLife_Viewer_2018' || '' }} + BUGSPLAT_DB: ${{ matrix.Linden && 'SecondLife_Viewer_2018' || '' }} + # Run BUILD steps for Release configuration. + # Run BUILD steps for ReleaseOS configuration only for release runs. + BUILD: ${{ (matrix.Linden || env.RELEASE_RUN) && 'Y' || '' }} build_coverity: false build_log_dir: ${{ github.workspace }}/.logs build_viewer: true @@ -58,16 +68,19 @@ jobs: variants: ${{ matrix.configuration }} steps: - name: Checkout code + if: env.BUILD uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} - name: Setup python + if: env.BUILD uses: actions/setup-python@v5 with: python-version: "3.11" - name: Checkout build variables + if: env.BUILD uses: actions/checkout@v4 with: repository: secondlife/build-variables @@ -75,17 +88,20 @@ jobs: path: .build-variables - name: Checkout master-message-template + if: env.BUILD uses: actions/checkout@v4 with: repository: secondlife/master-message-template path: .master-message-template - name: Install autobuild and python dependencies + if: env.BUILD run: pip3 install autobuild llsd - name: Cache autobuild packages - uses: actions/cache@v4 id: cache-installables + if: env.BUILD + uses: actions/cache@v4 with: path: .autobuild-installables key: ${{ runner.os }}-64-${{ matrix.configuration }}-${{ hashFiles('autobuild.xml') }} @@ -94,17 +110,19 @@ jobs: ${{ runner.os }}-64- - name: Install windows dependencies - if: runner.os == 'Windows' + if: env.BUILD && runner.os == 'Windows' run: choco install nsis-unicode - name: Determine source branch id: which-branch + if: env.BUILD uses: secondlife/viewer-build-util/which-branch@v2 with: token: ${{ github.token }} - name: Build id: build + if: env.BUILD shell: bash env: AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }} @@ -227,7 +245,7 @@ jobs: echo "artifact=$RUNNER_OS$cfg_suffix" >> $GITHUB_OUTPUT - name: Upload executable - if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.viewer_app + if: matrix.Linden && steps.build.outputs.viewer_app uses: actions/upload-artifact@v4 with: name: "${{ steps.build.outputs.artifact }}-app" @@ -237,7 +255,7 @@ jobs: # The other upload of nontrivial size is the symbol file. Use a distinct # artifact for that too. - name: Upload symbol file - if: matrix.configuration != 'ReleaseOS' + if: matrix.Linden uses: actions/upload-artifact@v4 with: name: "${{ steps.build.outputs.artifact }}-symbols" @@ -245,7 +263,7 @@ jobs: ${{ steps.build.outputs.symbolfile }} - name: Upload metadata - if: matrix.configuration != 'ReleaseOS' + if: matrix.Linden uses: actions/upload-artifact@v4 with: name: "${{ steps.build.outputs.artifact }}-metadata" @@ -256,7 +274,7 @@ jobs: - name: Upload physics package uses: actions/upload-artifact@v4 # should only be set for viewer-private - if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.physicstpv + if: matrix.Linden && steps.build.outputs.physicstpv with: name: "${{ steps.build.outputs.artifact }}-physics" # emitted by build.sh, zero or one lines @@ -362,8 +380,7 @@ jobs: release: needs: [build, sign-and-package-windows, sign-and-package-mac] runs-on: ubuntu-latest - # Build with a tag like "Second_Life#abcdef0" to generate a release page (used for builds we are planning to deploy). - if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') + if: env.RELEASE_RUN steps: - uses: actions/download-artifact@v4 with: -- cgit v1.2.3 From 9d30040dfe161e750a897065c16450478e740aa9 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 May 2024 15:57:50 -0400 Subject: Try to work around workflow YAML env setting limitation. --- .github/workflows/build.yaml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 3bf7964ba2..afac61cb1b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -13,7 +13,22 @@ env: RELEASE_RUN: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') && 'Y' }} jobs: + # The whole point of the setvar job is that we want to reference global + # env.RELEASE_RUN in build.env, but a job.env can't directly reference the + # global env context. + setvar: + runs-on: ubuntu-latest + outputs: + release_run: ${{ steps.setvar.outputs.release_run }} + steps: + - name: Set Variable + id: setvar + shell: bash + run: | + echo "release_run=$RELEASE_RUN" >> "$GITHUB_OUTPUT" + build: + needs: setvar strategy: matrix: runner: [windows-large, macos-12-xl] @@ -49,7 +64,7 @@ jobs: BUGSPLAT_DB: ${{ matrix.Linden && 'SecondLife_Viewer_2018' || '' }} # Run BUILD steps for Release configuration. # Run BUILD steps for ReleaseOS configuration only for release runs. - BUILD: ${{ (matrix.Linden || env.RELEASE_RUN) && 'Y' || '' }} + BUILD: ${{ (matrix.Linden || needs.setvar.outputs.release_run) && 'Y' || '' }} build_coverity: false build_log_dir: ${{ github.workspace }}/.logs build_viewer: true -- cgit v1.2.3 From 18c1458409fbb4ab3a734bd80673a7726fee107f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 May 2024 16:01:26 -0400 Subject: Can't reference global env in job.if either. --- .github/workflows/build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index afac61cb1b..07499f768c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -393,9 +393,9 @@ jobs: version: ${{ needs.build.outputs.viewer_version }} release: - needs: [build, sign-and-package-windows, sign-and-package-mac] + needs: [setvar, build, sign-and-package-windows, sign-and-package-mac] runs-on: ubuntu-latest - if: env.RELEASE_RUN + if: needs.setvar.outputs.release_run steps: - uses: actions/download-artifact@v4 with: -- cgit v1.2.3 From f822193974af363fa4bb0208dc02848be6c983a2 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 May 2024 16:08:54 -0400 Subject: Make env.RELEASE_RUN the empty string if false not the string "false", which is true. --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 07499f768c..47f612f028 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -10,7 +10,7 @@ on: env: # Build with a tag like "Second_Life#abcdef0" to generate a release page # (used for builds we are planning to deploy). - RELEASE_RUN: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') && 'Y' }} + RELEASE_RUN: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') && 'Y' || '' }} jobs: # The whole point of the setvar job is that we want to reference global -- cgit v1.2.3 From 1f0b80f709dd3b263e88ca6e3db027a1406ec240 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 May 2024 17:15:25 -0400 Subject: Streamline the new workflow `RELEASE_RUN` logic a little. Since downstream jobs reference the output of the new `setvar` job, instead of directly referencing global `env.RELEASE_RUN`, no need to set `RELEASE_RUN` in the global environment. --- .github/workflows/build.yaml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 47f612f028..94bd13f4af 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -7,19 +7,22 @@ on: branches: ["main", "release/*", "project/*"] tags: ["Second_Life*"] -env: - # Build with a tag like "Second_Life#abcdef0" to generate a release page - # (used for builds we are planning to deploy). - RELEASE_RUN: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') && 'Y' || '' }} - jobs: - # The whole point of the setvar job is that we want to reference global - # env.RELEASE_RUN in build.env, but a job.env can't directly reference the - # global env context. + # The whole point of the setvar job is that we want to set a variable once + # that will be consumed by multiple subsequent jobs. We tried setting it in + # the global env, but a job.env can't directly reference the global env + # context. setvar: runs-on: ubuntu-latest outputs: release_run: ${{ steps.setvar.outputs.release_run }} + env: + # Build with a tag like "Second_Life#abcdef0" to generate a release page + # (used for builds we are planning to deploy). + # When you want to use a string variable as a workflow YAML boolean, it's + # important to ensure it's the empty string when false. If you omit || '', + # its value when false is "false", which is interpreted as true. + RELEASE_RUN: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') && 'Y' || '' }} steps: - name: Set Variable id: setvar -- cgit v1.2.3 From 0960ae78923b51df4408bfaaeba5399f85d55efe Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 15 May 2024 14:41:56 -0700 Subject: Experiment with getting manually triggered workflow builds to optionally do a release --- .github/workflows/build.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 94bd13f4af..364a3a97e8 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -2,6 +2,11 @@ name: Build on: workflow_dispatch: + inputs: + release_run: + type: boolean + description: Do a release of this build + default: false pull_request: push: branches: ["main", "release/*", "project/*"] @@ -398,7 +403,7 @@ jobs: release: needs: [setvar, build, sign-and-package-windows, sign-and-package-mac] runs-on: ubuntu-latest - if: needs.setvar.outputs.release_run + if: needs.setvar.outputs.release_run || github.event.inputs.release_run steps: - uses: actions/download-artifact@v4 with: -- cgit v1.2.3 From 7feec9998e61c234b1a9557c2edf8fc2b52a73cc Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 15 May 2024 15:04:16 -0700 Subject: Move all release_run logic into setvar job. --- .github/workflows/build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 364a3a97e8..b60f787a9c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -27,7 +27,7 @@ jobs: # When you want to use a string variable as a workflow YAML boolean, it's # important to ensure it's the empty string when false. If you omit || '', # its value when false is "false", which is interpreted as true. - RELEASE_RUN: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life') && 'Y' || '' }} + RELEASE_RUN: ${{ (github.event.inputs.release_run || github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life')) && 'Y' || '' }} steps: - name: Set Variable id: setvar @@ -403,7 +403,7 @@ jobs: release: needs: [setvar, build, sign-and-package-windows, sign-and-package-mac] runs-on: ubuntu-latest - if: needs.setvar.outputs.release_run || github.event.inputs.release_run + if: needs.setvar.outputs.release_run steps: - uses: actions/download-artifact@v4 with: -- cgit v1.2.3 From 8011d3f457ca86b9610d5e9580d554393dd4a0a6 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 15 May 2024 16:08:04 -0700 Subject: Fix channel detection for mac builds --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4785273b78..b26006f2ff 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -179,7 +179,7 @@ jobs: # determine the viewer channel from the branch name branch=$AUTOBUILD_VCS_BRANCH - IFS='/' read -ra ba <<< $branch + IFS='/' read -ra ba <<< "$branch" prefix=${ba[0]} if [ "$prefix" == "project" ]; then IFS='_' read -ra prj <<< "${ba[1]}" -- cgit v1.2.3 From 0f00dc2f658869cc73a18b03b024a6cc88964e0b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 22 May 2024 20:29:55 +0300 Subject: Add support for sending messages to Nearby chat from Lua script --- indra/llui/llchat.h | 6 +++- indra/newview/llchathistory.cpp | 39 +++++++++++++++++-------- indra/newview/llchathistory.h | 3 +- indra/newview/llchatitemscontainerctrl.cpp | 5 ++-- indra/newview/llchatitemscontainerctrl.h | 6 +++- indra/newview/llfloaterimnearbychat.cpp | 3 ++ indra/newview/llfloaterimnearbychathandler.cpp | 12 ++++++-- indra/newview/llfloaterimnearbychatlistener.cpp | 9 +++--- indra/newview/llfloaterimnearbychatlistener.h | 4 +-- indra/newview/llviewerchat.cpp | 9 ++++-- indra/newview/llviewermessage.cpp | 4 ++- indra/newview/scripts/lua/LLChat.lua | 17 +++++++++++ indra/newview/skins/default/xui/en/strings.xml | 4 ++- 13 files changed, 89 insertions(+), 32 deletions(-) create mode 100644 indra/newview/scripts/lua/LLChat.lua diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index 56105add7e..8fd92c2550 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -89,7 +89,8 @@ public: mPosAgent(), mURL(), mChatStyle(CHAT_STYLE_NORMAL), - mSessionID() + mSessionID(), + mIsScript(false) { } std::string mText; // UTF-8 line of text @@ -107,6 +108,9 @@ public: std::string mURL; EChatStyle mChatStyle; LLUUID mSessionID; + + bool mIsScript; }; +static const std::string LUA_PREFIX("[LUA]"); #endif diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 4a08eace62..6f02a08020 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -125,6 +125,7 @@ public: mUserNameTextBox(NULL), mTimeBoxTextBox(NULL), mNeedsTimeBox(true), + mIsFromScript(false), mAvatarNameCacheConnection() {} @@ -658,11 +659,12 @@ public: const LLUUID& getAvatarId () const { return mAvatarID;} - void setup(const LLChat& chat, const LLStyle::Params& style_params, const LLSD& args) + void setup(const LLChat& chat, const LLStyle::Params& style_params, const LLSD& args, bool is_script) { mAvatarID = chat.mFromID; mSessionID = chat.mSessionID; mSourceType = chat.mSourceType; + mIsFromScript = is_script; // To be able to report a message, we need a copy of it's text // and it's easier to store text directly than trying to get @@ -732,7 +734,7 @@ public: username_end == (chat.mFromName.length() - 1)) { mFrom = chat.mFromName.substr(0, username_start); - user_name->setValue(mFrom); + user_name->setValue(mIsFromScript ? LLTrans::getString("ScriptBy") + mFrom : mFrom); if (gSavedSettings.getBOOL("NameTagShowUsernames")) { @@ -774,7 +776,7 @@ public: switch (mSourceType) { case CHAT_SOURCE_AGENT: - icon->setValue(chat.mFromID); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : chat.mFromID); break; case CHAT_SOURCE_OBJECT: icon->setValue(LLSD("OBJECT_Icon")); @@ -787,7 +789,7 @@ public: icon->setValue(LLSD("Command_Destinations_Icon")); break; case CHAT_SOURCE_UNKNOWN: - icon->setValue(LLSD("Unknown_Icon")); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : chat.mFromID); } // In case the message came from an object, save the object info @@ -1029,7 +1031,14 @@ private: mFrom = av_name.getDisplayName(); LLTextBox* user_name = getChild("user_name"); - user_name->setValue( LLSD(av_name.getDisplayName() ) ); + if(mIsFromScript) + { + user_name->setValue(LLSD(LLTrans::getString("ScriptBy") + av_name.getDisplayName())); + } + else + { + user_name->setValue(LLSD(av_name.getDisplayName())); + } user_name->setToolTip( av_name.getUserName() ); if (gSavedSettings.getBOOL("NameTagShowUsernames") && @@ -1071,6 +1080,8 @@ protected: bool mNeedsTimeBox; + bool mIsFromScript; + private: boost::signals2::connection mAvatarNameCacheConnection; }; @@ -1088,6 +1099,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) mTopHeaderPad(p.top_header_pad), mBottomHeaderPad(p.bottom_header_pad), mIsLastMessageFromLog(false), + mIsLastFromScript(false), mNotifyAboutUnreadMsg(p.notify_unread_msg) { LLTextEditor::Params editor_params(p); @@ -1185,11 +1197,11 @@ LLView* LLChatHistory::getSeparator() return separator; } -LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args) +LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args, bool is_script) { LLChatHistoryHeader* header = LLChatHistoryHeader::createInstance(mMessageHeaderFilename); if (header) - header->setup(chat, style_params, args); + header->setup(chat, style_params, args, is_script); return header; } @@ -1258,8 +1270,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL name_params.color(name_color); name_params.readonly_color(name_color); - std::string prefix = chat.mText.substr(0, 4); - + bool is_lua = (chat.mText.substr(0, LUA_PREFIX.size()) == LUA_PREFIX); + std::string prefix = chat.mText.substr(is_lua ? LUA_PREFIX.size() : 0, 4); //IRC styled /me messages. bool irc_me = prefix == "/me " || prefix == "/me'"; @@ -1393,7 +1405,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL && mLastFromID == chat.mFromID && mLastMessageTime.notNull() && (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 - && mIsLastMessageFromLog == message_from_log) //distinguish between current and previous chat session's histories + && mIsLastMessageFromLog == message_from_log //distinguish between current and previous chat session's histories + && mIsLastFromScript == is_lua) { view = getSeparator(); if (!view) @@ -1408,7 +1421,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } else { - view = getHeader(chat, name_params, args); + view = getHeader(chat, name_params, args, is_lua); if (!view) { LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL; @@ -1437,6 +1450,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mLastFromID = chat.mFromID; mLastMessageTime = new_message_time; mIsLastMessageFromLog = message_from_log; + mIsLastFromScript = is_lua; } // body of the message processing @@ -1491,7 +1505,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // usual messages showing else if (!teleport_separator) { - std::string message = irc_me ? chat.mText.substr(3) : chat.mText; + std::string message = is_lua ? chat.mText.substr(LUA_PREFIX.size()) : chat.mText; + message = irc_me ? message.substr(3) : message; //MESSAGE TEXT PROCESSING //*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010) diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index b8364ff860..8acbea6ed5 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -101,7 +101,7 @@ class LLChatHistory : public LLUICtrl * Builds a message header. * @return pointer to LLView header object. */ - LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args); + LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args, bool is_script = false); public: ~LLChatHistory(); LLSD getValue() const; @@ -127,6 +127,7 @@ class LLChatHistory : public LLUICtrl LLDate mLastMessageTime; bool mIsLastMessageFromLog; bool mNotifyAboutUnreadMsg; + bool mIsLastFromScript; //std::string mLastMessageTimeStr; std::string mMessageHeaderFilename; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 2b875c708d..8eabe3d222 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -187,6 +187,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification) int sType = notification["source"].asInteger(); mSourceType = (EChatSourceType)sType; + mIsFromScript = notification["is_lua"].asBoolean(); std::string color_name = notification["text_color"].asString(); @@ -214,7 +215,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification) { std::string str_sender; - str_sender = fromName; + str_sender = mIsFromScript ? LLTrans::getString("ScriptBy") + fromName : fromName; str_sender+=" "; @@ -401,7 +402,7 @@ void LLFloaterIMNearbyChatToastPanel::draw() else if(mSourceType == CHAT_SOURCE_SYSTEM) icon->setValue(LLSD("SL_Logo")); else if(mSourceType == CHAT_SOURCE_AGENT) - icon->setValue(mFromID); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : mFromID); else if(!mFromID.isNull()) icon->setValue(mFromID); } diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h index d041615060..7df00e8fd9 100644 --- a/indra/newview/llchatitemscontainerctrl.h +++ b/indra/newview/llchatitemscontainerctrl.h @@ -48,7 +48,8 @@ protected: LLFloaterIMNearbyChatToastPanel() : mIsDirty(false), - mSourceType(CHAT_SOURCE_OBJECT) + mSourceType(CHAT_SOURCE_OBJECT), + mIsFromScript(false) {}; public: ~LLFloaterIMNearbyChatToastPanel(){} @@ -58,6 +59,8 @@ public: const LLUUID& getFromID() const { return mFromID;} const std::string& getFromName() const { return mFromName; } + bool isFromScript() { return mIsFromScript; } + //void addText (const std::string& message , const LLStyle::Params& input_params = LLStyle::Params()); //void setMessage (const LLChat& msg); void snapToMessageHeight (); @@ -88,6 +91,7 @@ private: std::string mFromName; EChatSourceType mSourceType; LLChatMsgBox* mMsgText; + bool mIsFromScript; diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index e64f468cbe..6b817c7cf1 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; + const S32 EXPANDED_HEIGHT = 266; const S32 COLLAPSED_HEIGHT = 60; const S32 EXPANDED_MIN_HEIGHT = 150; diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 77ceea19af..91d9cd56cf 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -301,12 +301,13 @@ void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat) { LLUUID fromID = chat["from_id"].asUUID(); // agent id or object id std::string from = chat["from"].asString(); + bool is_lua = chat["is_lua"].asBoolean(); LLToast* toast = m_active_toasts[0].get(); if (toast) { LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast(toast->getPanel()); - if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText()) + if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->isFromScript() == is_lua && panel->canAddText()) { panel->addMessage(chat); toast->reshapeToPanel(); @@ -600,15 +601,19 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, std::string toast_msg; if (chat_msg.mChatStyle == CHAT_STYLE_IRC) { + if (chat_msg.mIsScript) + { + toast_msg += LLTrans::getString("ScriptStr"); + } if (!chat_msg.mFromName.empty()) { toast_msg += chat_msg.mFromName; } - toast_msg += chat_msg.mText.substr(3); + toast_msg += chat_msg.mText.substr(chat_msg.mIsScript ? LUA_PREFIX.size() + 3 : 3); } else { - toast_msg = chat_msg.mText; + toast_msg = chat_msg.mIsScript ? chat_msg.mText.substr(LUA_PREFIX.size()) : chat_msg.mText; } bool chat_overlaps = false; @@ -658,6 +663,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, chat["color_alpha"] = r_color_alpha; chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ; chat["message"] = toast_msg; + chat["is_lua"] = chat_msg.mIsScript; channel->addChat(chat); } diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp index 616acf0eae..d6dfe42639 100644 --- a/indra/newview/llfloaterimnearbychatlistener.cpp +++ b/indra/newview/llfloaterimnearbychatlistener.cpp @@ -36,10 +36,9 @@ #include "llviewercontrol.h" -LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar) +LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener() : LLEventAPI("LLChatBar", - "LLChatBar listener to (e.g.) sendChat, etc."), - mChatbar(chatbar) + "LLChatBar listener to (e.g.) sendChat, etc.") { add("sendChat", "Send chat to the simulator:\n" @@ -54,7 +53,7 @@ LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyCh void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const { // Extract the data - std::string chat_text = chat_data["message"].asString(); + std::string chat_text = LUA_PREFIX + chat_data["message"].asString(); S32 channel = 0; if (chat_data.has("channel")) @@ -95,6 +94,6 @@ void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const } // 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_to_send, type_o_chat, ((BOOL) (channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim")); } diff --git a/indra/newview/llfloaterimnearbychatlistener.h b/indra/newview/llfloaterimnearbychatlistener.h index 96184d95b3..0df0341d36 100644 --- a/indra/newview/llfloaterimnearbychatlistener.h +++ b/indra/newview/llfloaterimnearbychatlistener.h @@ -38,12 +38,10 @@ class LLFloaterIMNearbyChat; class LLFloaterIMNearbyChatListener : public LLEventAPI { public: - LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar); + LLFloaterIMNearbyChatListener(); private: void sendChat(LLSD const & chat_data) const; - - LLFloaterIMNearbyChat & mChatbar; }; #endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 597cf3c98c..70c426740b 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -30,6 +30,7 @@ // newview includes #include "llagent.h" // gAgent #include "llslurl.h" +#include "lltrans.h" #include "lluicolor.h" #include "lluicolortable.h" #include "llviewercontrol.h" // gSavedSettings @@ -216,8 +217,7 @@ S32 LLViewerChat::getChatFontSize() //static void LLViewerChat::formatChatMsg(const LLChat& chat, std::string& formated_msg) { - std::string tmpmsg = chat.mText; - + std::string tmpmsg = chat.mIsScript ? chat.mText.substr(LUA_PREFIX.size()) : chat.mText; if(chat.mChatStyle == CHAT_STYLE_IRC) { formated_msg = chat.mFromName + tmpmsg.substr(3); @@ -227,6 +227,11 @@ void LLViewerChat::formatChatMsg(const LLChat& chat, std::string& formated_msg) formated_msg = tmpmsg; } + if (chat.mIsScript) + { + formated_msg = LLTrans::getString("ScriptStr") + formated_msg; + } + } //static diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 52bc2d9654..4fe5beceae 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2600,8 +2600,10 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) BOOL ircstyle = FALSE; + chat.mIsScript = (mesg.substr(0, LUA_PREFIX.size()) == LUA_PREFIX); + // Look for IRC-style emotes here so chatbubbles work - std::string prefix = mesg.substr(0, 4); + std::string prefix = mesg.substr(chat.mIsScript ? LUA_PREFIX.size() : 0, 4); if (prefix == "/me " || prefix == "/me'") { ircstyle = TRUE; diff --git a/indra/newview/scripts/lua/LLChat.lua b/indra/newview/scripts/lua/LLChat.lua new file mode 100644 index 0000000000..7db538e837 --- /dev/null +++ b/indra/newview/scripts/lua/LLChat.lua @@ -0,0 +1,17 @@ +leap = require 'leap' + +local LLChat = {} + +function LLChat.sendNearby(msg) + leap.send('LLChatBar', {op='sendChat', message=msg}) +end + +function LLChat.sendWhisper(msg) + leap.send('LLChatBar', {op='sendChat', type='whisper', message=msg}) +end + +function LLChat.sendShout(msg) + leap.send('LLChatBar', {op='sendChat', type='shout', message=msg}) +end + +return LLChat diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index bee58da6b0..76a2660dbb 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -534,7 +534,9 @@ http://secondlife.com/support for help fixing this problem. Change your default animations Force your avatar to sit Change your environment settings - + + + Not Connected (You) -- cgit v1.2.3 From 85664b011e37c6c9926924f6fb72ceeb10d07833 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 22 May 2024 21:03:45 +0300 Subject: add throttle for sending messages; add simple demo script --- indra/newview/llfloaterimnearbychatlistener.cpp | 11 +++++++++++ indra/newview/scripts/lua/test_LLChat.lua | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 indra/newview/scripts/lua/test_LLChat.lua diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp index d6dfe42639..e8fb510111 100644 --- a/indra/newview/llfloaterimnearbychatlistener.cpp +++ b/indra/newview/llfloaterimnearbychatlistener.cpp @@ -35,6 +35,7 @@ #include "llchat.h" #include "llviewercontrol.h" +static const F32 CHAT_THROTTLE_PERIOD = 1.f; LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener() : LLEventAPI("LLChatBar", @@ -52,6 +53,16 @@ LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener() // "sendChat" command void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const { + static F64 last_throttle_time = 0.0; + F64 cur_time = LLTimer::getElapsedSeconds(); + + if (cur_time < last_throttle_time + CHAT_THROTTLE_PERIOD) + { + LL_DEBUGS("LLFloaterIMNearbyChatListener") << "'sendChat' was throttled" << LL_ENDL; + return; + } + last_throttle_time = cur_time; + // Extract the data std::string chat_text = LUA_PREFIX + chat_data["message"].asString(); diff --git a/indra/newview/scripts/lua/test_LLChat.lua b/indra/newview/scripts/lua/test_LLChat.lua new file mode 100644 index 0000000000..95bd218baa --- /dev/null +++ b/indra/newview/scripts/lua/test_LLChat.lua @@ -0,0 +1,18 @@ +LLChat = require 'LLChat' + +function generateRandomWord(length) + local alphabet = "abcdefghijklmnopqrstuvwxyz" + local word = "" + for i = 1, length do + local randomIndex = math.random(1, #alphabet) + word = word .. alphabet:sub(randomIndex, randomIndex) + end + return word +end + +local msg = "" +math.randomseed(os.time()) +for i = 1, math.random(1, 10) do + msg = msg .. " ".. generateRandomWord(math.random(1, 8)) +end +LLChat.sendNearby(msg) -- cgit v1.2.3 From c38e71411080af9e03646bbe34f766201d942afd Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Thu, 23 May 2024 13:13:47 +0300 Subject: mac build fix --- indra/newview/llchathistory.cpp | 4 ++-- indra/newview/llchatitemscontainerctrl.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 6f02a08020..54b0c171f1 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -776,7 +776,7 @@ public: switch (mSourceType) { case CHAT_SOURCE_AGENT: - icon->setValue(mIsFromScript ? LLSD("Inv_Script") : chat.mFromID); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : LLSD(chat.mFromID)); break; case CHAT_SOURCE_OBJECT: icon->setValue(LLSD("OBJECT_Icon")); @@ -789,7 +789,7 @@ public: icon->setValue(LLSD("Command_Destinations_Icon")); break; case CHAT_SOURCE_UNKNOWN: - icon->setValue(mIsFromScript ? LLSD("Inv_Script") : chat.mFromID); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : LLSD(chat.mFromID)); } // In case the message came from an object, save the object info diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 8eabe3d222..0561d56fe1 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -402,7 +402,7 @@ void LLFloaterIMNearbyChatToastPanel::draw() else if(mSourceType == CHAT_SOURCE_SYSTEM) icon->setValue(LLSD("SL_Logo")); else if(mSourceType == CHAT_SOURCE_AGENT) - icon->setValue(mIsFromScript ? LLSD("Inv_Script") : mFromID); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : LLSD(mFromID)); else if(!mFromID.isNull()) icon->setValue(mFromID); } -- cgit v1.2.3 From e4b7d2f463d19cab28985414365fd8415e3dc700 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 24 May 2024 15:24:50 +0300 Subject: Mark script messages in compact mode too; code clean up --- indra/llui/llchat.h | 12 +++++++++++ indra/newview/llchathistory.cpp | 28 ++++++++++++------------- indra/newview/llfloaterimnearbychathandler.cpp | 2 +- indra/newview/llfloaterimnearbychatlistener.cpp | 12 +++++------ indra/newview/llfloaterimnearbychatlistener.h | 4 +++- indra/newview/llviewerchat.cpp | 2 +- indra/newview/scripts/lua/test_LLChat.lua | 8 +++---- 7 files changed, 40 insertions(+), 28 deletions(-) diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index 8fd92c2550..343b81ba8d 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -113,4 +113,16 @@ public: }; static const std::string LUA_PREFIX("[LUA]"); +inline std::string remove_LUA_PREFIX(const std::string &string, bool is_lua) +{ + if (is_lua) + { + return string.substr(LUA_PREFIX.size()); + } + else + { + return string; + } +} + #endif diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 54b0c171f1..7ee0f3dd7a 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -665,6 +665,7 @@ public: mSessionID = chat.mSessionID; mSourceType = chat.mSourceType; mIsFromScript = is_script; + mPrefix = mIsFromScript ? LLTrans::getString("ScriptBy") : ""; // To be able to report a message, we need a copy of it's text // and it's easier to store text directly than trying to get @@ -734,7 +735,7 @@ public: username_end == (chat.mFromName.length() - 1)) { mFrom = chat.mFromName.substr(0, username_start); - user_name->setValue(mIsFromScript ? LLTrans::getString("ScriptBy") + mFrom : mFrom); + user_name->setValue(mPrefix + mFrom); if (gSavedSettings.getBOOL("NameTagShowUsernames")) { @@ -789,7 +790,7 @@ public: icon->setValue(LLSD("Command_Destinations_Icon")); break; case CHAT_SOURCE_UNKNOWN: - icon->setValue(mIsFromScript ? LLSD("Inv_Script") : LLSD(chat.mFromID)); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : LLSD("Unknown_Icon")); } // In case the message came from an object, save the object info @@ -1031,14 +1032,7 @@ private: mFrom = av_name.getDisplayName(); LLTextBox* user_name = getChild("user_name"); - if(mIsFromScript) - { - user_name->setValue(LLSD(LLTrans::getString("ScriptBy") + av_name.getDisplayName())); - } - else - { - user_name->setValue(LLSD(av_name.getDisplayName())); - } + user_name->setValue(LLSD(mPrefix + av_name.getDisplayName())); user_name->setToolTip( av_name.getUserName() ); if (gSavedSettings.getBOOL("NameTagShowUsernames") && @@ -1081,6 +1075,7 @@ protected: bool mNeedsTimeBox; bool mIsFromScript; + std::string mPrefix; private: boost::signals2::connection mAvatarNameCacheConnection; @@ -1270,8 +1265,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL name_params.color(name_color); name_params.readonly_color(name_color); - bool is_lua = (chat.mText.substr(0, LUA_PREFIX.size()) == LUA_PREFIX); - std::string prefix = chat.mText.substr(is_lua ? LUA_PREFIX.size() : 0, 4); + bool is_lua = LLStringUtil::startsWith(chat.mText, LUA_PREFIX); + + std::string message = remove_LUA_PREFIX(chat.mText, is_lua); + std::string prefix = message.substr(0, 4); + //IRC styled /me messages. bool irc_me = prefix == "/me " || prefix == "/me'"; @@ -1347,6 +1345,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // names showing if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size()) { + std::string script_prefix = is_lua ? LLTrans::getString("ScriptBy") : ""; // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. if (chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull()) { @@ -1371,7 +1370,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); // Add link to avatar's inspector and delimiter to message. - mEditor->appendText(std::string(link_params.link_href) + delimiter, + mEditor->appendText(script_prefix + std::string(link_params.link_href) + delimiter, prependNewLineState, link_params); prependNewLineState = false; } @@ -1384,7 +1383,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } else { - mEditor->appendText("" + chat.mFromName + "" + delimiter, + mEditor->appendText(script_prefix + "" + chat.mFromName + "" + delimiter, prependNewLineState, body_message_params); prependNewLineState = false; } @@ -1505,7 +1504,6 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // usual messages showing else if (!teleport_separator) { - std::string message = is_lua ? chat.mText.substr(LUA_PREFIX.size()) : chat.mText; message = irc_me ? message.substr(3) : message; //MESSAGE TEXT PROCESSING diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 91d9cd56cf..0c7cd3aec4 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -613,7 +613,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, } else { - toast_msg = chat_msg.mIsScript ? chat_msg.mText.substr(LUA_PREFIX.size()) : chat_msg.mText; + toast_msg = remove_LUA_PREFIX(chat_msg.mText, chat_msg.mIsScript); } bool chat_overlaps = false; diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp index e8fb510111..e1be6f7281 100644 --- a/indra/newview/llfloaterimnearbychatlistener.cpp +++ b/indra/newview/llfloaterimnearbychatlistener.cpp @@ -39,7 +39,8 @@ static const F32 CHAT_THROTTLE_PERIOD = 1.f; LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener() : LLEventAPI("LLChatBar", - "LLChatBar listener to (e.g.) sendChat, etc.") + "LLChatBar listener to (e.g.) sendChat, etc."), + mLastThrottleTime(0) { add("sendChat", "Send chat to the simulator:\n" @@ -51,17 +52,16 @@ LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener() // "sendChat" command -void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const +void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) { - static F64 last_throttle_time = 0.0; F64 cur_time = LLTimer::getElapsedSeconds(); - if (cur_time < last_throttle_time + CHAT_THROTTLE_PERIOD) + if (cur_time < mLastThrottleTime + CHAT_THROTTLE_PERIOD) { LL_DEBUGS("LLFloaterIMNearbyChatListener") << "'sendChat' was throttled" << LL_ENDL; return; } - last_throttle_time = cur_time; + mLastThrottleTime = cur_time; // Extract the data std::string chat_text = LUA_PREFIX + chat_data["message"].asString(); @@ -105,6 +105,6 @@ void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const } // Send it as if it was typed in - LLFloaterIMNearbyChat::sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL) (channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim")); + LLFloaterIMNearbyChat::sendChatFromViewer(chat_to_send, type_o_chat, ((channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim")); } diff --git a/indra/newview/llfloaterimnearbychatlistener.h b/indra/newview/llfloaterimnearbychatlistener.h index 0df0341d36..2d7c851f2c 100644 --- a/indra/newview/llfloaterimnearbychatlistener.h +++ b/indra/newview/llfloaterimnearbychatlistener.h @@ -41,7 +41,9 @@ public: LLFloaterIMNearbyChatListener(); private: - void sendChat(LLSD const & chat_data) const; + void sendChat(LLSD const & chat_data); + + F64 mLastThrottleTime; }; #endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 70c426740b..ce29ceac1a 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -217,7 +217,7 @@ S32 LLViewerChat::getChatFontSize() //static void LLViewerChat::formatChatMsg(const LLChat& chat, std::string& formated_msg) { - std::string tmpmsg = chat.mIsScript ? chat.mText.substr(LUA_PREFIX.size()) : chat.mText; + std::string tmpmsg = remove_LUA_PREFIX(chat.mText, chat.mIsScript); if(chat.mChatStyle == CHAT_STYLE_IRC) { formated_msg = chat.mFromName + tmpmsg.substr(3); diff --git a/indra/newview/scripts/lua/test_LLChat.lua b/indra/newview/scripts/lua/test_LLChat.lua index 95bd218baa..883b82fafb 100644 --- a/indra/newview/scripts/lua/test_LLChat.lua +++ b/indra/newview/scripts/lua/test_LLChat.lua @@ -2,15 +2,15 @@ LLChat = require 'LLChat' function generateRandomWord(length) local alphabet = "abcdefghijklmnopqrstuvwxyz" - local word = "" + local wordTable = {} for i = 1, length do local randomIndex = math.random(1, #alphabet) - word = word .. alphabet:sub(randomIndex, randomIndex) + table.insert(wordTable, alphabet:sub(randomIndex, randomIndex)) end - return word + return table.concat(wordTable) end -local msg = "" +local msg = "AI says:" math.randomseed(os.time()) for i = 1, math.random(1, 10) do msg = msg .. " ".. generateRandomWord(math.random(1, 8)) -- cgit v1.2.3 From b0ef843fe0702482e843379b4975b2dda4d58935 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 24 May 2024 09:22:40 -0400 Subject: Nat's ideas from PR #1547 --- indra/llcommon/llstring.h | 62 +++++++++++++++++++++++++ indra/llui/llchat.h | 13 ++++++ indra/newview/llchathistory.cpp | 22 ++++----- indra/newview/llfloaterimnearbychathandler.cpp | 5 +- indra/newview/llfloaterimnearbychatlistener.cpp | 24 ++++------ indra/newview/llfloaterimnearbychatlistener.h | 4 +- indra/newview/llviewerchat.cpp | 2 +- indra/newview/llviewermessage.cpp | 5 +- indra/newview/scripts/lua/test_LLChat.lua | 12 ++--- 9 files changed, 108 insertions(+), 41 deletions(-) diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 21b0da4822..cd8b2a2dcd 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -315,6 +315,14 @@ public: static void trim(string_type& string) { trimHead(string); trimTail(string); } static void truncate(string_type& string, size_type count); + // if string startsWith prefix, remove it and return true + static bool removePrefix(string_type& string, const string_type& prefix); + // if string startsWith prefix, return (string without prefix, true), else (string, false) + static std::pair withoutPrefix(const string_type& string, const string_type& prefix); + // like removePrefix() + static bool removeSuffix(string_type& string, const string_type& suffix); + static std::pair withoutSuffix(const string_type& string, const string_type& suffix); + static void toUpper(string_type& string); static void toLower(string_type& string); @@ -1479,6 +1487,60 @@ void LLStringUtilBase::trimTail(string_type& string) } } +// if string startsWith prefix, remove it and return true +template +bool LLStringUtilBase::removePrefix(string_type& string, const string_type& prefix) +{ + bool found{ startsWith(string, prefix) }; + if (found) + { + string.erase(0, prefix.length()); + } + return found; +} + +// if string startsWith prefix, return (string without prefix, true), else (string, false) +template +std::pair::string_type, bool> +LLStringUtilBase::withoutPrefix(const string_type& string, const string_type& prefix) +{ + bool found{ startsWith(string, prefix) }; + if (! found) + { + return { string, false }; + } + else + { + return { string.substr(prefix.length()), true }; + } +} + +// like removePrefix() +template +bool LLStringUtilBase::removeSuffix(string_type& string, const string_type& suffix) +{ + bool found{ endsWith(string, suffix) }; + if (found) + { + string.erase(string.length() - suffix.length()); + } + return found; +} + +template +std::pair::string_type, bool> +LLStringUtilBase::withoutSuffix(const string_type& string, const string_type& suffix) +{ + bool found{ endsWith(string, suffix) }; + if (! found) + { + return { string, false }; + } + else + { + return { string.substr(0, string.length() - suffix.length()), true }; + } +} // Replace line feeds with carriage return-line feed pairs. //static diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index 8fd92c2550..70d7e82970 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -113,4 +113,17 @@ public: }; static const std::string LUA_PREFIX("[LUA]"); +inline +std::string without_LUA_PREFIX(const std::string& string, bool is_lua) +{ + if (is_lua) + { + return string.substr(LUA_PREFIX.size()); + } + else + { + return string; + } +} + #endif diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 54b0c171f1..f16377d7e3 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -665,6 +665,7 @@ public: mSessionID = chat.mSessionID; mSourceType = chat.mSourceType; mIsFromScript = is_script; + mScriptPrefix = is_script? LLTrans::getString("ScriptBy") : ""; // To be able to report a message, we need a copy of it's text // and it's easier to store text directly than trying to get @@ -734,7 +735,7 @@ public: username_end == (chat.mFromName.length() - 1)) { mFrom = chat.mFromName.substr(0, username_start); - user_name->setValue(mIsFromScript ? LLTrans::getString("ScriptBy") + mFrom : mFrom); + user_name->setValue(mScriptPrefix + mFrom); if (gSavedSettings.getBOOL("NameTagShowUsernames")) { @@ -789,7 +790,7 @@ public: icon->setValue(LLSD("Command_Destinations_Icon")); break; case CHAT_SOURCE_UNKNOWN: - icon->setValue(mIsFromScript ? LLSD("Inv_Script") : LLSD(chat.mFromID)); + icon->setValue(mIsFromScript ? LLSD("Inv_Script") : LLSD("Unknown_Icon")); } // In case the message came from an object, save the object info @@ -1031,14 +1032,7 @@ private: mFrom = av_name.getDisplayName(); LLTextBox* user_name = getChild("user_name"); - if(mIsFromScript) - { - user_name->setValue(LLSD(LLTrans::getString("ScriptBy") + av_name.getDisplayName())); - } - else - { - user_name->setValue(LLSD(av_name.getDisplayName())); - } + user_name->setValue(LLSD(mScriptPrefix + av_name.getDisplayName())); user_name->setToolTip( av_name.getUserName() ); if (gSavedSettings.getBOOL("NameTagShowUsernames") && @@ -1070,6 +1064,7 @@ protected: std::string mFrom; LLUUID mSessionID; std::string mText; + std::string mScriptPrefix; F64 mTime; // IM's frame time time_t mCreationTime; // Views's time @@ -1080,7 +1075,7 @@ protected: bool mNeedsTimeBox; - bool mIsFromScript; + bool mIsFromScript; private: boost::signals2::connection mAvatarNameCacheConnection; @@ -1270,8 +1265,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL name_params.color(name_color); name_params.readonly_color(name_color); - bool is_lua = (chat.mText.substr(0, LUA_PREFIX.size()) == LUA_PREFIX); - std::string prefix = chat.mText.substr(is_lua ? LUA_PREFIX.size() : 0, 4); + auto [message, is_lua] = LLStringUtil::withoutPrefix(chat.mText, LUA_PREFIX); + std::string prefix = message.substr(0, 4); //IRC styled /me messages. bool irc_me = prefix == "/me " || prefix == "/me'"; @@ -1505,7 +1500,6 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL // usual messages showing else if (!teleport_separator) { - std::string message = is_lua ? chat.mText.substr(LUA_PREFIX.size()) : chat.mText; message = irc_me ? message.substr(3) : message; //MESSAGE TEXT PROCESSING diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 91d9cd56cf..cda71f97d4 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -599,6 +599,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, { // Handle IRC styled messages. std::string toast_msg; + std::string msg_text = without_LUA_PREFIX(chat_msg.mText, chat_msg.mIsScript); if (chat_msg.mChatStyle == CHAT_STYLE_IRC) { if (chat_msg.mIsScript) @@ -609,11 +610,11 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, { toast_msg += chat_msg.mFromName; } - toast_msg += chat_msg.mText.substr(chat_msg.mIsScript ? LUA_PREFIX.size() + 3 : 3); + toast_msg += msg_text.substr(3); } else { - toast_msg = chat_msg.mIsScript ? chat_msg.mText.substr(LUA_PREFIX.size()) : chat_msg.mText; + toast_msg = msg_text; } bool chat_overlaps = false; diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp index e8fb510111..9093db282a 100644 --- a/indra/newview/llfloaterimnearbychatlistener.cpp +++ b/indra/newview/llfloaterimnearbychatlistener.cpp @@ -34,6 +34,7 @@ #include "llagent.h" #include "llchat.h" #include "llviewercontrol.h" +#include "stringize.h" static const F32 CHAT_THROTTLE_PERIOD = 1.f; @@ -51,17 +52,16 @@ LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener() // "sendChat" command -void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const +void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) { - static F64 last_throttle_time = 0.0; F64 cur_time = LLTimer::getElapsedSeconds(); - if (cur_time < last_throttle_time + CHAT_THROTTLE_PERIOD) + if (cur_time < mLastThrottleTime + CHAT_THROTTLE_PERIOD) { LL_DEBUGS("LLFloaterIMNearbyChatListener") << "'sendChat' was throttled" << LL_ENDL; return; } - last_throttle_time = cur_time; + mLastThrottleTime = cur_time; // Extract the data std::string chat_text = LUA_PREFIX + chat_data["message"].asString(); @@ -91,20 +91,14 @@ void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const } // Have to prepend /42 style channel numbers - std::string chat_to_send; - if (channel == 0) + if (channel) { - chat_to_send = chat_text; - } - else - { - 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 - LLFloaterIMNearbyChat::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 0df0341d36..34d4effd48 100644 --- a/indra/newview/llfloaterimnearbychatlistener.h +++ b/indra/newview/llfloaterimnearbychatlistener.h @@ -41,7 +41,9 @@ public: LLFloaterIMNearbyChatListener(); private: - void sendChat(LLSD const & chat_data) const; + F64 mLastThrottleTime{ 0.0 }; + + void sendChat(LLSD const & chat_data); }; #endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 70c426740b..00520f100e 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -217,7 +217,7 @@ S32 LLViewerChat::getChatFontSize() //static void LLViewerChat::formatChatMsg(const LLChat& chat, std::string& formated_msg) { - std::string tmpmsg = chat.mIsScript ? chat.mText.substr(LUA_PREFIX.size()) : chat.mText; + std::string tmpmsg = without_LUA_PREFIX(chat.mText, chat.mIsScript); if(chat.mChatStyle == CHAT_STYLE_IRC) { formated_msg = chat.mFromName + tmpmsg.substr(3); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 4fe5beceae..d1c773171b 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2600,10 +2600,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) BOOL ircstyle = FALSE; - chat.mIsScript = (mesg.substr(0, LUA_PREFIX.size()) == LUA_PREFIX); + auto [message, is_script] = LLStringUtil::withoutPrefix(mesg, LUA_PREFIX); + chat.mIsScript = is_script; // Look for IRC-style emotes here so chatbubbles work - std::string prefix = mesg.substr(chat.mIsScript ? LUA_PREFIX.size() : 0, 4); + std::string prefix = message.substr(0, 4); if (prefix == "/me " || prefix == "/me'") { ircstyle = TRUE; diff --git a/indra/newview/scripts/lua/test_LLChat.lua b/indra/newview/scripts/lua/test_LLChat.lua index 95bd218baa..3c5cbeeeb2 100644 --- a/indra/newview/scripts/lua/test_LLChat.lua +++ b/indra/newview/scripts/lua/test_LLChat.lua @@ -2,17 +2,17 @@ LLChat = require 'LLChat' function generateRandomWord(length) local alphabet = "abcdefghijklmnopqrstuvwxyz" - local word = "" + local word = {} for i = 1, length do local randomIndex = math.random(1, #alphabet) - word = word .. alphabet:sub(randomIndex, randomIndex) + table.insert(word, alphabet:sub(randomIndex, randomIndex)) end - return word + return table.concat(word) end -local msg = "" +local msg = {'AI says:'} math.randomseed(os.time()) for i = 1, math.random(1, 10) do - msg = msg .. " ".. generateRandomWord(math.random(1, 8)) + table.insert(msg, generateRandomWord(math.random(1, 8))) end -LLChat.sendNearby(msg) +LLChat.sendNearby(table.concat(msg, ' ')) -- cgit v1.2.3 From 94cac4c443b5acc189b5223c78eb278648846338 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 24 May 2024 10:15:24 -0400 Subject: Fix merge glitches --- indra/newview/llchathistory.cpp | 11 ----------- indra/newview/llfloaterimnearbychathandler.cpp | 4 ---- 2 files changed, 15 deletions(-) diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index e5878a9a24..d549f372e3 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -1265,19 +1265,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL name_params.color(name_color); name_params.readonly_color(name_color); -<<<<<<< variant A auto [message, is_lua] = LLStringUtil::withoutPrefix(chat.mText, LUA_PREFIX); std::string prefix = message.substr(0, 4); ->>>>>>> variant B - bool is_lua = LLStringUtil::startsWith(chat.mText, LUA_PREFIX); - - std::string message = remove_LUA_PREFIX(chat.mText, is_lua); - std::string prefix = message.substr(0, 4); - -####### Ancestor - bool is_lua = (chat.mText.substr(0, LUA_PREFIX.size()) == LUA_PREFIX); - std::string prefix = chat.mText.substr(is_lua ? LUA_PREFIX.size() : 0, 4); -======= end //IRC styled /me messages. bool irc_me = prefix == "/me " || prefix == "/me'"; diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 6a9dccf2f4..cda71f97d4 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -614,11 +614,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, } else { -<<<<<<< HEAD toast_msg = msg_text; -======= - toast_msg = remove_LUA_PREFIX(chat_msg.mText, chat_msg.mIsScript); ->>>>>>> release/luau-scripting } bool chat_overlaps = false; -- cgit v1.2.3 From 316bc0bdf30514a0c6894ef7c2859e79bf02a546 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 29 May 2024 09:49:56 -0400 Subject: Make ~ThreadPool() join every thread before destroying its vector. Otherwise we fall into the trap of destroying a joinable std::thread, which calls std::terminate() and hence our crash-on-terminate() handler. The previous ~ThreadPool() logic only joined threads if the queue wasn't already closed, but evidently we can reach the destructor with the queue closed but the threads not yet joined. Fixes #1534. --- indra/llcommon/threadpool.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index edccdb097b..0f445b84fb 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -109,20 +109,19 @@ LL::ThreadPoolBase::~ThreadPoolBase() void LL::ThreadPoolBase::close() { - if (! mQueue->isClosed()) + // mQueue might have been closed already, but in any case we must join or + // detach each of our threads before destroying the mThreads vector. + LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL; + mQueue->close(); + for (auto& pair: mThreads) { - LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL; - mQueue->close(); - for (auto& pair: mThreads) + if (pair.second.joinable()) { - if (pair.second.joinable()) - { - LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; - pair.second.join(); - } + LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; + pair.second.join(); } - LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL; } + LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL; } void LL::ThreadPoolBase::run(const std::string& name) -- cgit v1.2.3