summaryrefslogtreecommitdiff
path: root/indra/newview/rlvhandler.cpp
diff options
context:
space:
mode:
authorKitty Barnett <develop@catznip.com>2024-09-02 01:39:17 +0200
committerKitty Barnett <develop@catznip.com>2024-09-02 01:39:17 +0200
commit7402fe6412e98e4b295ee3e04874f379c752f7a0 (patch)
tree65b3bfb411094953f7e2cac6df9d0c73462cb49e /indra/newview/rlvhandler.cpp
parentb82e9b73d35e41ed51063905dd31ccced9e97266 (diff)
Add basic scaffolding to support reply commands and handle @versionXXX as an illustration
Diffstat (limited to 'indra/newview/rlvhandler.cpp')
-rw-r--r--indra/newview/rlvhandler.cpp93
1 files changed, 89 insertions, 4 deletions
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<bool> enable_temp_attach(gSavedSettings, Settings::EnableTempAttach);
static LLCachedControl<bool> show_debug_output(gSavedSettings, Settings::Debug);
static LLCachedControl<bool> 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<char>(",", "", 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<const RlvCommand> 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<EParamType::Reply>::processCommand(const RlvCommand& rlvCmd, ReplyHandlerFunc* pHandler)
+{
+ // Sanity check - <param> 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=<chnannel> and @versionnew=<channel>
+template<> template<>
+ECmdRet VersionReplyHandler::onCommand(const RlvCommand& rlvCmd, std::string& strReply)
+{
+ strReply = Strings::getVersion(EBehaviour::Version == rlvCmd.getBehaviourType());
+ return ECmdRet::Success;
+}
+
+// Handles: @versionnum[:impl]=<channel>
+template<> template<>
+ECmdRet ReplyHandler<EBehaviour::VersionNum>::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;
+}
+
+// ============================================================================