diff options
Diffstat (limited to 'linden/indra/newview/rlvhelper.h')
-rw-r--r-- | linden/indra/newview/rlvhelper.h | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/linden/indra/newview/rlvhelper.h b/linden/indra/newview/rlvhelper.h new file mode 100644 index 0000000..a0e040e --- /dev/null +++ b/linden/indra/newview/rlvhelper.h | |||
@@ -0,0 +1,579 @@ | |||
1 | #ifndef RLV_HELPER_H | ||
2 | #define RLV_HELPER_H | ||
3 | |||
4 | #include "llboost.h" | ||
5 | #include "llinventorymodel.h" | ||
6 | #include "llselectmgr.h" | ||
7 | #include "llviewercontrol.h" | ||
8 | #include "llviewerobjectlist.h" | ||
9 | #include "llwlparamset.h" | ||
10 | |||
11 | #include "rlvmultistringsearch.h" | ||
12 | |||
13 | // ============================================================================ | ||
14 | // Extensions | ||
15 | // | ||
16 | |||
17 | // Comment out if you don't want the Advanced / RLVa menu (may prevent enabling some extensions or experimental features - see below) | ||
18 | #define RLV_ADVANCED_MENU | ||
19 | // Comment out if you provide your own way to enable/disable RLVa | ||
20 | #define RLV_ADVANCED_TOGGLE_RLVA | ||
21 | |||
22 | // Provides access to "advanced" feature through the RLVa debug menu | ||
23 | #define RLV_EXTENSION_ENABLE_WEAR // "Enable Wear" | ||
24 | #define RLV_EXTENSION_HIDELOCKED // "Hide locked layers", "Hide locked attachments" and "Hide locked inventory" | ||
25 | #define RLV_EXTENSION_FLOATER_RESTRICTIONS // Enables the Advanced / RLVa / Restrictions... floater | ||
26 | |||
27 | // Extensions | ||
28 | #define RLV_EXTENSION_CMD_GETSETDEBUG_EX // Extends the debug variables accessible through @getdebug_xxx/@setdebug_xxx | ||
29 | #define RLV_EXTENSION_CMD_FINDFOLDERS // @findfolders:<option>=<channel> - @findfolder with multiple results | ||
30 | #define RLV_EXTENSION_FLAG_NOSTRIP // Layers and attachments marked as "nostrip" are exempt from @detach/@remoutfit | ||
31 | #define RLV_EXTENSION_STARTLOCATION // Reenables "Start Location" at login if not @tploc=n or @unsit=n restricted at last logoff | ||
32 | #define RLV_EXPERIMENTAL // Enables/disables experimental features en masse | ||
33 | |||
34 | // Experimental features | ||
35 | #ifdef RLV_EXPERIMENTAL | ||
36 | // Stable (will mature to RLV_EXTENSION_XXX in next release if no bugs are found) | ||
37 | #define RLV_EXPERIMENTAL_FARTOUCH_FEEDBACK // Enables "cleaner" UI responses when fartouch blocks something | ||
38 | |||
39 | // Under testing (stable, but requires further testing - safe for public release but may be quirky) | ||
40 | |||
41 | // Under development (don't include in public release) | ||
42 | #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
43 | #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
44 | #endif // RLV_EXPERIMENTAL | ||
45 | |||
46 | // ============================================================================ | ||
47 | // Defines | ||
48 | // | ||
49 | |||
50 | // Version of the specifcation we support | ||
51 | const S32 RLV_VERSION_MAJOR = 1; | ||
52 | const S32 RLV_VERSION_MINOR = 20; | ||
53 | const S32 RLV_VERSION_PATCH = 0; | ||
54 | |||
55 | // Implementation version | ||
56 | const S32 RLVa_VERSION_MAJOR = 1; | ||
57 | const S32 RLVa_VERSION_MINOR = 0; | ||
58 | const S32 RLVa_VERSION_PATCH = 1; | ||
59 | const S32 RLVa_VERSION_BUILD = 7; | ||
60 | |||
61 | // The official viewer version we're patching against | ||
62 | #define RLV_MAKE_TARGET(x, y, z) ((x << 16) | (y << 8) | z) | ||
63 | #define RLV_TARGET RLV_MAKE_TARGET(1, 22, 11) | ||
64 | |||
65 | // Defining these makes it easier if we ever need to change our tag | ||
66 | #define RLV_WARNS LL_WARNS("RLV") | ||
67 | #define RLV_INFOS LL_INFOS("RLV") | ||
68 | #define RLV_DEBUGS LL_DEBUGS("RLV") | ||
69 | |||
70 | #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
71 | // Turn on extended debugging information | ||
72 | #define RLV_DEBUG | ||
73 | // Make sure we halt execution on errors | ||
74 | #define RLV_ERRS LL_ERRS("RLV") | ||
75 | // Uncomment to enable the Advanced / RLVa / Unit Tests menu (non-public) | ||
76 | //#define RLV_DEBUG_TESTS | ||
77 | #else | ||
78 | // Uncomment if you want extended debugging information on release builds | ||
79 | //#define RLV_DEBUG | ||
80 | // Don't halt execution on errors in release | ||
81 | #define RLV_ERRS LL_WARNS("RLV") | ||
82 | #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | ||
83 | |||
84 | #define RLV_ROOT_FOLDER "#RLV" | ||
85 | #define RLV_CMD_PREFIX '@' | ||
86 | #define RLV_PUTINV_PREFIX "#RLV/~" | ||
87 | #define RLV_SETROT_OFFSET F_PI_BY_TWO // @setrot is off by 90° with the rest of SL | ||
88 | |||
89 | #define RLV_FOLDER_FLAG_NOSTRIP "nostrip" | ||
90 | #define RLV_FOLDER_PREFIX_HIDDEN '.' | ||
91 | #define RLV_FOLDER_PREFIX_PUTINV '~' | ||
92 | |||
93 | // ============================================================================ | ||
94 | // Enumeration declarations | ||
95 | // | ||
96 | |||
97 | // NOTE: * any changes to this enumeration should be reflected in initLookupTable() | ||
98 | // * only uncomment the ones we actually use in a switch() to keep the size of the lookup table down | ||
99 | enum ERlvBehaviour { | ||
100 | RLV_BHVR_VERSION = 0, // "version" | ||
101 | RLV_BHVR_DETACH, // "detach" | ||
102 | // RLV_BHVR_SENDCHAT, // "sendchat" | ||
103 | // RLV_BHVR_EMOTE, // "emote" | ||
104 | // RLV_BHVR_CHATSHOUT, // "chatshout" | ||
105 | // RLV_BHVR_CHATNORMAL, // "chatnormal" | ||
106 | // RLV_BHVR_CHATWHISPER, // "chatwhisper" | ||
107 | RLV_BHVR_REDIRCHAT, // "redirchat" | ||
108 | RLV_BHVR_REDIREMOTE, // "rediremote" | ||
109 | RLV_BHVR_SENDIM, // "sendim" | ||
110 | RLV_BHVR_RECVCHAT, // "recvchat" | ||
111 | RLV_BHVR_RECVEMOTE, // "recvemote" | ||
112 | RLV_BHVR_RECVIM, // "recvim" | ||
113 | // RLV_BHVR_TPLM, // "tplm" | ||
114 | RLV_BHVR_TPLOC, // "tploc" | ||
115 | RLV_BHVR_TPLURE, // "tplure" | ||
116 | RLV_BHVR_SITTP, // "sittp" | ||
117 | // RLV_BHVR_CLEAR, // "clear" | ||
118 | RLV_BHVR_EDIT, // "edit" | ||
119 | RLV_BHVR_REZ, // "rez" | ||
120 | RLV_BHVR_ADDOUTFIT, // "addoutfit" | ||
121 | RLV_BHVR_REMOUTFIT, // "remoutfit" | ||
122 | RLV_BHVR_GETOUTFIT, // "getoutfit" | ||
123 | RLV_BHVR_GETATTACH, // "getattach" | ||
124 | RLV_BHVR_SHOWINV, // "showinv" | ||
125 | // RLV_BHVR_VIEWNOTE, // "viewnote" | ||
126 | RLV_BHVR_UNSIT, // "unsit" | ||
127 | RLV_BHVR_SIT, // "sit" | ||
128 | // RLV_BHVR_SENDCHANNEL, // "sendchannel" | ||
129 | RLV_BHVR_GETSTATUS, // "getstatus" | ||
130 | RLV_BHVR_GETSTATUSALL, // "getstatusall" | ||
131 | RLV_BHVR_GETINV, // "getinv" | ||
132 | RLV_BHVR_GETINVWORN, // "getinvworn" | ||
133 | RLV_BHVR_FINDFOLDER, // "findfolder" | ||
134 | RLV_BHVR_FINDFOLDERS, // "findfolders" | ||
135 | RLV_BHVR_ATTACH, // "attach" | ||
136 | RLV_BHVR_ATTACHALL, // "attachall" | ||
137 | RLV_BHVR_DETACHALL, // "detachall" | ||
138 | RLV_BHVR_GETPATH, // "getpath" | ||
139 | RLV_BHVR_ATTACHTHIS, // "attachthis" | ||
140 | RLV_BHVR_ATTACHALLTHIS, // "attachallthis" | ||
141 | RLV_BHVR_DETACHTHIS, // "detachthis" | ||
142 | RLV_BHVR_DETACHALLTHIS, // "detachallthis" | ||
143 | RLV_BHVR_FARTOUCH, // "fartouch" | ||
144 | RLV_BHVR_SHOWWORLDMAP, // "showworldmap" | ||
145 | RLV_BHVR_SHOWMINIMAP, // "showminimap" | ||
146 | RLV_BHVR_SHOWLOC, // "showloc" | ||
147 | RLV_BHVR_TPTO, // "tpto" | ||
148 | RLV_BHVR_ACCEPTTP, // "accepttp" | ||
149 | RLV_BHVR_SHOWNAMES, // "shownames" | ||
150 | RLV_BHVR_FLY, // "fly" | ||
151 | RLV_BHVR_GETSITID, // "getsitid" | ||
152 | RLV_BHVR_SETDEBUG, // "setdebug" | ||
153 | RLV_BHVR_SETENV, // "setenv" | ||
154 | RLV_BHVR_DETACHME, // "detachme" | ||
155 | RLV_BHVR_SHOWHOVERTEXTALL, // "showhovertextall" | ||
156 | RLV_BHVR_SHOWHOVERTEXTWORLD, // "showhovertextworld" | ||
157 | RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud" | ||
158 | RLV_BHVR_SHOWHOVERTEXT, // "showhovertext" | ||
159 | RLV_BHVR_NOTIFY, // "notify" | ||
160 | |||
161 | RLV_BHVR_COUNT, | ||
162 | RLV_BHVR_UNKNOWN | ||
163 | }; | ||
164 | |||
165 | enum ERlvParamType { | ||
166 | RLV_TYPE_UNKNOWN, | ||
167 | RLV_TYPE_ADD, // <param> == "n"|"add" | ||
168 | RLV_TYPE_REMOVE, // <param> == "y"|"rem" | ||
169 | RLV_TYPE_FORCE, // <param> == "force" | ||
170 | RLV_TYPE_REPLY // <param> == <number> | ||
171 | }; | ||
172 | |||
173 | enum ERlvCmdRet { | ||
174 | RLV_RET_NOERROR, // Command executed succesfully | ||
175 | RLV_RET_RETAINED, // Command was retained | ||
176 | RLV_RET_FAILED, // Command failed (general failure) | ||
177 | RLV_RET_FAILED_SYNTAX, // Command failed (syntax error) | ||
178 | RLV_RET_FAILED_UNSET, // Command failed (unset restriction) | ||
179 | RLV_RET_FAILED_DUPLICATE, // Command failed (duplicate) | ||
180 | RLV_RET_FAILED_OPTION, // Command failed (invalid option) | ||
181 | RLV_RET_UNKNOWN // Command unkown | ||
182 | }; | ||
183 | |||
184 | // ============================================================================ | ||
185 | /* | ||
186 | * RlvCommand | ||
187 | * ========== | ||
188 | * Encapsulates an "RLV command" (duh :p) | ||
189 | * | ||
190 | */ | ||
191 | |||
192 | class RlvCommand | ||
193 | { | ||
194 | public: | ||
195 | /* | ||
196 | * Constructors | ||
197 | */ | ||
198 | explicit RlvCommand(const std::string& strCommand); | ||
199 | RlvCommand(const RlvCommand& rlvCmd); | ||
200 | |||
201 | /* | ||
202 | * Accessors | ||
203 | */ | ||
204 | BOOL isValid() const { return m_fValid; } | ||
205 | |||
206 | const std::string& getBehaviour() const { return m_strBehaviour; } | ||
207 | ERlvBehaviour getBehaviourType() const { return m_eBehaviour; } | ||
208 | const std::string& getOption() const { return m_strOption; } | ||
209 | const std::string& getParam() const { return m_strParam; } | ||
210 | ERlvParamType getParamType() const { return m_eParamType; } | ||
211 | |||
212 | std::string asString() const; | ||
213 | |||
214 | /* | ||
215 | * Operators | ||
216 | */ | ||
217 | bool operator ==(const RlvCommand&) const; | ||
218 | |||
219 | // Parses an RLV command into its "tokens" | ||
220 | static BOOL parseCommand(/*[in]*/ const std::string& strCommand, | ||
221 | /*[out]*/ std::string& strBehaviour, /*[out]*/ std::string& strOption, /*[out]*/ std::string& strParam); | ||
222 | static void initLookupTable(); | ||
223 | |||
224 | /* | ||
225 | * Member variables | ||
226 | */ | ||
227 | protected: | ||
228 | BOOL m_fValid; | ||
229 | std::string m_strBehaviour; | ||
230 | ERlvBehaviour m_eBehaviour; | ||
231 | std::string m_strOption; | ||
232 | std::string m_strParam; | ||
233 | ERlvParamType m_eParamType; | ||
234 | |||
235 | static RlvMultiStringSearch m_BhvrLookup; | ||
236 | friend class RlvHandler; | ||
237 | }; | ||
238 | |||
239 | // ============================================================================ | ||
240 | /* | ||
241 | * RlvObject | ||
242 | * ========= | ||
243 | * Encapsulates an "RLV Object" (= an object that has issued an RLV command) | ||
244 | * | ||
245 | */ | ||
246 | |||
247 | typedef std::list<RlvCommand> rlv_command_list_t; | ||
248 | |||
249 | class RlvObject | ||
250 | { | ||
251 | public: | ||
252 | RlvObject(const LLUUID& uuid) : m_UUID(uuid), m_nLookupMisses(0) { m_fLookup = (NULL != gObjectList.findObject(uuid)); } | ||
253 | |||
254 | BOOL addCommand(const RlvCommand& rlvCmd); | ||
255 | BOOL removeCommand(const RlvCommand& rlvCmd); | ||
256 | |||
257 | BOOL hasBehaviour(ERlvBehaviour eBehaviour) const; | ||
258 | BOOL hasBehaviour(const std::string& strBehaviour) const; | ||
259 | BOOL hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const; | ||
260 | BOOL hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const; | ||
261 | |||
262 | std::string getStatusString(const std::string& strMatch) const; | ||
263 | |||
264 | const rlv_command_list_t* getCommandList() const { return &m_Commands; } | ||
265 | protected: | ||
266 | LLUUID m_UUID; // The object's UUID | ||
267 | bool m_fLookup; // TRUE if the object existed in gObjectList at one point in time | ||
268 | S16 m_nLookupMisses; // Count of unsuccessful lookups in gObjectList by the GC | ||
269 | rlv_command_list_t m_Commands; // List of behaviours held by this object (in the order they were received) | ||
270 | |||
271 | friend class RlvHandler; | ||
272 | }; | ||
273 | |||
274 | // ============================================================================ | ||
275 | /* | ||
276 | * RlvCriteriaCategoryCollector | ||
277 | * ============================ | ||
278 | * Criteria based folder matching filter used by @findfolder and @findfolders | ||
279 | * | ||
280 | */ | ||
281 | |||
282 | class RlvCriteriaCategoryCollector : public LLInventoryCollectFunctor | ||
283 | { | ||
284 | public: | ||
285 | RlvCriteriaCategoryCollector(const std::string& strCriteria) | ||
286 | { | ||
287 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
288 | boost::char_separator<char> sep("&&", "", boost::drop_empty_tokens); | ||
289 | tokenizer tokens(strCriteria, sep); | ||
290 | for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) | ||
291 | m_Criteria.push_back(*itToken); | ||
292 | } | ||
293 | virtual ~RlvCriteriaCategoryCollector() {} | ||
294 | |||
295 | virtual bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem) | ||
296 | { | ||
297 | if ( (!pFolder) || (m_Criteria.empty()) ) // We're only interested in matching folders, we don't care about items | ||
298 | return false; // (if there are no criteria then we don't want to return a match) | ||
299 | |||
300 | std::string strFolderName = pFolder->getName(); | ||
301 | LLStringUtil::toLower(strFolderName); | ||
302 | |||
303 | if ( (strFolderName.empty()) || (RLV_FOLDER_PREFIX_HIDDEN == strFolderName[0]) ) | ||
304 | return false; | ||
305 | |||
306 | for (std::list<std::string>::const_iterator itCrit = m_Criteria.begin(); itCrit != m_Criteria.end(); ++itCrit) | ||
307 | if (-1 == strFolderName.find(*itCrit)) // Return false on the first mismatch | ||
308 | return false; | ||
309 | return true; | ||
310 | } | ||
311 | |||
312 | protected: | ||
313 | std::list<std::string> m_Criteria; | ||
314 | }; | ||
315 | |||
316 | // ============================================================================ | ||
317 | /* | ||
318 | * RlvWearableItemCollector | ||
319 | * ======================== | ||
320 | * Inventory item filter used by attach/detach/attachall/detachall/getinvworn (also used by "Add/Replace Outfit" and "Take Off Items") | ||
321 | * | ||
322 | */ | ||
323 | |||
324 | class RlvWearableItemCollector : public LLInventoryCollectFunctor | ||
325 | { | ||
326 | public: | ||
327 | RlvWearableItemCollector(const LLUUID& idFolder, bool fAttach, bool fMatchAll) | ||
328 | : m_idFolder(idFolder), m_fAttach(fAttach), m_fMatchAll(fMatchAll) | ||
329 | { | ||
330 | m_Wearable.push_back(idFolder); | ||
331 | } | ||
332 | virtual ~RlvWearableItemCollector() {} | ||
333 | |||
334 | virtual bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem); | ||
335 | |||
336 | const LLUUID& getFoldedParent(const LLUUID& idFolder) const; | ||
337 | protected: | ||
338 | bool m_fAttach; | ||
339 | bool m_fMatchAll; | ||
340 | const LLUUID m_idFolder; | ||
341 | |||
342 | bool onCollectFolder(const LLInventoryCategory* pFolder); | ||
343 | bool onCollectItem(const LLInventoryItem* pItem); | ||
344 | |||
345 | std::list<LLUUID> m_Tentative; | ||
346 | std::list<LLUUID> m_Wearable; | ||
347 | |||
348 | std::map<LLUUID, LLUUID> m_Folding; | ||
349 | }; | ||
350 | |||
351 | // ============================================================================ | ||
352 | /* | ||
353 | * RlvRetainedCommand | ||
354 | * ================== | ||
355 | * | ||
356 | */ | ||
357 | |||
358 | struct RlvRetainedCommand | ||
359 | { | ||
360 | public: | ||
361 | std::string strObject; | ||
362 | LLUUID idObject; | ||
363 | std::string strCmd; | ||
364 | |||
365 | RlvRetainedCommand(const std::string obj, const LLUUID& uuid, const std::string& cmd) : strObject(obj), idObject(uuid), strCmd(cmd) {} | ||
366 | private: | ||
367 | RlvRetainedCommand(); | ||
368 | }; | ||
369 | typedef std::list<RlvRetainedCommand> rlv_retained_list_t; | ||
370 | |||
371 | // ============================================================================ | ||
372 | /* | ||
373 | * RlvWLSnapshot | ||
374 | * ============= | ||
375 | * | ||
376 | */ | ||
377 | |||
378 | struct RlvWLSnapshot | ||
379 | { | ||
380 | public: | ||
381 | static void restoreSnapshot(const RlvWLSnapshot* pWLSnapshot); | ||
382 | static RlvWLSnapshot* takeSnapshot(); | ||
383 | private: | ||
384 | RlvWLSnapshot() {} | ||
385 | |||
386 | bool fIsRunning; | ||
387 | bool fUseLindenTime; | ||
388 | LLWLParamSet WLParams; | ||
389 | }; | ||
390 | |||
391 | // ============================================================================ | ||
392 | /* | ||
393 | * RlvSettings | ||
394 | * =========== | ||
395 | * | ||
396 | */ | ||
397 | |||
398 | #define RLV_SETTING_MAIN "RestrainedLife" | ||
399 | #define RLV_SETTING_DEBUG "RestrainedLifeDebug" | ||
400 | #define RLV_SETTING_NOSETENV "RestrainedLifeNoSetEnv" | ||
401 | #define RLV_SETTING_FORBIDGIVETORLV "RestrainedLifeForbidGiveToRLV" | ||
402 | |||
403 | #define RLV_SETTING_ENABLEWEAR "RLVaEnableWear" | ||
404 | #define RLV_SETTING_ENABLELEGACYNAMING "RLVaEnableLegacyNaming" | ||
405 | #define RLV_SETTING_HIDELOCKEDLAYER "RLVaHideLockedLayers" | ||
406 | #define RLV_SETTING_HIDELOCKEDATTACH "RLVaHideLockedAttachments" | ||
407 | #define RLV_SETTING_HIDELOCKEDINVENTORY "RLVaHideLockedInventory" | ||
408 | #define RLV_SETTING_LOGINLASTLOCATION "RLVaLoginLastLocation" | ||
409 | #define RLV_SETTING_SHOWNAMETAGS "RLVaShowNameTags" | ||
410 | |||
411 | inline BOOL rlvGetSettingBOOL(const std::string& strSetting, BOOL fDefault) | ||
412 | { | ||
413 | return (gSavedSettings.controlExists(strSetting)) ? gSavedSettings.getBOOL(strSetting) : fDefault; | ||
414 | } | ||
415 | inline BOOL rlvGetPerUserSettingsBOOL(const std::string& strSetting, BOOL fDefault) | ||
416 | { | ||
417 | return (gSavedPerAccountSettings.controlExists(strSetting)) ? gSavedPerAccountSettings.getBOOL(strSetting) : fDefault; | ||
418 | } | ||
419 | |||
420 | class RlvSettings | ||
421 | { | ||
422 | public: | ||
423 | static BOOL getDebug() { return rlvGetSettingBOOL(RLV_SETTING_DEBUG, FALSE); } | ||
424 | static BOOL getForbidGiveToRLV() { return rlvGetSettingBOOL(RLV_SETTING_FORBIDGIVETORLV, TRUE); } | ||
425 | |||
426 | static BOOL getEnableWear() { return rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, FALSE); } | ||
427 | static BOOL getHideLockedLayers() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDLAYER, FALSE); } | ||
428 | static BOOL getHideLockedAttach() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDATTACH, FALSE); } | ||
429 | static BOOL getHideLockedInventory() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDINVENTORY, FALSE); } | ||
430 | |||
431 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
432 | static BOOL getLoginLastLocation() { return rlvGetPerUserSettingsBOOL(RLV_SETTING_LOGINLASTLOCATION, TRUE); } | ||
433 | static void updateLoginLastLocation(); | ||
434 | #endif // RLV_EXTENSION_STARTLOCATION | ||
435 | |||
436 | static BOOL fShowNameTags; | ||
437 | }; | ||
438 | |||
439 | // ============================================================================ | ||
440 | /* | ||
441 | * State keeping classes/structure | ||
442 | * | ||
443 | */ | ||
444 | |||
445 | struct RlvRedirInfo | ||
446 | { | ||
447 | S16 nRedirChat; | ||
448 | S16 nRedirEmote; | ||
449 | |||
450 | RlvRedirInfo() : nRedirChat(0), nRedirEmote(0) {} | ||
451 | bool isActive() { return (nRedirChat + nRedirEmote) != 0; } | ||
452 | }; | ||
453 | |||
454 | struct RlvReattachInfo | ||
455 | { | ||
456 | LLUUID idItem; | ||
457 | bool fInInventory; | ||
458 | bool fAssetSaved; | ||
459 | |||
460 | RlvReattachInfo() : idItem(), fInInventory(false), fAssetSaved(false) {} | ||
461 | }; | ||
462 | |||
463 | // ============================================================================ | ||
464 | /* | ||
465 | * Various helper classes/timers/functors | ||
466 | * | ||
467 | */ | ||
468 | |||
469 | class RlvGCTimer : public LLEventTimer | ||
470 | { | ||
471 | public: | ||
472 | RlvGCTimer() : LLEventTimer(30.0) {} | ||
473 | virtual BOOL tick(); | ||
474 | }; | ||
475 | |||
476 | class RlvCurrentlyWorn : public LLInventoryFetchObserver | ||
477 | { | ||
478 | public: | ||
479 | RlvCurrentlyWorn() {} | ||
480 | ~RlvCurrentlyWorn() {} | ||
481 | virtual void done() {} | ||
482 | |||
483 | static void fetchWorn(); | ||
484 | void fetchItem(const LLUUID& idItem); | ||
485 | }; | ||
486 | |||
487 | struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor | ||
488 | { | ||
489 | virtual bool apply(LLSelectNode* pNode); | ||
490 | }; | ||
491 | |||
492 | struct RlvSelectIsOwnedByOrGroupOwned : public LLSelectedNodeFunctor | ||
493 | { | ||
494 | RlvSelectIsOwnedByOrGroupOwned(const LLUUID& uuid) : m_idAgent(uuid) {} | ||
495 | virtual bool apply(LLSelectNode* pNode); | ||
496 | LLUUID m_idAgent; | ||
497 | }; | ||
498 | |||
499 | struct RlvSelectIsSittingOn : public LLSelectedNodeFunctor | ||
500 | { | ||
501 | RlvSelectIsSittingOn(LLXform* pObject) : m_pObject(pObject) {} | ||
502 | virtual bool apply(LLSelectNode* pNode); | ||
503 | LLXform* m_pObject; | ||
504 | }; | ||
505 | |||
506 | // ============================================================================ | ||
507 | /* | ||
508 | * Various helper functions | ||
509 | * | ||
510 | */ | ||
511 | |||
512 | BOOL rlvAttachToEnabler(void* pParam); | ||
513 | bool rlvCanDeleteOrReturn(); | ||
514 | S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type); | ||
515 | bool rlvIsEmote(const std::string& strUTF8Text); | ||
516 | bool rlvIsValidChannel(S32 nChannel); | ||
517 | bool rlvIsWearingItem(const LLInventoryItem* pItem); | ||
518 | |||
519 | void rlvForceDetach(LLViewerJointAttachment* pAttachPt); | ||
520 | void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null); | ||
521 | bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply); | ||
522 | bool rlvSendChatReply(S32 nChannel, const std::string& strReply); | ||
523 | |||
524 | void rlvStringReplace(std::string& strText, std::string strFrom, const std::string& strTo); | ||
525 | std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch = NULL); | ||
526 | std::string rlvGetLastParenthesisedText(const std::string& strText, std::string::size_type* pidxStart = NULL); | ||
527 | |||
528 | #ifdef RLV_ADVANCED_TOGGLE_RLVA | ||
529 | // "Advanced / RLVa / Enable RLV" menu option | ||
530 | void rlvDbgToggleEnabled(void*); | ||
531 | BOOL rlvDbgGetEnabled(void*); | ||
532 | #endif // RLV_ADVANCED_TOGGLE_RLVA | ||
533 | |||
534 | // ============================================================================ | ||
535 | // Inlined class member functions | ||
536 | // | ||
537 | |||
538 | inline bool RlvCommand::operator ==(const RlvCommand& rhs) const | ||
539 | { | ||
540 | // The specification notes that "@detach=n" is semantically identical to "@detach=add" (same for "y" and "rem" | ||
541 | return (m_strBehaviour == rhs.m_strBehaviour) && (m_strOption == rhs.m_strOption) && | ||
542 | ( (RLV_TYPE_UNKNOWN != m_eParamType) ? (m_eParamType == rhs.m_eParamType) : (m_strParam == rhs.m_strParam) ); | ||
543 | } | ||
544 | |||
545 | inline void RlvCurrentlyWorn::fetchItem(const LLUUID& idItem) | ||
546 | { | ||
547 | if (idItem.notNull()) | ||
548 | { | ||
549 | LLInventoryFetchObserver::item_ref_t idItems; | ||
550 | idItems.push_back(idItem); | ||
551 | fetchItems(idItems); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | // ============================================================================ | ||
556 | // Inlined helper functions | ||
557 | // | ||
558 | |||
559 | inline bool rlvIsEmote(const std::string& strUTF8Text) | ||
560 | { | ||
561 | return (strUTF8Text.length() > 4) && ( (strUTF8Text.compare(0, 4, "/me ") == 0) || (strUTF8Text.compare(0, 4, "/me'") == 0) ); | ||
562 | } | ||
563 | |||
564 | // Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e | ||
565 | inline bool rlvIsValidChannel(S32 nChannel) | ||
566 | { | ||
567 | return (nChannel >= 0) && (CHAT_CHANNEL_DEBUG != nChannel); | ||
568 | } | ||
569 | |||
570 | // Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e | ||
571 | inline bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply) | ||
572 | { | ||
573 | S32 nChannel; | ||
574 | return (LLStringUtil::convertToS32(strChannel, nChannel)) ? rlvSendChatReply(nChannel, strReply) : false; | ||
575 | } | ||
576 | |||
577 | // ============================================================================ | ||
578 | |||
579 | #endif // RLV_HELPER_H | ||