aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewergesture.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llviewergesture.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llviewergesture.cpp279
1 files changed, 279 insertions, 0 deletions
diff --git a/linden/indra/newview/llviewergesture.cpp b/linden/indra/newview/llviewergesture.cpp
new file mode 100644
index 0000000..d4201c0
--- /dev/null
+++ b/linden/indra/newview/llviewergesture.cpp
@@ -0,0 +1,279 @@
1/**
2 * @file llviewergesture.cpp
3 * @brief LLViewerGesture class implementation
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "llviewergesture.h"
31
32#include "audioengine.h"
33#include "lldir.h"
34#include "llviewerinventory.h"
35#include "sound_ids.h" // for testing
36
37#include "llchatbar.h"
38#include "llkeyboard.h" // for key shortcuts for testing
39#include "llinventorymodel.h"
40#include "llvoavatar.h"
41#include "llxfermanager.h"
42#include "llviewermessage.h" // send_guid_sound_trigger
43#include "llviewernetwork.h"
44#include "llagent.h"
45
46// Globals
47LLViewerGestureList gGestureList;
48
49const F32 LLViewerGesture::SOUND_VOLUME = 1.f;
50
51LLViewerGesture::LLViewerGesture()
52: LLGesture()
53{ }
54
55LLViewerGesture::LLViewerGesture(KEY key, MASK mask, const std::string &trigger,
56 const LLUUID &sound_item_id,
57 const std::string &animation,
58 const std::string &output_string)
59: LLGesture(key, mask, trigger, sound_item_id, animation, output_string)
60{
61}
62
63LLViewerGesture::LLViewerGesture(U8 **buffer, S32 max_size)
64: LLGesture(buffer, max_size)
65{
66}
67
68LLViewerGesture::LLViewerGesture(const LLViewerGesture &rhs)
69: LLGesture((LLGesture)rhs)
70{
71}
72
73BOOL LLViewerGesture::trigger(KEY key, MASK mask)
74{
75 if (mKey == key && mMask == mask)
76 {
77 doTrigger( TRUE );
78 return TRUE;
79 }
80 else
81 {
82 return FALSE;
83 }
84}
85
86
87BOOL LLViewerGesture::trigger(const std::string &trigger_string)
88{
89 // Assumes trigger_string is lowercase
90 if (mTriggerLower == trigger_string)
91 {
92 doTrigger( FALSE );
93 return TRUE;
94 }
95 else
96 {
97 return FALSE;
98 }
99}
100
101
102// private
103void LLViewerGesture::doTrigger( BOOL send_chat )
104{
105 if (mSoundItemID != LLUUID::null)
106 {
107 LLViewerInventoryItem *item;
108 item = gInventory.getItem(mSoundItemID);
109 if (item)
110 {
111 send_sound_trigger(item->getAssetUUID(), SOUND_VOLUME);
112 }
113 }
114
115 if (!mAnimation.empty())
116 {
117 // AFK animations trigger the special "away" state, which
118 // includes agent control settings. JC
119 if (mAnimation == "enter_away_from_keyboard_state" || mAnimation == "away")
120 {
121 gAgent.setAFK();
122 }
123 else
124 {
125 LLUUID anim_id = gAnimLibrary.stringToAnimState(mAnimation.c_str());
126 gAgent.sendAnimationRequest(anim_id, ANIM_REQUEST_START);
127 }
128 }
129
130 if ( send_chat && !mOutputString.empty())
131 {
132 // Don't play nodding animation, since that might not blend
133 // with the gesture animation.
134 gChatBar->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
135 }
136}
137
138
139LLViewerGestureList::LLViewerGestureList()
140: LLGestureList()
141{
142 mIsLoaded = FALSE;
143}
144
145void LLViewerGestureList::saveToServer()
146{
147 U8 *buffer = new U8[getMaxSerialSize()];
148
149 U8 *end = serialize(buffer);
150
151 if (end - buffer > getMaxSerialSize())
152 {
153 llerrs << "Wrote off end of buffer, serial size computation is wrong" << llendl;
154 }
155
156 //U64 xfer_id = gXferManager->registerXfer(buffer, end - buffer);
157 // write to a file because mem<->mem xfer isn't implemented
158 LLUUID random_uuid;
159 char filename[LL_MAX_PATH];
160 random_uuid.generate();
161 random_uuid.toString(filename);
162 strcat(filename,".tmp");
163
164 char filename_and_path[LL_MAX_PATH];
165 sprintf(filename_and_path, "%s%s%s",
166 gDirUtilp->getTempDir().c_str(),
167 gDirUtilp->getDirDelimiter().c_str(),
168 filename);
169
170 FILE *fp = LLFile::fopen(filename_and_path, "wb");
171
172 if (fp)
173 {
174 fwrite(buffer, end - buffer, 1, fp);
175 fclose(fp);
176
177 gMessageSystem->newMessageFast(_PREHASH_GestureUpdate);
178 gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
179 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
180 gMessageSystem->addStringFast(_PREHASH_Filename, filename);
181 gMessageSystem->addBOOLFast(_PREHASH_ToViewer, FALSE);
182 gMessageSystem->sendReliable(gUserServer);
183 }
184
185 delete[] buffer;
186}
187
188/*
189void LLViewerGestureList::requestFromServer()
190{
191 gMessageSystem->newMessageFast(_PREHASH_GestureRequest);
192 gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
193 gMessageSystem->addUUIDFast(_PREHASH_AgentID, agent_get_id());
194 gMessageSystem->addU8("Reset", 0);
195 gMessageSystem->sendReliable(gUserServer);
196}
197
198void LLViewerGestureList::requestResetFromServer( BOOL is_male )
199{
200 gMessageSystem->newMessageFast(_PREHASH_GestureRequest);
201 gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
202 gMessageSystem->addUUIDFast(_PREHASH_AgentID, agent_get_id());
203 gMessageSystem->addU8("Reset", is_male ? 1 : 2);
204 gMessageSystem->sendReliable(gUserServer);
205 mIsLoaded = FALSE;
206}
207*/
208
209// helper for deserialize that creates the right LLGesture subclass
210LLGesture *LLViewerGestureList::create_gesture(U8 **buffer, S32 max_size)
211{
212 return new LLViewerGesture(buffer, max_size);
213}
214
215
216// See if the prefix matches any gesture. If so, return TRUE
217// and place the full text of the gesture trigger into
218// output_str
219BOOL LLViewerGestureList::matchPrefix(const std::string& in_str, std::string* out_str)
220{
221 S32 in_len = in_str.length();
222
223 LLString in_str_lc = in_str;
224 LLString::toLower(in_str_lc);
225
226 for (S32 i = 0; i < count(); i++)
227 {
228 LLGesture* gesture = get(i);
229 const std::string &trigger = gesture->getTrigger();
230
231 if (in_len > (S32)trigger.length())
232 {
233 // too short, bail out
234 continue;
235 }
236
237 std::string trigger_trunc = utf8str_truncate(trigger, in_len);
238 LLString::toLower(trigger_trunc);
239 if (in_str_lc == trigger_trunc)
240 {
241 *out_str = trigger;
242 return TRUE;
243 }
244 }
245 return FALSE;
246}
247
248
249// static
250void LLViewerGestureList::xferCallback(void *data, S32 size, void** /*user_data*/, S32 status)
251{
252 if (LL_ERR_NOERR == status)
253 {
254 U8 *buffer = (U8 *)data;
255 U8 *end = gGestureList.deserialize(buffer, size);
256
257 if (end - buffer > size)
258 {
259 llerrs << "Read off of end of array, error in serialization" << llendl;
260 }
261
262 gGestureList.mIsLoaded = TRUE;
263 }
264 else
265 {
266 llwarns << "Unable to load gesture list!" << llendl;
267 }
268}
269
270// static
271void LLViewerGestureList::processGestureUpdate(LLMessageSystem *msg, void** /*user_data*/)
272{
273 char remote_filename[MAX_STRING];
274 msg->getStringFast(_PREHASH_AgentBlock, _PREHASH_Filename, MAX_STRING, remote_filename);
275
276
277 gXferManager->requestFile(remote_filename, LL_PATH_CACHE, msg->getSender(), TRUE, xferCallback, NULL,
278 LLXferManager::HIGH_PRIORITY);
279}