corrade-lsl-templates – Diff between revs 5 and 29

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 5 Rev 29
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // 4 //
5 // This project makes Corrade, the Second Life / OpenSim bot look at the 5 // This project makes Corrade, the Second Life / OpenSim bot look at the
6 // avatars typing in local chat. You can find more details about the bot 6 // avatars typing in local chat. You can find more details about the bot
7 // at the URL: http://grimore.org/secondlife/scripted_agents/corrade 7 // at the URL: http://grimore.org/secondlife/scripted_agents/corrade
8 // 8 //
9 // The script works in combination with a "configuration" notecard that 9 // The script works in combination with a "configuration" notecard that
10 // must be placed in the same primitive as this script. The purpose of this 10 // must be placed in the same primitive as this script. The purpose of this
11 // script is to show setting and disposing of viewer effects with Corrade 11 // script is to show setting and disposing of viewer effects with Corrade
12 // and you are free to use, change, and commercialize it under the terms 12 // and you are free to use, change, and commercialize it under the terms
13 // of the GNU/GPLv3 license at: http://www.gnu.org/licenses/gpl.html 13 // of the CC BY 2.0 license at: https://creativecommons.org/licenses/by/2.0
14 // 14 //
15 /////////////////////////////////////////////////////////////////////////// 15 ///////////////////////////////////////////////////////////////////////////
16   16  
17 /////////////////////////////////////////////////////////////////////////// 17 ///////////////////////////////////////////////////////////////////////////
18 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 18 // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 //
19 /////////////////////////////////////////////////////////////////////////// 19 ///////////////////////////////////////////////////////////////////////////
20 string wasKeyValueGet(string k, string data) { 20 string wasKeyValueGet(string k, string data) {
21 if(llStringLength(data) == 0) return ""; 21 if(llStringLength(data) == 0) return "";
22 if(llStringLength(k) == 0) return ""; 22 if(llStringLength(k) == 0) return "";
23 list a = llParseString2List(data, ["&", "="], []); 23 list a = llParseString2List(data, ["&", "="], []);
24 integer i = llListFindList(a, [ k ]); 24 integer i = llListFindList(a, [ k ]);
25 if(i != -1) return llList2String(a, i+1); 25 if(i != -1) return llList2String(a, i+1);
26 return ""; 26 return "";
27 } 27 }
28 28
29 /////////////////////////////////////////////////////////////////////////// 29 ///////////////////////////////////////////////////////////////////////////
30 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // 30 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 //
31 /////////////////////////////////////////////////////////////////////////// 31 ///////////////////////////////////////////////////////////////////////////
32 string wasKeyValueEncode(list data) { 32 string wasKeyValueEncode(list data) {
33 list k = llList2ListStrided(data, 0, -1, 2); 33 list k = llList2ListStrided(data, 0, -1, 2);
34 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 34 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
35 data = []; 35 data = [];
36 do { 36 do {
37 data += llList2String(k, 0) + "=" + llList2String(v, 0); 37 data += llList2String(k, 0) + "=" + llList2String(v, 0);
38 k = llDeleteSubList(k, 0, 0); 38 k = llDeleteSubList(k, 0, 0);
39 v = llDeleteSubList(v, 0, 0); 39 v = llDeleteSubList(v, 0, 0);
40 } while(llGetListLength(k) != 0); 40 } while(llGetListLength(k) != 0);
41 return llDumpList2String(data, "&"); 41 return llDumpList2String(data, "&");
42 } 42 }
43   43  
44 /////////////////////////////////////////////////////////////////////////// 44 ///////////////////////////////////////////////////////////////////////////
45 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 45 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
46 /////////////////////////////////////////////////////////////////////////// 46 ///////////////////////////////////////////////////////////////////////////
47 // escapes a string in conformance with RFC1738 47 // escapes a string in conformance with RFC1738
48 string wasURLEscape(string i) { 48 string wasURLEscape(string i) {
49 string o = ""; 49 string o = "";
50 do { 50 do {
51 string c = llGetSubString(i, 0, 0); 51 string c = llGetSubString(i, 0, 0);
52 i = llDeleteSubString(i, 0, 0); 52 i = llDeleteSubString(i, 0, 0);
53 if(c == "") jump continue; 53 if(c == "") jump continue;
54 if(c == " ") { 54 if(c == " ") {
55 o += "+"; 55 o += "+";
56 jump continue; 56 jump continue;
57 } 57 }
58 if(c == "\n") { 58 if(c == "\n") {
59 o += "%0D" + llEscapeURL(c); 59 o += "%0D" + llEscapeURL(c);
60 jump continue; 60 jump continue;
61 } 61 }
62 o += llEscapeURL(c); 62 o += llEscapeURL(c);
63 @continue; 63 @continue;
64 } while(i != ""); 64 } while(i != "");
65 return o; 65 return o;
66 } 66 }
67   67  
68 /////////////////////////////////////////////////////////////////////////// 68 ///////////////////////////////////////////////////////////////////////////
69 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 69 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
70 /////////////////////////////////////////////////////////////////////////// 70 ///////////////////////////////////////////////////////////////////////////
71 // unescapes a string in conformance with RFC1738 71 // unescapes a string in conformance with RFC1738
72 string wasURLUnescape(string i) { 72 string wasURLUnescape(string i) {
73 return llUnescapeURL( 73 return llUnescapeURL(
74 llDumpList2String( 74 llDumpList2String(
75 llParseString2List( 75 llParseString2List(
76 llDumpList2String( 76 llDumpList2String(
77 llParseString2List( 77 llParseString2List(
78 i, 78 i,
79 ["+"], 79 ["+"],
80 [] 80 []
81 ), 81 ),
82 " " 82 " "
83 ), 83 ),
84 ["%0D%0A"], 84 ["%0D%0A"],
85 [] 85 []
86 ), 86 ),
87 "\n" 87 "\n"
88 ) 88 )
89 ); 89 );
90 } 90 }
91   91  
92 // corrade data 92 // corrade data
93 key CORRADE = NULL_KEY; 93 key CORRADE = NULL_KEY;
94 string GROUP = ""; 94 string GROUP = "";
95 string PASSWORD = ""; 95 string PASSWORD = "";
96 // the look UUID 96 // the look UUID
97 key LOOK = NULL_KEY; 97 key LOOK = NULL_KEY;
98 // the effect to use 98 // the effect to use
99 string EFFECT = "look"; 99 string EFFECT = "look";
100 key EFFECT_UUID = NULL_KEY; 100 key EFFECT_UUID = NULL_KEY;
101 string EFFECT_TYPE = ""; 101 string EFFECT_TYPE = "";
102 integer EFFECT_DURATION = 10; 102 integer EFFECT_DURATION = 10;
103   103  
104 // for holding the callback URL 104 // for holding the callback URL
105 string callback = ""; 105 string callback = "";
106   106  
107 // for notecard reading 107 // for notecard reading
108 integer line = 0; 108 integer line = 0;
109 109
110 // key-value data will be read into this list 110 // key-value data will be read into this list
111 list tuples = []; 111 list tuples = [];
112   112  
113 // the name to look at 113 // the name to look at
114 string firstName = ""; 114 string firstName = "";
115 string lastName = ""; 115 string lastName = "";
116   116  
117 default { 117 default {
118 state_entry() { 118 state_entry() {
119 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { 119 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
120 llOwnerSay("Sorry, could not find a configuration inventory notecard."); 120 llOwnerSay("Sorry, could not find a configuration inventory notecard.");
121 return; 121 return;
122 } 122 }
123 // DEBUG 123 // DEBUG
124 llOwnerSay("Reading configuration file..."); 124 llOwnerSay("Reading configuration file...");
125 llGetNotecardLine("configuration", line); 125 llGetNotecardLine("configuration", line);
126 } 126 }
127 dataserver(key id, string data) { 127 dataserver(key id, string data) {
128 if(data == EOF) { 128 if(data == EOF) {
129 // invariant, length(tuples) % 2 == 0 129 // invariant, length(tuples) % 2 == 0
130 if(llGetListLength(tuples) % 2 != 0) { 130 if(llGetListLength(tuples) % 2 != 0) {
131 llOwnerSay("Error in configuration notecard."); 131 llOwnerSay("Error in configuration notecard.");
132 return; 132 return;
133 } 133 }
134 CORRADE = llList2Key( 134 CORRADE = llList2Key(
135 tuples, 135 tuples,
136 llListFindList( 136 llListFindList(
137 tuples, 137 tuples,
138 [ 138 [
139 "corrade" 139 "corrade"
140 ] 140 ]
141 ) 141 )
142 +1 142 +1
143 ); 143 );
144 if(CORRADE == NULL_KEY) { 144 if(CORRADE == NULL_KEY) {
145 llOwnerSay("Error in configuration notecard: corrade"); 145 llOwnerSay("Error in configuration notecard: corrade");
146 return; 146 return;
147 } 147 }
148 GROUP = llList2String( 148 GROUP = llList2String(
149 tuples, 149 tuples,
150 llListFindList( 150 llListFindList(
151 tuples, 151 tuples,
152 [ 152 [
153 "group" 153 "group"
154 ] 154 ]
155 ) 155 )
156 +1 156 +1
157 ); 157 );
158 if(GROUP == "") { 158 if(GROUP == "") {
159 llOwnerSay("Error in configuration notecard: group"); 159 llOwnerSay("Error in configuration notecard: group");
160 return; 160 return;
161 } 161 }
162 PASSWORD = llList2String( 162 PASSWORD = llList2String(
163 tuples, 163 tuples,
164 llListFindList( 164 llListFindList(
165 tuples, 165 tuples,
166 [ 166 [
167 "password" 167 "password"
168 ] 168 ]
169 ) 169 )
170 +1 170 +1
171 ); 171 );
172 if(PASSWORD == "") { 172 if(PASSWORD == "") {
173 llOwnerSay("Error in configuration notecard: password"); 173 llOwnerSay("Error in configuration notecard: password");
174 return; 174 return;
175 } 175 }
176 EFFECT = llToLower( 176 EFFECT = llToLower(
177 llList2String( 177 llList2String(
178 tuples, 178 tuples,
179 llListFindList( 179 llListFindList(
180 tuples, 180 tuples,
181 [ 181 [
182 "effect" 182 "effect"
183 ] 183 ]
184 ) 184 )
185 +1 185 +1
186 ) 186 )
187 ); 187 );
188 if(EFFECT != "look" && EFFECT != "point") { 188 if(EFFECT != "look" && EFFECT != "point") {
189 llOwnerSay("Error in configuration notecard: effect"); 189 llOwnerSay("Error in configuration notecard: effect");
190 return; 190 return;
191 } 191 }
192 if(EFFECT == "look") { 192 if(EFFECT == "look") {
193 EFFECT_UUID = llList2Key( 193 EFFECT_UUID = llList2Key(
194 tuples, 194 tuples,
195 llListFindList( 195 llListFindList(
196 tuples, 196 tuples,
197 [ 197 [
198 "lookUUID" 198 "lookUUID"
199 ] 199 ]
200 ) 200 )
201 +1 201 +1
202 ); 202 );
203 if(EFFECT_UUID == NULL_KEY) { 203 if(EFFECT_UUID == NULL_KEY) {
204 llOwnerSay("Error in configuration notecard: lookUUID"); 204 llOwnerSay("Error in configuration notecard: lookUUID");
205 return; 205 return;
206 } 206 }
207 EFFECT_TYPE = "Focus"; 207 EFFECT_TYPE = "Focus";
208 } 208 }
209 if(EFFECT == "point") { 209 if(EFFECT == "point") {
210 EFFECT_UUID = llList2Key( 210 EFFECT_UUID = llList2Key(
211 tuples, 211 tuples,
212 llListFindList( 212 llListFindList(
213 tuples, 213 tuples,
214 [ 214 [
215 "pointUUID" 215 "pointUUID"
216 ] 216 ]
217 ) 217 )
218 +1 218 +1
219 ); 219 );
220 if(EFFECT_UUID == NULL_KEY) { 220 if(EFFECT_UUID == NULL_KEY) {
221 llOwnerSay("Error in configuration notecard: pointUUID"); 221 llOwnerSay("Error in configuration notecard: pointUUID");
222 return; 222 return;
223 } 223 }
224 EFFECT_TYPE = "Select"; 224 EFFECT_TYPE = "Select";
225 } 225 }
226 EFFECT_DURATION = llList2Integer( 226 EFFECT_DURATION = llList2Integer(
227 tuples, 227 tuples,
228 llListFindList( 228 llListFindList(
229 tuples, 229 tuples,
230 [ 230 [
231 "duration" 231 "duration"
232 ] 232 ]
233 ) 233 )
234 +1 234 +1
235 ); 235 );
236 if(EFFECT_DURATION == 0) { 236 if(EFFECT_DURATION == 0) {
237 llOwnerSay("Error in configuration notecard: duration"); 237 llOwnerSay("Error in configuration notecard: duration");
238 return; 238 return;
239 } 239 }
240 // DEBUG 240 // DEBUG
241 llOwnerSay("Read configuration notecard..."); 241 llOwnerSay("Read configuration notecard...");
242 state url; 242 state url;
243 } 243 }
244 if(data == "") jump continue; 244 if(data == "") jump continue;
245 integer i = llSubStringIndex(data, "#"); 245 integer i = llSubStringIndex(data, "#");
246 if(i != -1) data = llDeleteSubString(data, i, -1); 246 if(i != -1) data = llDeleteSubString(data, i, -1);
247 list o = llParseString2List(data, ["="], []); 247 list o = llParseString2List(data, ["="], []);
248 // get rid of starting and ending quotes 248 // get rid of starting and ending quotes
249 string k = llDumpList2String( 249 string k = llDumpList2String(
250 llParseString2List( 250 llParseString2List(
251 llStringTrim( 251 llStringTrim(
252 llList2String( 252 llList2String(
253 o, 253 o,
254 0 254 0
255 ), 255 ),
256 STRING_TRIM), 256 STRING_TRIM),
257 ["\""], [] 257 ["\""], []
258 ), "\""); 258 ), "\"");
259 string v = llDumpList2String( 259 string v = llDumpList2String(
260 llParseString2List( 260 llParseString2List(
261 llStringTrim( 261 llStringTrim(
262 llList2String( 262 llList2String(
263 o, 263 o,
264 1 264 1
265 ), 265 ),
266 STRING_TRIM), 266 STRING_TRIM),
267 ["\""], [] 267 ["\""], []
268 ), "\""); 268 ), "\"");
269 if(k == "" || v == "") jump continue; 269 if(k == "" || v == "") jump continue;
270 tuples += k; 270 tuples += k;
271 tuples += v; 271 tuples += v;
272 @continue; 272 @continue;
273 llGetNotecardLine("configuration", ++line); 273 llGetNotecardLine("configuration", ++line);
274 } 274 }
275 on_rez(integer num) { 275 on_rez(integer num) {
276 llResetScript(); 276 llResetScript();
277 } 277 }
278 changed(integer change) { 278 changed(integer change) {
279 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 279 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
280 llResetScript(); 280 llResetScript();
281 } 281 }
282 } 282 }
283 } 283 }
284   284  
285 state url { 285 state url {
286 state_entry() { 286 state_entry() {
287 // DEBUG 287 // DEBUG
288 llOwnerSay("Requesting URL..."); 288 llOwnerSay("Requesting URL...");
289 llRequestURL(); 289 llRequestURL();
290 } 290 }
291 http_request(key id, string method, string body) { 291 http_request(key id, string method, string body) {
292 if(method != URL_REQUEST_GRANTED) return; 292 if(method != URL_REQUEST_GRANTED) return;
293 callback = body; 293 callback = body;
294 // DEBUG 294 // DEBUG
295 llOwnerSay("Got URL..."); 295 llOwnerSay("Got URL...");
296 state detect; 296 state detect;
297 } 297 }
298 on_rez(integer num) { 298 on_rez(integer num) {
299 llResetScript(); 299 llResetScript();
300 } 300 }
301 changed(integer change) { 301 changed(integer change) {
302 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 302 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
303 llResetScript(); 303 llResetScript();
304 } 304 }
305 } 305 }
306 } 306 }
307 307
308 state detect { 308 state detect {
309 state_entry() { 309 state_entry() {
310 // DEBUG 310 // DEBUG
311 llOwnerSay("Detecting if Corrade is online..."); 311 llOwnerSay("Detecting if Corrade is online...");
312 llSetTimerEvent(5); 312 llSetTimerEvent(5);
313 } 313 }
314 timer() { 314 timer() {
315 llRequestAgentData((key)CORRADE, DATA_ONLINE); 315 llRequestAgentData((key)CORRADE, DATA_ONLINE);
316 } 316 }
317 dataserver(key id, string data) { 317 dataserver(key id, string data) {
318 if(data != "1") { 318 if(data != "1") {
319 // DEBUG 319 // DEBUG
320 llOwnerSay("Corrade is not online, sleeping..."); 320 llOwnerSay("Corrade is not online, sleeping...");
321 llSetTimerEvent(30); 321 llSetTimerEvent(30);
322 return; 322 return;
323 } 323 }
324 state notify; 324 state notify;
325 } 325 }
326 on_rez(integer num) { 326 on_rez(integer num) {
327 llResetScript(); 327 llResetScript();
328 } 328 }
329 changed(integer change) { 329 changed(integer change) {
330 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 330 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
331 llResetScript(); 331 llResetScript();
332 } 332 }
333 } 333 }
334 } 334 }
335 335
336 state notify { 336 state notify {
337 state_entry() { 337 state_entry() {
338 // DEBUG 338 // DEBUG
339 llOwnerSay("Binding to the typing notification for local chat..."); 339 llOwnerSay("Binding to the typing notification for local chat...");
340 llInstantMessage( 340 llInstantMessage(
341 (key)CORRADE, 341 (key)CORRADE,
342 wasKeyValueEncode( 342 wasKeyValueEncode(
343 [ 343 [
344 "command", "notify", 344 "command", "notify",
345 "group", wasURLEscape(GROUP), 345 "group", wasURLEscape(GROUP),
346 "password", wasURLEscape(PASSWORD), 346 "password", wasURLEscape(PASSWORD),
347 "action", "set", 347 "action", "set",
348 "type", "typing", 348 "type", "typing",
349 "URL", wasURLEscape(callback), 349 "URL", wasURLEscape(callback),
350 "callback", wasURLEscape(callback) 350 "callback", wasURLEscape(callback)
351 ] 351 ]
352 ) 352 )
353 ); 353 );
354 } 354 }
355 http_request(key id, string method, string body) { 355 http_request(key id, string method, string body) {
356 llHTTPResponse(id, 200, "OK"); 356 llHTTPResponse(id, 200, "OK");
357 if(wasKeyValueGet("command", body) != "notify") return; 357 if(wasKeyValueGet("command", body) != "notify") return;
358 if(wasKeyValueGet("success", body) != "True") { 358 if(wasKeyValueGet("success", body) != "True") {
359 // DEBUG 359 // DEBUG
360 llOwnerSay("Failed to bind to the typing notification..."); 360 llOwnerSay("Failed to bind to the typing notification...");
361 state sense; 361 state sense;
362 } 362 }
363 // DEBUG 363 // DEBUG
364 llOwnerSay("Typing notification installed..."); 364 llOwnerSay("Typing notification installed...");
365 state sense; 365 state sense;
366 } 366 }
367 on_rez(integer num) { 367 on_rez(integer num) {
368 llResetScript(); 368 llResetScript();
369 } 369 }
370 changed(integer change) { 370 changed(integer change) {
371 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 371 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
372 llResetScript(); 372 llResetScript();
373 } 373 }
374 } 374 }
375 } 375 }
376   376  
377 state sense { 377 state sense {
378 state_entry() { 378 state_entry() {
379 // DEBUG 379 // DEBUG
380 llOwnerSay("Waiting for typing messages..."); 380 llOwnerSay("Waiting for typing messages...");
381 } 381 }
382 timer() { 382 timer() {
383 llRequestAgentData((key)CORRADE, DATA_ONLINE); 383 llRequestAgentData((key)CORRADE, DATA_ONLINE);
384 } 384 }
385 dataserver(key id, string data) { 385 dataserver(key id, string data) {
386 if(data == "1") return; 386 if(data == "1") return;
387 // DEBUG 387 // DEBUG
388 llOwnerSay("Corrade is not online, sleeping..."); 388 llOwnerSay("Corrade is not online, sleeping...");
389 // Switch to detect loop and wait there for Corrade to come online. 389 // Switch to detect loop and wait there for Corrade to come online.
390 state detect; 390 state detect;
391 } 391 }
392 http_request(key id, string method, string body) { 392 http_request(key id, string method, string body) {
393 llHTTPResponse(id, 200, "OK"); 393 llHTTPResponse(id, 200, "OK");
394 firstName = wasURLUnescape( 394 firstName = wasURLUnescape(
395 wasKeyValueGet( 395 wasKeyValueGet(
396 "firstname", 396 "firstname",
397 body 397 body
398 ) 398 )
399 ); 399 );
400 lastName = wasURLUnescape( 400 lastName = wasURLUnescape(
401 wasKeyValueGet( 401 wasKeyValueGet(
402 "lastname", 402 "lastname",
403 body 403 body
404 ) 404 )
405 ); 405 );
406 state delete; 406 state delete;
407 } 407 }
408 on_rez(integer num) { 408 on_rez(integer num) {
409 llResetScript(); 409 llResetScript();
410 } 410 }
411 changed(integer change) { 411 changed(integer change) {
412 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 412 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
413 llResetScript(); 413 llResetScript();
414 } 414 }
415 } 415 }
416 } 416 }
417   417  
418 state delete { 418 state delete {
419 state_entry() { 419 state_entry() {
420 llInstantMessage( 420 llInstantMessage(
421 (key)CORRADE, wasKeyValueEncode( 421 (key)CORRADE, wasKeyValueEncode(
422 [ 422 [
423 "command", "deleteviewereffect", 423 "command", "deleteviewereffect",
424 "group", wasURLEscape(GROUP), 424 "group", wasURLEscape(GROUP),
425 "password", wasURLEscape(PASSWORD), 425 "password", wasURLEscape(PASSWORD),
426 "effect", EFFECT, 426 "effect", EFFECT,
427 "id", EFFECT_UUID, 427 "id", EFFECT_UUID,
428 "callback", wasURLEscape(callback) 428 "callback", wasURLEscape(callback)
429 ] 429 ]
430 ) 430 )
431 ); 431 );
432 // alarm 10 432 // alarm 10
433 llSetTimerEvent(10); 433 llSetTimerEvent(10);
434 } 434 }
435 timer() { 435 timer() {
436 state effect; 436 state effect;
437 } 437 }
438 http_request(key id, string method, string body) { 438 http_request(key id, string method, string body) {
439 llHTTPResponse(id, 200, "OK"); 439 llHTTPResponse(id, 200, "OK");
440 state effect; 440 state effect;
441 } 441 }
442 on_rez(integer num) { 442 on_rez(integer num) {
443 llResetScript(); 443 llResetScript();
444 } 444 }
445 changed(integer change) { 445 changed(integer change) {
446 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 446 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
447 llResetScript(); 447 llResetScript();
448 } 448 }
449 } 449 }
450 state_exit() { 450 state_exit() {
451 llSetTimerEvent(0); 451 llSetTimerEvent(0);
452 } 452 }
453 } 453 }
454   454  
455 state effect { 455 state effect {
456 state_entry() { 456 state_entry() {
457 llInstantMessage( 457 llInstantMessage(
458 (key)CORRADE, wasKeyValueEncode( 458 (key)CORRADE, wasKeyValueEncode(
459 [ 459 [
460 "command", "setviewereffect", 460 "command", "setviewereffect",
461 "group", wasURLEscape(GROUP), 461 "group", wasURLEscape(GROUP),
462 "password", wasURLEscape(PASSWORD), 462 "password", wasURLEscape(PASSWORD),
463 "effect", EFFECT, 463 "effect", EFFECT,
464 "offset", ZERO_VECTOR, 464 "offset", ZERO_VECTOR,
465 "firstname", firstName, 465 "firstname", firstName,
466 "lastname", lastName, 466 "lastname", lastName,
467 "type", EFFECT_TYPE, 467 "type", EFFECT_TYPE,
468 "id", EFFECT_UUID, 468 "id", EFFECT_UUID,
469 "callback", wasURLEscape(callback) 469 "callback", wasURLEscape(callback)
470 ] 470 ]
471 ) 471 )
472 ); 472 );
473 // alarm 10 473 // alarm 10
474 llSetTimerEvent(10); 474 llSetTimerEvent(10);
475 } 475 }
476 timer() { 476 timer() {
477 state sense; 477 state sense;
478 } 478 }
479 http_request(key id, string method, string body) { 479 http_request(key id, string method, string body) {
480 llHTTPResponse(id, 200, "OK"); 480 llHTTPResponse(id, 200, "OK");
481 if(wasKeyValueGet("command", body) 481 if(wasKeyValueGet("command", body)
482 != "setviewereffect") return; 482 != "setviewereffect") return;
483 if(wasKeyValueGet("success", body) != "True") { 483 if(wasKeyValueGet("success", body) != "True") {
484 // DEBUG 484 // DEBUG
485 llOwnerSay("Failed to look at..."); 485 llOwnerSay("Failed to look at...");
486 state sense; 486 state sense;
487 } 487 }
488 state wait; 488 state wait;
489 } 489 }
490 on_rez(integer num) { 490 on_rez(integer num) {
491 llResetScript(); 491 llResetScript();
492 } 492 }
493 changed(integer change) { 493 changed(integer change) {
494 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 494 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
495 llResetScript(); 495 llResetScript();
496 } 496 }
497 } 497 }
498 state_exit() { 498 state_exit() {
499 llSetTimerEvent(0); 499 llSetTimerEvent(0);
500 } 500 }
501 } 501 }
502   502  
503 state wait { 503 state wait {
504 state_entry() { 504 state_entry() {
505 llSetTimerEvent(EFFECT_DURATION); 505 llSetTimerEvent(EFFECT_DURATION);
506 } 506 }
507 timer() { 507 timer() {
508 llSetTimerEvent(0); 508 llSetTimerEvent(0);
509 llInstantMessage( 509 llInstantMessage(
510 (key)CORRADE, wasKeyValueEncode( 510 (key)CORRADE, wasKeyValueEncode(
511 [ 511 [
512 "command", "deleteviewereffect", 512 "command", "deleteviewereffect",
513 "group", wasURLEscape(GROUP), 513 "group", wasURLEscape(GROUP),
514 "password", wasURLEscape(PASSWORD), 514 "password", wasURLEscape(PASSWORD),
515 "effect", EFFECT, 515 "effect", EFFECT,
516 "id", EFFECT_UUID 516 "id", EFFECT_UUID
517 ] 517 ]
518 ) 518 )
519 ); 519 );
520 state sense; 520 state sense;
521 } 521 }
522 on_rez(integer num) { 522 on_rez(integer num) {
523 llResetScript(); 523 llResetScript();
524 } 524 }
525 changed(integer change) { 525 changed(integer change) {
526 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 526 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
527 llResetScript(); 527 llResetScript();
528 } 528 }
529 } 529 }
530 state_exit() { 530 state_exit() {
531 llSetTimerEvent(0); 531 llSetTimerEvent(0);
532 } 532 }
533 } 533 }
534   534