From c820bb2929a37fb222ce0d7368d699e81f5edc00 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 31 Aug 2024 01:33:27 +0200 Subject: Minimal code needed to add RLVa with an on/off toggle --- indra/newview/rlvhandler.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 indra/newview/rlvhandler.cpp (limited to 'indra/newview/rlvhandler.cpp') diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp new file mode 100644 index 0000000000..3315ed1999 --- /dev/null +++ b/indra/newview/rlvhandler.cpp @@ -0,0 +1,40 @@ +#include "llviewerprecompiledheaders.h" +#include "llappviewer.h" +#include "llstartup.h" + +#include "rlvdefines.h" +#include "rlvcommon.h" +#include "rlvhandler.h" + +using namespace Rlv; + +// ============================================================================ +// Static variable initialization +// + +bool RlvHandler::mIsEnabled = false; + +// ============================================================================ +// Initialization helper functions +// + +bool RlvHandler::canEnable() +{ + return LLStartUp::getStartupState() <= STATE_LOGIN_CLEANUP; +} + +bool RlvHandler::setEnabled(bool enable) +{ + if (mIsEnabled == enable) + return enable; + + if (enable && canEnable()) + { + RLV_INFOS << "Enabling Restrained Love API support - " << RlvStrings::getVersionAbout() << RLV_ENDL; + mIsEnabled = true; + } + + return mIsEnabled; +} + +// ============================================================================ -- cgit v1.2.3 From b82e9b73d35e41ed51063905dd31ccced9e97266 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 1 Sep 2024 01:21:00 +0200 Subject: Add owner say chat hook --- indra/newview/rlvhandler.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'indra/newview/rlvhandler.cpp') diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 3315ed1999..bf78a0a38a 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1,10 +1,12 @@ #include "llviewerprecompiledheaders.h" #include "llappviewer.h" #include "llstartup.h" +#include "llviewercontrol.h" +#include "llviewerobject.h" -#include "rlvdefines.h" #include "rlvcommon.h" #include "rlvhandler.h" +#include "rlvhelper.h" using namespace Rlv; @@ -14,6 +16,46 @@ using namespace Rlv; bool RlvHandler::mIsEnabled = false; +// ============================================================================ +// Command processing functions +// + +bool RlvHandler::handleSimulatorChat(std::string& message, const LLChat& chat, const LLViewerObject* chatObj) +{ + static LLCachedControl enable_temp_attach(gSavedSettings, Settings::EnableTempAttach); + static LLCachedControl show_debug_output(gSavedSettings, Settings::Debug); + static LLCachedControl hide_unset_dupes(gSavedSettings, Settings::DebugHideUnsetDup); + + if ( message.length() <= 3 || Rlv::Constants::CmdPrefix != message[0] || CHAT_TYPE_OWNER != chat.mChatType || + (chatObj && chatObj->isTempAttachment() && !enable_temp_attach()) ) + { + return false; + } + + message.erase(0, 1); + LLStringUtil::toLower(message); + CommandDbgOut cmdDbgOut(message); + + boost_tokenizer tokens(message, boost::char_separator(",", "", boost::drop_empty_tokens)); + for (const std::string& strCmd : tokens) + { + ECmdRet eRet = (ECmdRet)processCommand(chat.mFromID, strCmd, true); + if ( show_debug_output() && + (!hide_unset_dupes() || (ECmdRet::SuccessUnset != eRet && ECmdRet::SuccessDuplicate != eRet)) ) + { + cmdDbgOut.add(strCmd, eRet); + } + } + + message = cmdDbgOut.get(); + return true; +} + +ECmdRet RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCmd, bool fromObj) +{ + return ECmdRet::FailedNoProcessor; +} + // ============================================================================ // Initialization helper functions // -- cgit v1.2.3 From 7402fe6412e98e4b295ee3e04874f379c752f7a0 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Mon, 2 Sep 2024 01:39:17 +0200 Subject: Add basic scaffolding to support reply commands and handle @versionXXX as an illustration --- indra/newview/rlvhandler.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 4 deletions(-) (limited to 'indra/newview/rlvhandler.cpp') diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index bf78a0a38a..3d7f73937f 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1,4 +1,5 @@ #include "llviewerprecompiledheaders.h" +#include "llagent.h" #include "llappviewer.h" #include "llstartup.h" #include "llviewercontrol.h" @@ -22,11 +23,12 @@ bool RlvHandler::mIsEnabled = false; bool RlvHandler::handleSimulatorChat(std::string& message, const LLChat& chat, const LLViewerObject* chatObj) { + // *TODO: There's an edge case for temporary attachments when going from enabled -> disabled with restrictions already in place static LLCachedControl enable_temp_attach(gSavedSettings, Settings::EnableTempAttach); static LLCachedControl show_debug_output(gSavedSettings, Settings::Debug); static LLCachedControl hide_unset_dupes(gSavedSettings, Settings::DebugHideUnsetDup); - if ( message.length() <= 3 || Rlv::Constants::CmdPrefix != message[0] || CHAT_TYPE_OWNER != chat.mChatType || + if ( message.length() <= 3 || Constants::CmdPrefix != message[0] || CHAT_TYPE_OWNER != chat.mChatType || (chatObj && chatObj->isTempAttachment() && !enable_temp_attach()) ) { return false; @@ -39,7 +41,7 @@ bool RlvHandler::handleSimulatorChat(std::string& message, const LLChat& chat, c boost_tokenizer tokens(message, boost::char_separator(",", "", boost::drop_empty_tokens)); for (const std::string& strCmd : tokens) { - ECmdRet eRet = (ECmdRet)processCommand(chat.mFromID, strCmd, true); + ECmdRet eRet = processCommand(chat.mFromID, strCmd, true); if ( show_debug_output() && (!hide_unset_dupes() || (ECmdRet::SuccessUnset != eRet && ECmdRet::SuccessDuplicate != eRet)) ) { @@ -53,7 +55,44 @@ bool RlvHandler::handleSimulatorChat(std::string& message, const LLChat& chat, c ECmdRet RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCmd, bool fromObj) { - return ECmdRet::FailedNoProcessor; + const RlvCommand rlvCmd(idObj, strCmd); + return processCommand(std::ref(rlvCmd), fromObj); +} + +ECmdRet RlvHandler::processCommand(std::reference_wrapper rlvCmd, bool fromObj) +{ + { + const RlvCommand& rlvCmdTmp = rlvCmd; // Reference to the temporary with limited variable scope since we don't want it to leak below + + RLV_DEBUGS << "[" << rlvCmdTmp.getObjectID() << "]: " << rlvCmdTmp.asString() << RLV_ENDL; + if (!rlvCmdTmp.isValid()) + { + RLV_DEBUGS << "\t-> invalid syntax" << RLV_ENDL; + return ECmdRet::FailedSyntax; + } + if (rlvCmdTmp.isBlocked()) + { + RLV_DEBUGS << "\t-> blocked command" << RLV_ENDL; + return ECmdRet::FailedDisabled; + } + } + + ECmdRet eRet = ECmdRet::Unknown; + switch (rlvCmd.get().getParamType()) + { + case EParamType::Reply: + eRet = rlvCmd.get().processCommand(); + break; + case EParamType::Unknown: + default: + eRet = ECmdRet::FailedParam; + break; + } + RLV_ASSERT(ECmdRet::Unknown != eRet); + + RLV_DEBUGS << "\t--> command " << (isReturnCodeSuccess(eRet) ? "succeeded" : "failed") << RLV_ENDL; + + return eRet; } // ============================================================================ @@ -72,7 +111,7 @@ bool RlvHandler::setEnabled(bool enable) if (enable && canEnable()) { - RLV_INFOS << "Enabling Restrained Love API support - " << RlvStrings::getVersionAbout() << RLV_ENDL; + RLV_INFOS << "Enabling Restrained Love API support - " << Strings::getVersionAbout() << RLV_ENDL; mIsEnabled = true; } @@ -80,3 +119,49 @@ bool RlvHandler::setEnabled(bool enable) } // ============================================================================ +// Command handlers (RLV_TYPE_REPLY) +// + +ECmdRet CommandHandlerBaseImpl::processCommand(const RlvCommand& rlvCmd, ReplyHandlerFunc* pHandler) +{ + // Sanity check - should specify a - valid - reply channel + S32 nChannel; + if (!LLStringUtil::convertToS32(rlvCmd.getParam(), nChannel) || !Util::isValidReplyChannel(nChannel, rlvCmd.getObjectID() == gAgent.getID())) + return ECmdRet::FailedParam; + + std::string strReply; + ECmdRet eRet = (*pHandler)(rlvCmd, strReply); + + // If we made it this far then: + // - the command was handled successfully so we send off the response + // - the command failed but we still send off an - empty - response to keep the issuing script from blocking + if (nChannel != 0) + { + Util::sendChatReply(nChannel, strReply); + } + + return eRet; +} + +// Handles: @version= and @versionnew= +template<> template<> +ECmdRet VersionReplyHandler::onCommand(const RlvCommand& rlvCmd, std::string& strReply) +{ + strReply = Strings::getVersion(EBehaviour::Version == rlvCmd.getBehaviourType()); + return ECmdRet::Success; +} + +// Handles: @versionnum[:impl]= +template<> template<> +ECmdRet ReplyHandler::onCommand(const RlvCommand& rlvCmd, std::string& strReply) +{ + if (!rlvCmd.hasOption()) + strReply = Strings::getVersionNum(); + else if ("impl" == rlvCmd.getOption()) + strReply = Strings::getVersionImplNum(); + else + return ECmdRet::FailedOption; + return ECmdRet::Success; +} + +// ============================================================================ -- cgit v1.2.3 From 4f7eb9b12e9c7eeb9f3ee0980bd4616df7d678b6 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Mon, 2 Sep 2024 01:57:34 +0200 Subject: Add the @getcommand command query reply command --- indra/newview/rlvhandler.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'indra/newview/rlvhandler.cpp') diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 3d7f73937f..8b2620cf48 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -9,6 +9,8 @@ #include "rlvhandler.h" #include "rlvhelper.h" +#include + using namespace Rlv; // ============================================================================ @@ -143,6 +145,35 @@ ECmdRet CommandHandlerBaseImpl::processCommand(const RlvComma return eRet; } +// Handles: @getcommand[:[;[;]]]= +template<> template<> +ECmdRet ReplyHandler::onCommand(const RlvCommand& rlvCmd, std::string& strReply) +{ + std::vector optionList; + Util::parseStringList(rlvCmd.getOption(), optionList); + + // If a second parameter is present it'll specify the command type + EParamType eType = EParamType::Unknown; + if (optionList.size() >= 2) + { + if (optionList[1] == "any" || optionList[1].empty()) + eType = EParamType::Unknown; + else if (optionList[1] == "add") + eType = EParamType::AddRem; + else if (optionList[1] == "force") + eType = EParamType::Force; + else if (optionList[1] == "reply") + eType = EParamType::Reply; + else + return ECmdRet::FailedOption; + } + + std::list cmdList; + if (BehaviourDictionary::instance().getCommands(!optionList.empty() ? optionList[0] : LLStringUtil::null, eType, cmdList)) + strReply = boost::algorithm::join(cmdList, optionList.size() >= 3 ? optionList[2] : Constants::OptionSeparator); + return ECmdRet::Success; +} + // Handles: @version= and @versionnew= template<> template<> ECmdRet VersionReplyHandler::onCommand(const RlvCommand& rlvCmd, std::string& strReply) -- cgit v1.2.3 From db8916454457e3e4856fddcbbafe66b3766e4ffa Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Tue, 3 Sep 2024 18:14:06 +0200 Subject: Add the RLVa console --- indra/newview/rlvhandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/rlvhandler.cpp') diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 8b2620cf48..0a0da0e25d 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1,6 +1,5 @@ #include "llviewerprecompiledheaders.h" #include "llagent.h" -#include "llappviewer.h" #include "llstartup.h" #include "llviewercontrol.h" #include "llviewerobject.h" @@ -38,7 +37,7 @@ bool RlvHandler::handleSimulatorChat(std::string& message, const LLChat& chat, c message.erase(0, 1); LLStringUtil::toLower(message); - CommandDbgOut cmdDbgOut(message); + CommandDbgOut cmdDbgOut(message, chatObj->getID() == gAgentID); boost_tokenizer tokens(message, boost::char_separator(",", "", boost::drop_empty_tokens)); for (const std::string& strCmd : tokens) @@ -128,7 +127,7 @@ ECmdRet CommandHandlerBaseImpl::processCommand(const RlvComma { // Sanity check - should specify a - valid - reply channel S32 nChannel; - if (!LLStringUtil::convertToS32(rlvCmd.getParam(), nChannel) || !Util::isValidReplyChannel(nChannel, rlvCmd.getObjectID() == gAgent.getID())) + if (!LLStringUtil::convertToS32(rlvCmd.getParam(), nChannel) || !Util::isValidReplyChannel(nChannel, rlvCmd.getObjectID() == gAgentID)) return ECmdRet::FailedParam; std::string strReply; @@ -141,6 +140,7 @@ ECmdRet CommandHandlerBaseImpl::processCommand(const RlvComma { Util::sendChatReply(nChannel, strReply); } + RlvHandler::instance().mOnCommandOutput(rlvCmd, nChannel, strReply); return eRet; } -- cgit v1.2.3 From 6f4d7c2d6d363aee60d2f3d1fe4ed4a251aaa11b Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Tue, 17 Sep 2024 19:12:55 +0200 Subject: Add proper file headers --- indra/newview/rlvhandler.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'indra/newview/rlvhandler.cpp') diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 0a0da0e25d..bf086c1b4b 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1,3 +1,30 @@ +/** + * @file rlvhandler.cpp + * @author Kitty Barnett + * @brief RLVa helper classes for internal use only + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + #include "llviewerprecompiledheaders.h" #include "llagent.h" #include "llstartup.h" -- cgit v1.2.3 From dc64ac19fd74694a6e9ecf0cb68e3f83257c93b9 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sat, 28 Sep 2024 00:36:12 +0200 Subject: Replace None and Success. Those are X11 defines and thus lead to compile errors when compiling a Linux viewer. --- indra/newview/rlvhandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/rlvhandler.cpp') diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index bf086c1b4b..6c4b439105 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -198,7 +198,7 @@ ECmdRet ReplyHandler::onCommand(const RlvCommand& rlvCmd std::list cmdList; if (BehaviourDictionary::instance().getCommands(!optionList.empty() ? optionList[0] : LLStringUtil::null, eType, cmdList)) strReply = boost::algorithm::join(cmdList, optionList.size() >= 3 ? optionList[2] : Constants::OptionSeparator); - return ECmdRet::Success; + return ECmdRet::Succeeded; } // Handles: @version= and @versionnew= @@ -206,7 +206,7 @@ template<> template<> ECmdRet VersionReplyHandler::onCommand(const RlvCommand& rlvCmd, std::string& strReply) { strReply = Strings::getVersion(EBehaviour::Version == rlvCmd.getBehaviourType()); - return ECmdRet::Success; + return ECmdRet::Succeeded; } // Handles: @versionnum[:impl]= @@ -219,7 +219,7 @@ ECmdRet ReplyHandler::onCommand(const RlvCommand& rlvCmd strReply = Strings::getVersionImplNum(); else return ECmdRet::FailedOption; - return ECmdRet::Success; + return ECmdRet::Succeeded; } // ============================================================================ -- cgit v1.2.3