corrade-lsl-templates – Blame information for rev 37

Subversion Repositories:
Rev:
Rev Author Line No. Line
35 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 //
3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // This script makes Corrade retrieve an item from the sim.
6 // For more information on Corrade, please see:
7 // http://grimore.org/secondlife/scripted_agents/corrade
8 //
9 ///////////////////////////////////////////////////////////////////////////
10  
11 ///////////////////////////////////////////////////////////////////////////
12 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
13 ///////////////////////////////////////////////////////////////////////////
14 vector wasCirclePoint(float radius) {
15 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
16 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
17 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
18 return <x, y, 0>;
19 return wasCirclePoint(radius);
20 }
21  
22 ///////////////////////////////////////////////////////////////////////////
23 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
24 ///////////////////////////////////////////////////////////////////////////
25 string wasKeyValueGet(string k, string data) {
26 if(llStringLength(data) == 0) return "";
27 if(llStringLength(k) == 0) return "";
28 list a = llParseString2List(data, ["&", "="], []);
29 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
30 if(i != -1) return llList2String(a, 2*i+1);
31 return "";
32 }
33  
34 ///////////////////////////////////////////////////////////////////////////
35 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 //
36 ///////////////////////////////////////////////////////////////////////////
37 string wasKeyValueEncode(list data) {
38 list k = llList2ListStrided(data, 0, -1, 2);
39 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
40 data = [];
41 do {
42 data += llList2String(k, 0) + "=" + llList2String(v, 0);
43 k = llDeleteSubList(k, 0, 0);
44 v = llDeleteSubList(v, 0, 0);
45 } while(llGetListLength(k) != 0);
46 return llDumpList2String(data, "&");
47 }
48  
49 ///////////////////////////////////////////////////////////////////////////
50 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
51 ///////////////////////////////////////////////////////////////////////////
52 // escapes a string in conformance with RFC1738
53 string wasURLEscape(string i) {
54 string o = "";
55 do {
56 string c = llGetSubString(i, 0, 0);
57 i = llDeleteSubString(i, 0, 0);
58 if(c == "") jump continue;
59 if(c == " ") {
60 o += "+";
61 jump continue;
62 }
63 if(c == "\n") {
64 o += "%0D" + llEscapeURL(c);
65 jump continue;
66 }
67 o += llEscapeURL(c);
68 @continue;
69 } while(i != "");
70 return o;
71 }
72  
73 ///////////////////////////////////////////////////////////////////////////
74 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
75 ///////////////////////////////////////////////////////////////////////////
76 // unescapes a string in conformance with RFC1738
77 string wasURLUnescape(string i) {
78 return llUnescapeURL(
79 llDumpList2String(
80 llParseString2List(
81 llDumpList2String(
82 llParseString2List(
83 i,
84 ["+"],
85 []
86 ),
87 " "
88 ),
89 ["%0D%0A"],
90 []
91 ),
92 "\n"
93 )
94 );
95 }
96  
97 ///////////////////////////////////////////////////////////////////////////
98 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
99 ///////////////////////////////////////////////////////////////////////////
100 list wasCSVToList(string csv) {
101 list l = [];
102 list s = [];
103 string m = "";
104 do {
105 string a = llGetSubString(csv, 0, 0);
106 csv = llDeleteSubString(csv, 0, 0);
107 if(a == ",") {
108 if(llList2String(s, -1) != "\"") {
109 l += m;
110 m = "";
111 jump continue;
112 }
113 m += a;
114 jump continue;
115 }
116 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
117 m += a;
118 csv = llDeleteSubString(csv, 0, 0);
119 jump continue;
120 }
121 if(a == "\"") {
122 if(llList2String(s, -1) != a) {
123 s += a;
124 jump continue;
125 }
126 s = llDeleteSubList(s, -1, -1);
127 jump continue;
128 }
129 m += a;
130 @continue;
131 } while(csv != "");
132 // postcondition: length(s) = 0
133 return l + m;
134 }
135  
136 ///////////////////////////////////////////////////////////////////////////
137 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
138 ///////////////////////////////////////////////////////////////////////////
139 string wasListToCSV(list l) {
140 list v = [];
141 do {
142 string a = llDumpList2String(
143 llParseStringKeepNulls(
144 llList2String(
145 l,
146  
147 ),
148 ["\""],
149 []
150 ),
151 "\"\""
152 );
153 if(llParseStringKeepNulls(
154 a,
155 [" ", ",", "\n", "\""], []
156 ) !=
157 (list) a
158 ) a = "\"" + a + "\"";
159 v += a;
160 l = llDeleteSubList(l, 0, 0);
161 } while(l != []);
162 return llDumpList2String(v, ",");
163 }
164  
165 ///////////////////////////////////////////////////////////////////////////
166 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
167 ///////////////////////////////////////////////////////////////////////////
168 integer wasMenuIndex = 0;
169 list wasDialogMenu(list input, list actions, string direction) {
170 integer cut = 11-wasListCountExclude(actions, [""]);
171 if(direction == ">" && (wasMenuIndex+1)*cut+wasMenuIndex+1 < llGetListLength(input)) {
172 ++wasMenuIndex;
173 jump slice;
174 }
175 if(direction == "<" && wasMenuIndex-1 >= 0) {
176 --wasMenuIndex;
177 jump slice;
178 }
179 @slice;
180 integer multiple = wasMenuIndex*cut;
181 input = llList2List(input, multiple+wasMenuIndex, multiple+cut+wasMenuIndex);
182 input = wasListMerge(input, actions, "");
183 return input;
184 }
185  
186 ///////////////////////////////////////////////////////////////////////////
187 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
188 ///////////////////////////////////////////////////////////////////////////
189 integer wasListCountExclude(list input, list exclude) {
190 if(llGetListLength(input) == 0) return 0;
191 if(llListFindList(exclude, (list)llList2String(input, 0)) == -1)
192 return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
193 return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
194 }
195  
196 ///////////////////////////////////////////////////////////////////////////
197 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
198 ///////////////////////////////////////////////////////////////////////////
199 list wasListMerge(list l, list m, string merge) {
200 if(llGetListLength(l) == 0 && llGetListLength(m) == 0) return [];
201 string a = llList2String(m, 0);
202 if(a != merge) return [ a ] + wasListMerge(l, llDeleteSubList(m, 0, 0), merge);
203 return [ llList2String(l, 0) ] + wasListMerge(llDeleteSubList(l, 0, 0), llDeleteSubList(m, 0, 0), merge);
204 }
205  
206 // for notecard reading
207 integer line = 0;
208  
209 // key-value data will be read into this list
210 list tuples = [];
211 string configuration = "";
212  
213 // URL
214 string callback = "";
215  
216 // dialog variables
217 list names = [];
218 list UUIDs = [];
219 list local = [];
220 list menu = [];
221 integer listenHandle = 0;
222  
223 // jump table
224 string autopilot_jump_state = "";
225  
226 // utility variables
227 key itemUUID = NULL_KEY;
228 vector autoPilotTarget = ZERO_VECTOR;
229  
230 // position of the cliking avatar
231 key avatarTouch = NULL_KEY;
232  
233 default {
234 state_entry() {
235 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
236 llOwnerSay("Sorry, could not find a configuration inventory notecard.");
237 return;
238 }
239 // DEBUG
240 llOwnerSay("Reading configuration file...");
241 llGetNotecardLine("configuration", line);
242 }
243 dataserver(key id, string data) {
244 if(data == EOF) {
245 // invariant, length(tuples) % 2 == 0
246 if(llGetListLength(tuples) % 2 != 0) {
247 llOwnerSay("Error in configuration notecard.");
248 return;
249 }
250 key CORRADE = llList2Key(
251 tuples,
252 llListFindList(
253 tuples,
254 [
255 "corrade"
256 ]
257 )
258 +1);
259 if(CORRADE == NULL_KEY) {
260 llOwnerSay("Error in configuration notecard: corrade");
261 return;
262 }
263 string GROUP = llList2String(
264 tuples,
265 llListFindList(
266 tuples,
267 [
268 "group"
269 ]
270 )
271 +1);
272 if(GROUP == "") {
273 llOwnerSay("Error in configuration notecard: group");
274 return;
275 }
276 string PASSWORD = llList2String(
277 tuples,
278 llListFindList(
279 tuples,
280 [
281 "password"
282 ]
283 )
284 +1);
285 if(PASSWORD == "") {
286 llOwnerSay("Error in configuration notecard: password");
287 return;
288 }
289 string VERSION = llList2String(
290 tuples,
291 llListFindList(
292 tuples,
293 [
294 "version"
295 ]
296 )
297 +1);
298 if(VERSION == "") {
299 llOwnerSay("Error in configuration notecard: version");
300 return;
301 }
302 // DEBUG
303 llOwnerSay("Read configuration notecard...");
304 configuration = wasKeyValueEncode(tuples);
305 // GC
306 tuples = [];
307  
308 autopilot_jump_state = "main";
309 state url;
310 }
311 if(data == "") jump continue;
312 integer i = llSubStringIndex(data, "#");
313 if(i != -1) data = llDeleteSubString(data, i, -1);
314 list o = llParseString2List(data, ["="], []);
315 // get rid of starting and ending quotes
316 string k = llDumpList2String(
317 llParseString2List(
318 llStringTrim(
319 llList2String(
320 o,
321  
322 ),
323 STRING_TRIM),
324 ["\""], []
325 ), "\"");
326 string v = llDumpList2String(
327 llParseString2List(
328 llStringTrim(
329 llList2String(
330 o,
331 1
332 ),
333 STRING_TRIM),
334 ["\""], []
335 ), "\"");
336 if(k == "" || v == "") jump continue;
337 tuples += k;
338 tuples += v;
339 @continue;
340 llGetNotecardLine("configuration", ++line);
341 }
342 attach(key id) {
343 llResetScript();
344 }
345 on_rez(integer num) {
346 llResetScript();
347 }
348 changed(integer change) {
349 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
350 llResetScript();
351 }
352 }
353 }
354  
355 state url {
356 state_entry() {
357 // DEBUG
358 llOwnerSay("Requesting URL...");
359 llReleaseURL(callback);
360 llRequestURL();
361 }
362 http_request(key id, string method, string body) {
363 if(method != URL_REQUEST_GRANTED) return;
364 callback = body;
365 // DEBUG
366 llOwnerSay("Got URL...");
367  
368 state main;
369 }
370 on_rez(integer num) {
371 llResetScript();
372 }
373 changed(integer change) {
374 llResetScript();
375 }
376 }
377  
378  
379 state main {
380 state_entry() {
381 llOwnerSay("Touch to select object...");
382 }
383 touch_start(integer num) {
384 // DEBUG
385 llOwnerSay("Getting objects...");
386  
387 // store the poition of the cliking avatar
388 avatarTouch = llDetectedKey(0);
389  
390 llInstantMessage(
391 wasKeyValueGet(
392 "corrade",
393 configuration
394 ),
395 wasKeyValueEncode(
396 [
397 "command", "getobjectsdata",
398 "group", wasURLEscape(
399 wasKeyValueGet(
400 "group",
401 configuration
402 )
403 ),
404 "password", wasURLEscape(
405 wasKeyValueGet(
406 "password",
407 configuration
408 )
409 ),
410 "entity", "world",
411 "range", wasURLEscape(
412 wasKeyValueGet(
413 "range",
414 configuration
415 )
416 ),
417 "data", wasListToCSV(
418 [
419 "Properties.Name",
420 "ID",
421 "Position"
422 ]
423 ),
424 "sift", wasListToCSV(
425 [
426 "take", 30
427 ]
428 ),
429 "callback", wasURLEscape(callback)
430 ]
431 )
432 );
433  
434 llSetTimerEvent(60);
435 }
436 timer() {
437 // DEBUG
438 llOwnerSay("Timeout retrieving object properties...");
439 llResetScript();
440 }
441 http_request(key id, string method, string body) {
442 llHTTPResponse(id, 200, "OK");
443  
444 // Only listen to getobjectsdata command.
445 if(wasKeyValueGet("command", body) != "getobjectsdata")
446 return;
447  
448 if(wasKeyValueGet("success", body) != "True") {
449 // DEBUG
450 llOwnerSay("Error querying primitives: " + wasKeyValueGet("error", body));
451 llResetScript();
452 }
453  
454 string dataKey = wasURLUnescape(
455 wasKeyValueGet(
456 "data",
457 body
458 )
459 );
460  
461 if(dataKey == "") {
462 // DEBUG
463 llOwnerSay("No data for scanned primitives. No primitives in range?");
464 llResetScript();
465 }
466  
467 list data = wasCSVToList(dataKey);
468 // Copy the names and UUIDs of the primitives.
469 names = [];
470 UUIDs = [];
471 local = [];
472 do {
473 string k = llList2String(data, 0);
474 data = llDeleteSubList(data, 0, 0);
475 string v = llList2String(data, 0);
476 data = llDeleteSubList(data, 0, 0);
477  
478 if(k == "Properties.Name") {
479 // Corrade may pass blank names due to SL
480 // objects not being yet discovered.
481 if(v == "") {
482 names += "Unknown";
483 jump continue;
484 }
485 names += v;
486 jump continue;
487 }
488  
489 if(k == "ID"){
490 if(v == "") {
491 UUIDs += NULL_KEY;
492 jump continue;
493 }
494 UUIDs += v;
495 jump continue;
496 }
497  
498 if(k == "Position") {
499 if(v == "") {
500 local += ZERO_VECTOR;
501 jump continue;
502 }
503 local += v;
504 jump continue;
505 }
506 @continue;
507 } while(llGetListLength(data));
508  
509 state pick;
510 }
511 on_rez(integer num) {
512 llResetScript();
513 }
514 changed(integer change) {
515 llResetScript();
516 }
517 state_exit() {
518 llSetTimerEvent(0);
519 }
520 }
521  
522 state pick {
523 state_entry() {
524 // DEBUG
525 llOwnerSay("Sending menu...");
526  
527 // trim the button labels down to 23 characters
528 menu = [];
529 integer i = 0;
530 do {
531 menu += llGetSubString(llList2String(names, i), 0, 23);
532 } while(++i < llGetListLength(names));
533  
534 // listen and send the dialog
535 integer comChannel = ((integer)("0x"+llGetSubString((string)avatarTouch,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
536 listenHandle = llListen(comChannel, "", avatarTouch, "");
537 llDialog(avatarTouch, "\nPlease choose a primitive for Corrade to sit on from the list below:\n", wasDialogMenu(menu, ["⟵ Back", "", "Next ⟶"], ""), comChannel);
538 llSetTimerEvent(60);
539 }
540 listen(integer channel, string name, key id, string message) {
541 if(message == "⟵ Back") {
542 llDialog(id, "\nPlease choose a primitive for Corrade to sit on from the list below:\n", wasDialogMenu(menu, ["⟵ Back", "", "Next ⟶"], "<"), channel);
543 return;
544 }
545 if(message == "Next ⟶") {
546 llDialog(id, "\nPlease choose a primitive for Corrade to sit on from the list below:\n", wasDialogMenu(menu, ["⟵ Back", "", "Next ⟶"], ">"), channel);
547 return;
548 }
549 integer i = llGetListLength(menu) - 1;
550 do {
551 string v = llList2String(menu, i);
552 if(llSubStringIndex(v, message) != -1)
553 jump selection;
554 } while(--i > -1);
555 // GC
556 menu = [];
557  
558 // DEBUG
559 llOwnerSay("Invalid menu item selected...");
560 llResetScript();
561 @selection;
562  
563 // DEBUG
564 llOwnerSay("Selected: " + llList2String(names, i) + "...");
565  
566 // Get the key of the object.
567 itemUUID = (key)llList2String(UUIDs, i);
568  
569 // Get the target.
570 autoPilotTarget = (vector)llList2String(local, i);
571  
572 // GC
573 menu = [];
574 names = [];
575 UUIDs = [];
576 local = [];
577  
578 // Got a menu item so bind to permission notifications and sit.
579 state bind;
580 }
581 timer() {
582 // DEBUG
583 llOwnerSay("Dialog menu timeout...");
584 llResetScript();
585 }
586 on_rez(integer num) {
587 llResetScript();
588 }
589 changed(integer change) {
590 llResetScript();
591 }
592 state_exit() {
593 llSetTimerEvent(0);
594 }
595 }
596  
597  
598 state bind {
599 state_entry() {
600 // DEBUG
601 llOwnerSay("Binding notifications...");
602  
603 llInstantMessage(
604 (key)wasKeyValueGet(
605 "corrade",
606 configuration
607 ),
608 wasKeyValueEncode(
609 [
610 "command", "notify",
611 "group", wasURLEscape(
612 wasKeyValueGet(
613 "group",
614 configuration
615 )
616 ),
617 "password", wasURLEscape(
618 wasKeyValueGet(
619 "password",
620 configuration
621 )
622 ),
623 "action", "set",
624 "type", wasListToCSV(
625 [
626 "inventory",
627 "location"
628 ]
629 ),
630 "tag", wasURLEscape(
631 wasKeyValueGet(
632 "tag",
633 configuration
634 )
635 ),
636 "URL", wasURLEscape(callback),
637 "callback", wasURLEscape(callback)
638 ]
639 )
640 );
641 llSetTimerEvent(60);
642 }
643 http_request(key id, string method, string body) {
644 llHTTPResponse(id, 200, "OK");
645  
646 if(wasKeyValueGet("command", body) != "notify")
647 return;
648  
649 if(wasKeyValueGet("success", body) != "True") {
650 // DEBUG
651 llOwnerSay("Failed to bind notifications...");
652 llResetScript();
653 }
654  
655 // DEBUG
656 llOwnerSay("Notifications installed, fetching...");
657  
658 autopilot_jump_state = "take";
659 state autopilot;
660 }
661 timer() {
662 // DEBUG
663 llOwnerSay("Timeout binding notifications...");
664 llResetScript();
665 }
666 on_rez(integer num) {
667 llResetScript();
668 }
669 changed(integer change) {
670 llResetScript();
671 }
672 state_exit() {
673 llSetTimerEvent(0);
674 }
675 }
676  
677 state autopilot {
678 state_entry() {
679 // DEBUG
680 llOwnerSay("Walking...");
681  
682 llInstantMessage(
683 (key)wasKeyValueGet(
684 "corrade",
685 configuration
686 ),
687 wasKeyValueEncode(
688 [
37 office 689 "command", "walkto",
35 office 690 "group", wasURLEscape(
691 wasKeyValueGet(
692 "group",
693 configuration
694 )
695 ),
696 "password", wasURLEscape(
697 wasKeyValueGet(
698 "password",
699 configuration
700 )
701 ),
702 "position", autoPilotTarget + wasCirclePoint(1.1),
37 office 703 "vicinity", 1.1,
704 "timeout", 60
35 office 705 ]
706 )
707 );
708  
709 llSetTimerEvent(60);
710 }
711 http_request(key id, string method, string body) {
712 llHTTPResponse(id, 200, "OK");
713  
714 // Wait for the location notification.
715 if(wasKeyValueGet("type", body) != "location")
716 return;
717  
718 // Compute the position beteen the bot and the target.
719 vector position = (vector)wasURLUnescape(
720 wasKeyValueGet(
721 "position",
722 body
723 )
724 );
725  
726 // Detect when Corrade is near.
727 if(llVecDist(position, autoPilotTarget) >
728 (float)wasURLEscape(wasKeyValueGet("scan", configuration)))
729 return;
730  
731 // DEBUG
732 llOwnerSay("Corrade has arrived...");
733  
734 // Jump table!
735 if(autopilot_jump_state == "drop")
736 state drop;
737  
738 if(autopilot_jump_state == "take")
739 state take;
740  
741 // DEBUG
742 llOwnerSay("Jump table corrupt, please contact vendor...");
743 }
744 timer() {
745 // DEBUG
746 llOwnerSay("Timeout fetching object...");
747 llResetScript();
748 }
749 on_rez(integer num) {
750 llResetScript();
751 }
752 changed(integer change) {
753 llResetScript();
754 }
755 state_exit() {
756 llSetTimerEvent(0);
757 }
758 }
759  
760 state take {
761 state_entry() {
762 // DEBUG
763 llOwnerSay("Taking to inventory...");
764  
765 llInstantMessage(
766 (key)wasKeyValueGet(
767 "corrade",
768 configuration
769 ),
770 wasKeyValueEncode(
771 [
772 "command", "derez",
773 "group", wasURLEscape(
774 wasKeyValueGet(
775 "group",
776 configuration
777 )
778 ),
779 "password", wasURLEscape(
780 wasKeyValueGet(
781 "password",
782 configuration
783 )
784 ),
785 "item", itemUUID,
786 "type", "AgentInventoryTake",
787 "range", "5"
788 ]
789 )
790 );
791  
792 llSetTimerEvent(60);
793 }
794 http_request(key id, string method, string body) {
795 llHTTPResponse(id, 200, "OK");
796  
797 // wait for inventory notification.
798 if(wasKeyValueGet("type", body) != "inventory")
799 return;
800  
801 // item taken to inventory implies the create action
802 if(wasKeyValueGet("action", body) != "created")
803 return;
804  
805 itemUUID = (key) wasURLUnescape(
806 wasKeyValueGet(
807 "inventory",
808 body
809 )
810 );
811  
812 // DEBUG
813 llOwnerSay("Retrieved object as inventory UUID: " + (string)itemUUID);
814  
815 state wear;
816 }
817 timer() {
818 // DEBUG
819 llOwnerSay("Timeout taking object to inventory...");
820 llResetScript();
821 }
822 on_rez(integer num) {
823 llResetScript();
824 }
825 changed(integer change) {
826 llResetScript();
827 }
828 state_exit() {
829 llSetTimerEvent(0);
830 }
831 }
832  
833 state wear {
834 state_entry() {
835 // DEBUG
836 llOwnerSay("Wearing...");
837  
838 llInstantMessage(
839 (key)wasKeyValueGet(
840 "corrade",
841 configuration
842 ),
843 wasKeyValueEncode(
844 [
845 "command", "attach",
846 "group", wasURLEscape(
847 wasKeyValueGet(
848 "group",
849 configuration
850 )
851 ),
852 "password", wasURLEscape(
853 wasKeyValueGet(
854 "password",
855 configuration
856 )
857 ),
858 "attachments", wasListToCSV(
859 [
860 wasURLEscape(
861 wasKeyValueGet(
862 "attachPoint",
863 configuration
864 )
865 ), itemUUID
866 ]
867 ),
868 "callback", wasURLEscape(callback)
869 ]
870 )
871 );
872  
873 llSetTimerEvent(60);
874 }
875 http_request(key id, string method, string body) {
876 llHTTPResponse(id, 200, "OK");
877  
878 if(wasKeyValueGet("command", body) != "attach")
879 return;
880  
881 if(wasKeyValueGet("success", body) != "True") {
882 // DEBUG
883 llOwnerSay("Unable to attach item: " + wasKeyValueGet("error", body));
884 llResetScript();
885 }
886  
887 // DEBUG
888 llOwnerSay("Item attached, returning...");
889  
890 // set the new target to the position of the avatar
891 autoPilotTarget = (vector)llList2String(
892 llGetObjectDetails(
893 avatarTouch,
894 [
895 OBJECT_POS
896 ]
897 ),
898  
899 );
900 autopilot_jump_state = "drop";
901 state autopilot;
902 }
903 timer() {
904 // DEBUG
905 llOwnerSay("Timeout taking object to inventory...");
906 llResetScript();
907 }
908 on_rez(integer num) {
909 llResetScript();
910 }
911 changed(integer change) {
912 llResetScript();
913 }
914 state_exit() {
915 llSetTimerEvent(0);
916 }
917 }
918  
919 state drop {
920 state_entry() {
921 // DEBUG
922 llOwnerSay("Dropping...");
923  
924 llInstantMessage(
925 (key)wasKeyValueGet(
926 "corrade",
927 configuration
928 ),
929 wasKeyValueEncode(
930 [
931 "command", "dropobject",
932 "group", wasURLEscape(
933 wasKeyValueGet(
934 "group",
935 configuration
936 )
937 ),
938 "password", wasURLEscape(
939 wasKeyValueGet(
940 "password",
941 configuration
942 )
943 ),
944 "type", "UUID",
945 "item", wasURLEscape(itemUUID),
946 "callback", wasURLEscape(callback)
947 ]
948 )
949 );
950  
951 llSetTimerEvent(60);
952 }
953 http_request(key id, string method, string body) {
954 llHTTPResponse(id, 200, "OK");
955  
956 if(wasKeyValueGet("command", body) != "dropobject")
957 return;
958  
959 if(wasKeyValueGet("success", body) != "True") {
960 // DEBUG
961 llOwnerSay("Could not drop object: " + wasURLUnescape(body));
962 llResetScript();
963 }
964  
965 // DEBUG
966 llOwnerSay("Item dropped...");
967  
968 state unbind;
969 }
970 timer() {
971 // DEBUG
972 llOwnerSay("Timeout dropping object...");
973 llResetScript();
974 }
975 on_rez(integer num) {
976 llResetScript();
977 }
978 changed(integer change) {
979 llResetScript();
980 }
981 state_exit() {
982 llSetTimerEvent(0);
983 }
984 }
985  
986 state unbind {
987 state_entry() {
988 // DEBUG
989 llOwnerSay("Unbinding notifications...");
990  
991 llInstantMessage(
992 (key)wasKeyValueGet(
993 "corrade",
994 configuration
995 ),
996 wasKeyValueEncode(
997 [
998 "command", "notify",
999 "group", wasURLEscape(
1000 wasKeyValueGet(
1001 "group",
1002 configuration
1003 )
1004 ),
1005 "password", wasURLEscape(
1006 wasKeyValueGet(
1007 "password",
1008 configuration
1009 )
1010 ),
1011 "action", "remove",
1012 "tag", wasURLEscape(
1013 wasKeyValueGet(
1014 "tag",
1015 configuration
1016 )
1017 ),
1018 "URL", wasURLEscape(callback),
1019 "callback", wasURLEscape(callback)
1020 ]
1021 )
1022 );
1023  
1024 llSetTimerEvent(60);
1025 }
1026 http_request(key id, string method, string body) {
1027 llHTTPResponse(id, 200, "OK");
1028  
1029 if(wasKeyValueGet("command", body) != "notify")
1030 return;
1031  
1032 if(wasKeyValueGet("success", body) != "True") {
1033 // DEBUG
1034 llOwnerSay("Failed to unbind notifications...");
1035 llResetScript();
1036 }
1037  
1038 // DEBUG
1039 llOwnerSay("Notifications uninstalled...");
1040  
1041 llResetScript();
1042 }
1043 timer() {
1044 // DEBUG
1045 llOwnerSay("Timeout binding notifications...");
1046 llResetScript();
1047 }
1048 on_rez(integer num) {
1049 llResetScript();
1050 }
1051 changed(integer change) {
1052 llResetScript();
1053 }
1054 state_exit() {
1055 llSetTimerEvent(0);
1056 }
37 office 1057 }