corrade-lsl-templates – Blame information for rev 42

Subversion Repositories:
Rev:
Rev Author Line No. Line
11 office 1 ///////////////////////////////////////////////////////////////////////////
42 office 2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
11 office 3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // A MOTD module for Corrade Eggdrop.
6 //
7 ///////////////////////////////////////////////////////////////////////////
42 office 8  
11 office 9 ///////////////////////////////////////////////////////////////////////////
41 office 10 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
11 office 11 ///////////////////////////////////////////////////////////////////////////
12 string wasKeyValueGet(string k, string data) {
13 if(llStringLength(data) == 0) return "";
14 if(llStringLength(k) == 0) return "";
41 office 15 list a = llParseStringKeepNulls(data, ["&", "="], []);
16 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
17 if(i != -1) return llList2String(a, 2*i+1);
11 office 18 return "";
19 }
42 office 20  
11 office 21 ///////////////////////////////////////////////////////////////////////////
42 office 22 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
11 office 23 ///////////////////////////////////////////////////////////////////////////
24 string wasKeyValueEncode(list data) {
25 list k = llList2ListStrided(data, 0, -1, 2);
26 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
27 data = [];
28 do {
29 data += llList2String(k, 0) + "=" + llList2String(v, 0);
30 k = llDeleteSubList(k, 0, 0);
31 v = llDeleteSubList(v, 0, 0);
32 } while(llGetListLength(k) != 0);
33 return llDumpList2String(data, "&");
34 }
42 office 35  
11 office 36 ///////////////////////////////////////////////////////////////////////////
42 office 37 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
11 office 38 ///////////////////////////////////////////////////////////////////////////
39 // http://was.fm/secondlife/wanderer
40 vector wasCirclePoint(float radius) {
41 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
42 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
43 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
44 return <x, y, 0>;
45 return wasCirclePoint(radius);
46 }
42 office 47  
11 office 48 ///////////////////////////////////////////////////////////////////////////
42 office 49 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
11 office 50 ///////////////////////////////////////////////////////////////////////////
51 // escapes a string in conformance with RFC1738
52 string wasURLEscape(string i) {
53 string o = "";
54 do {
55 string c = llGetSubString(i, 0, 0);
56 i = llDeleteSubString(i, 0, 0);
57 if(c == "") jump continue;
58 if(c == " ") {
59 o += "+";
60 jump continue;
61 }
62 if(c == "\n") {
63 o += "%0D" + llEscapeURL(c);
64 jump continue;
65 }
66 o += llEscapeURL(c);
67 @continue;
68 } while(i != "");
69 return o;
70 }
42 office 71  
11 office 72 ///////////////////////////////////////////////////////////////////////////
42 office 73 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
11 office 74 ///////////////////////////////////////////////////////////////////////////
75 list wasCSVToList(string csv) {
76 list l = [];
77 list s = [];
78 string m = "";
79 do {
80 string a = llGetSubString(csv, 0, 0);
81 csv = llDeleteSubString(csv, 0, 0);
82 if(a == ",") {
83 if(llList2String(s, -1) != "\"") {
84 l += m;
85 m = "";
86 jump continue;
87 }
88 m += a;
89 jump continue;
90 }
91 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
92 m += a;
93 csv = llDeleteSubString(csv, 0, 0);
94 jump continue;
95 }
96 if(a == "\"") {
97 if(llList2String(s, -1) != a) {
98 s += a;
99 jump continue;
100 }
101 s = llDeleteSubList(s, -1, -1);
102 jump continue;
103 }
104 m += a;
105 @continue;
106 } while(csv != "");
107 // postcondition: length(s) = 0
108 return l + m;
109 }
42 office 110  
11 office 111 ///////////////////////////////////////////////////////////////////////////
42 office 112 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
11 office 113 ///////////////////////////////////////////////////////////////////////////
114 string wasListToCSV(list l) {
115 list v = [];
116 do {
117 string a = llDumpList2String(
118 llParseStringKeepNulls(
119 llList2String(
42 office 120 l,
11 office 121  
42 office 122 ),
123 ["\""],
11 office 124 []
125 ),
126 "\"\""
127 );
128 if(llParseStringKeepNulls(
42 office 129 a,
11 office 130 [" ", ",", "\n", "\""], []
42 office 131 ) !=
11 office 132 (list) a
133 ) a = "\"" + a + "\"";
134 v += a;
135 l = llDeleteSubList(l, 0, 0);
136 } while(l != []);
137 return llDumpList2String(v, ",");
138 }
42 office 139  
11 office 140 ///////////////////////////////////////////////////////////////////////////
42 office 141 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
11 office 142 ///////////////////////////////////////////////////////////////////////////
143 // unescapes a string in conformance with RFC1738
144 string wasURLUnescape(string i) {
145 return llUnescapeURL(
146 llDumpList2String(
147 llParseString2List(
148 llDumpList2String(
149 llParseString2List(
42 office 150 i,
151 ["+"],
11 office 152 []
42 office 153 ),
11 office 154 " "
42 office 155 ),
156 ["%0D%0A"],
11 office 157 []
42 office 158 ),
11 office 159 "\n"
160 )
161 );
162 }
42 office 163  
11 office 164 // configuration data
165 string configuration = "";
166 // store message over state.
167 string firstname = "";
168 string lastname = "";
169 string group = "";
170 string data = "";
171 string jump_state = "";
42 office 172 integer membershipFee;
173  
11 office 174 default {
175 state_entry() {
176 llOwnerSay("[MOTD] Starting module...");
177 llSetTimerEvent(10);
178 }
179 link_message(integer sender, integer num, string message, key id) {
180 if(id != "configuration") return;
181 llOwnerSay("[MOTD] Got configuration...");
182 configuration = message;
183 jump_state = "create_database";
42 office 184 state trampoline;
11 office 185 }
186 timer() {
187 llOwnerSay("[MOTD] Requesting configuration...");
188 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
189 }
190 on_rez(integer num) {
191 llResetScript();
192 }
193 changed(integer change) {
42 office 194 if((change & CHANGED_INVENTORY) ||
195 (change & CHANGED_REGION_START) ||
11 office 196 (change & CHANGED_OWNER)) {
197 llResetScript();
198 }
199 }
200 state_exit() {
201 llSetTimerEvent(0);
202 }
203 }
42 office 204  
205 state trampoline {
11 office 206 state_entry() {
207 if(jump_state == "create_database")
208 state create_database;
209 if(jump_state == "greet")
210 state greet;
211 if(jump_state == "get")
212 state get;
213 if(jump_state == "set")
214 state set;
42 office 215 if(jump_state == "fee")
216 state fee;
217 if(jump_state == "pay")
218 state pay;
11 office 219 if(jump_state == "listen_group")
220 state listen_group;
42 office 221  
11 office 222 // DEBUG
223 llOwnerSay("[MOTD] Jump table corrupted, please contact creator...");
224 llResetScript();
225 }
226 on_rez(integer num) {
227 llResetScript();
228 }
229 changed(integer change) {
42 office 230 if((change & CHANGED_INVENTORY) ||
231 (change & CHANGED_REGION_START) ||
11 office 232 (change & CHANGED_OWNER)) {
233 llResetScript();
234 }
235 }
236 }
42 office 237  
11 office 238 state create_database {
239 state_entry() {
240 // DEBUG
24 office 241 llOwnerSay("[MOTD] Creating database: " + wasKeyValueGet("motd table", configuration));
11 office 242 llInstantMessage(
243 wasKeyValueGet(
42 office 244 "corrade",
11 office 245 configuration
42 office 246 ),
11 office 247 wasKeyValueEncode(
248 [
249 "command", "database",
250 "group", wasURLEscape(
251 wasKeyValueGet(
42 office 252 "group",
11 office 253 configuration
254 )
255 ),
256 "password", wasURLEscape(
257 wasKeyValueGet(
42 office 258 "password",
11 office 259 configuration
260 )
261 ),
42 office 262 "SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS \"" +
263 wasKeyValueGet("motd table", configuration) +
11 office 264 "\" (name text unique collate nocase, data text)"),
42 office 265 "callback", wasURLEscape(
266 wasKeyValueGet(
267 "URL",
268 configuration
269 )
270 )
11 office 271 ]
272 )
273 );
274 llSetTimerEvent(60);
275 }
42 office 276 link_message(integer sender, integer num, string body, key id) {
277 // Only process callbacks for the database command.
278 if(id != "callback" || wasKeyValueGet("command", body) != "database")
279 return;
280  
281 if(wasKeyValueGet("success", body) != "True") {
11 office 282 // DEBUG
42 office 283 llOwnerSay("[MOTD] Unable modify database: " +
11 office 284 wasURLUnescape(
285 wasKeyValueGet("error", body)
42 office 286 ) +
287 " " +
24 office 288 wasURLUnescape(
289 wasKeyValueGet("data", body)
11 office 290 )
42 office 291  
11 office 292 );
293 llResetScript();
294 }
295 llOwnerSay("[MOTD] Database created!");
296 state listen_group;
297 }
298 timer() {
299 state listen_group;
300 }
301 on_rez(integer num) {
302 llResetScript();
303 }
304 changed(integer change) {
42 office 305 if((change & CHANGED_INVENTORY) ||
306 (change & CHANGED_REGION_START) ||
11 office 307 (change & CHANGED_OWNER)) {
308 llResetScript();
309 }
310 }
311 state_exit() {
312 llSetTimerEvent(0);
313 }
314 }
42 office 315  
316  
11 office 317 state listen_group {
318 state_entry() {
319 // DEBUG
320 llOwnerSay("[MOTD] Waiting for group messages and new group members.");
321 }
322 link_message(integer sender, integer num, string message, key id) {
323 // We only care about notifications now.
324 if(id != "notification")
325 return;
42 office 326  
11 office 327 // Get the group.
328 group = wasURLUnescape(
329 wasKeyValueGet(
330 "group",
331 message
332 )
333 );
42 office 334  
335 // This script only processes group and membership notifications.
336 // Esnure that the notification is meant for the configured group.
337 if((wasKeyValueGet("type", message) != "membership" && wasKeyValueGet("type", message) != "group") ||
338 ((wasKeyValueGet("type", message) == "membership" || wasKeyValueGet("type", message) == "group") &&
339 wasURLUnescape(wasKeyValueGet("group", message)) !=
340 wasKeyValueGet("group", configuration)))
341 return;
342  
11 office 343 // Retrieve the membership notification.
344 if(wasKeyValueGet("type", message) == "membership" &&
345 wasKeyValueGet("action", message) == "joined") {
346 firstname = wasURLUnescape(
347 wasKeyValueGet(
348 "firstname",
349 message
350 )
351 );
352 lastname = wasURLUnescape(
353 wasKeyValueGet(
354 "lastname",
355 message
356 )
357 );
42 office 358  
359 if(wasKeyValueGet("pay back", configuration) != "true") {
360 jump_state = "greet";
361 state trampoline;
362 }
363  
364 jump_state = "fee";
365 state trampoline;
11 office 366 }
42 office 367  
11 office 368 // Get the sent message.
369 data = wasURLUnescape(
370 wasKeyValueGet(
42 office 371 "message",
11 office 372 message
373 )
374 );
42 office 375  
11 office 376 // Check if this is an eggdrop command.
42 office 377 if(llGetSubString(data, 0, 0) !=
11 office 378 wasKeyValueGet("command", configuration))
379 return;
42 office 380  
11 office 381 // Check if the command matches the current module.
15 office 382 list command = llParseString2List(data, [" "], []);
42 office 383 if(llList2String(command, 0) !=
15 office 384 wasKeyValueGet("command", configuration) + "motd")
11 office 385 return;
42 office 386  
11 office 387 // Remove command.
388 command = llDeleteSubList(command, 0, 0);
42 office 389  
11 office 390 // Dump the rest of the message.
391 data = llDumpList2String(command, " ");
42 office 392  
393 // DEBUG
394 //llOwnerSay("Remaining data: " + data);
395  
11 office 396 // Get the sent message.
397 if(data == "") {
398 jump_state = "get";
42 office 399 state trampoline;
11 office 400 }
42 office 401  
402 data = wasURLEscape(data);
11 office 403 jump_state = "set";
42 office 404 state trampoline;
11 office 405 }
406 on_rez(integer num) {
407 llResetScript();
408 }
409 changed(integer change) {
42 office 410 if((change & CHANGED_INVENTORY) ||
411 (change & CHANGED_REGION_START) ||
11 office 412 (change & CHANGED_OWNER)) {
413 llResetScript();
414 }
415 }
416 }
42 office 417  
11 office 418 state greet {
419 state_entry() {
420 // DEBUG
42 office 421 llOwnerSay("[MOTD] Retrieving MOTD...");
11 office 422 llInstantMessage(
423 wasKeyValueGet(
42 office 424 "corrade",
11 office 425 configuration
42 office 426 ),
11 office 427 wasKeyValueEncode(
428 [
429 "command", "database",
430 "group", wasURLEscape(
431 wasKeyValueGet(
42 office 432 "group",
11 office 433 configuration
434 )
435 ),
436 "password", wasURLEscape(
437 wasKeyValueGet(
42 office 438 "password",
11 office 439 configuration
440 )
441 ),
442 "SQL", wasURLEscape("SELECT data FROM \"" +
42 office 443 wasKeyValueGet("motd table", configuration) +
11 office 444 "\" WHERE name=:group"),
445 "data", wasURLEscape(
446 wasListToCSV(
447 [
448 "group",
449 wasURLEscape(group)
450 ]
451 )
452 ),
42 office 453 "callback", wasURLEscape(
454 wasKeyValueGet(
455 "URL",
456 configuration
457 )
458 )
11 office 459 ]
460 )
461 );
462 llSetTimerEvent(60);
463 }
42 office 464 link_message(integer sender, integer num, string body, key id) {
465 // Only process callbacks for the database command.
466 if(id != "callback" || wasKeyValueGet("command", body) != "database")
467 return;
468  
469 if(wasKeyValueGet("success", body) != "True") {
11 office 470 // DEBUG
42 office 471 llOwnerSay("[MOTD] Unable retrieve from database: " +
11 office 472 wasURLUnescape(
473 wasKeyValueGet("error", body)
474 )
475 );
476 state listen_group;
477 }
42 office 478  
11 office 479 data = llDumpList2String(
480 llDeleteSubList(
481 wasCSVToList(
482 wasURLUnescape(
483 wasKeyValueGet("data", body)
484 )
485 ),
486 0,
487  
488 ),
489 ""
490 );
42 office 491  
11 office 492 if(data == "")
493 state listen_group;
42 office 494  
11 office 495 data = "Hello " + firstname + " " + lastname + "!" + " " + data;
496 state tell;
497 }
498 timer() {
499 state listen_group;
500 }
501 on_rez(integer num) {
502 llResetScript();
503 }
504 changed(integer change) {
42 office 505 if((change & CHANGED_INVENTORY) ||
506 (change & CHANGED_REGION_START) ||
11 office 507 (change & CHANGED_OWNER)) {
508 llResetScript();
509 }
510 }
511 state_exit() {
512 llSetTimerEvent(0);
513 }
514 }
42 office 515  
11 office 516 state get {
517 state_entry() {
518 // DEBUG
519 llOwnerSay("[MOTD] Retrieving from database.");
520 llInstantMessage(
521 wasKeyValueGet(
42 office 522 "corrade",
11 office 523 configuration
42 office 524 ),
11 office 525 wasKeyValueEncode(
526 [
527 "command", "database",
528 "group", wasURLEscape(
529 wasKeyValueGet(
42 office 530 "group",
11 office 531 configuration
532 )
533 ),
534 "password", wasURLEscape(
535 wasKeyValueGet(
42 office 536 "password",
11 office 537 configuration
538 )
539 ),
540 "SQL", wasURLEscape("SELECT data FROM \"" +
42 office 541 wasKeyValueGet("motd table", configuration) +
11 office 542 "\" WHERE name=:group"),
543 "data", wasURLEscape(
544 wasListToCSV(
545 [
546 "group",
24 office 547 wasURLEscape(
548 wasKeyValueGet(
42 office 549 "group",
24 office 550 configuration
551 )
552 )
11 office 553 ]
554 )
555 ),
42 office 556 "callback", wasURLEscape(
557 wasKeyValueGet(
558 "URL",
559 configuration
560 )
561 )
11 office 562 ]
563 )
564 );
565 llSetTimerEvent(60);
566 }
42 office 567 link_message(integer sender, integer num, string body, key id) {
568 // Only process callbacks for the database command.
569 if(id != "callback" || wasKeyValueGet("command", body) != "database")
570 return;
571  
572 if(wasKeyValueGet("success", body) != "True") {
11 office 573 // DEBUG
42 office 574 llOwnerSay("[MOTD] Unable retrieve from database: " +
11 office 575 wasURLUnescape(
576 wasKeyValueGet("error", body)
577 )
578 );
579 state listen_group;
580 }
42 office 581  
11 office 582 data = llDumpList2String(
583 llDeleteSubList(
584 wasCSVToList(
585 wasURLUnescape(
586 wasKeyValueGet("data", body)
587 )
588 ),
589 0,
590  
591 ),
592 ""
593 );
42 office 594  
11 office 595 if(data == "") {
596 data = "Sorry, no MOTD is currently set.";
597 state tell;
598 }
42 office 599  
11 office 600 state tell;
601 }
602 timer() {
603 state listen_group;
604 }
605 on_rez(integer num) {
606 llResetScript();
607 }
608 changed(integer change) {
42 office 609 if((change & CHANGED_INVENTORY) ||
610 (change & CHANGED_REGION_START) ||
11 office 611 (change & CHANGED_OWNER)) {
612 llResetScript();
613 }
614 }
615 state_exit() {
616 llSetTimerEvent(0);
617 }
618 }
42 office 619  
620 state fee {
621 state_entry() {
622 // DEBUG
623 llOwnerSay("[MOTD] Member joined, getting group membership fee...");
624 llInstantMessage(
625 wasKeyValueGet(
626 "corrade",
627 configuration
628 ),
629 wasKeyValueEncode(
630 [
631 "command", "getgroupdata",
632 "group", wasURLEscape(
633 wasKeyValueGet(
634 "group",
635 configuration
636 )
637 ),
638 "password", wasURLEscape(
639 wasKeyValueGet(
640 "password",
641 configuration
642 )
643 ),
644 "data", "MembershipFee",
645 "callback", wasURLEscape(
646 wasKeyValueGet(
647 "URL",
648 configuration
649 )
650 )
651 ]
652 )
653 );
654 llSetTimerEvent(60);
655 }
656 link_message(integer sender, integer num, string body, key id) {
657 // Only process callbacks for the database command.
658 if(id != "callback" || wasKeyValueGet("command", body) != "getgroupdata")
659 return;
660  
661 if(wasKeyValueGet("success", body) != "True") {
662 // DEBUG
663 llOwnerSay("[MOTD] Unable to get group data: " +
664 wasURLUnescape(
665 wasKeyValueGet("error", body)
666 )
667 );
668 state listen_group;
669 }
670  
671 list membership = wasCSVToList(
672 wasURLUnescape(
673 wasKeyValueGet(
674 "data",
675 body
676 )
677 )
678 );
679  
680 membershipFee = llList2Integer(
681 membership,
682 llListFindList(
683 membership,
684 [ "MembershipFee" ]
685 ) + 1
686 );
687  
688 if(membershipFee <= 0) {
689 // DEBUG
690 llOwnerSay("The configured group does not have a membership fee!");
691 state listen_group;
692 }
693  
694 jump_state = "pay";
695 state trampoline;
696 }
697 timer() {
698 state listen_group;
699 }
700 on_rez(integer num) {
701 llResetScript();
702 }
703 changed(integer change) {
704 if((change & CHANGED_INVENTORY) ||
705 (change & CHANGED_REGION_START) ||
706 (change & CHANGED_OWNER)) {
707 llResetScript();
708 }
709 }
710 state_exit() {
711 llSetTimerEvent(0);
712 }
713 }
714  
715 state pay {
716 state_entry() {
717 // DEBUG
718 llOwnerSay("[MOTD] Paying back the entrance fee...");
719 llInstantMessage(
720 wasKeyValueGet(
721 "corrade",
722 configuration
723 ),
724 wasKeyValueEncode(
725 [
726 "command", "pay",
727 "group", wasURLEscape(
728 wasKeyValueGet(
729 "group",
730 configuration
731 )
732 ),
733 "password", wasURLEscape(
734 wasKeyValueGet(
735 "password",
736 configuration
737 )
738 ),
739 "amount", membershipFee,
740 "entity", "avatar",
741 "firstname", wasURLEscape(firstname),
742 "lastname", wasURLEscape(lastname),
743 "callback", wasURLEscape(
744 wasKeyValueGet(
745 "URL",
746 configuration
747 )
748 )
749 ]
750 )
751 );
752 llSetTimerEvent(60);
753 }
754 link_message(integer sender, integer num, string body, key id) {
755 // Only process callbacks for the database command.
756 if(id != "callback" || wasKeyValueGet("command", body) != "pay")
757 return;
758  
759 if(wasKeyValueGet("success", body) != "True") {
760 // DEBUG
761 llOwnerSay("[MOTD] Unable to pay the entrance fee: " +
762 wasURLUnescape(
763 wasKeyValueGet("error", body)
764 )
765 );
766 state listen_group;
767 }
768  
769 // DEBUG
770 llOwnerSay("[MOTD] Paid back the entrance fee.");
771  
772 jump_state = "greet";
773 state trampoline;
774 }
775 timer() {
776 state listen_group;
777 }
778 on_rez(integer num) {
779 llResetScript();
780 }
781 changed(integer change) {
782 if((change & CHANGED_INVENTORY) ||
783 (change & CHANGED_REGION_START) ||
784 (change & CHANGED_OWNER)) {
785 llResetScript();
786 }
787 }
788 state_exit() {
789 llSetTimerEvent(0);
790 }
791 }
792  
11 office 793 state set {
794 state_entry() {
795 // DEBUG
42 office 796 llOwnerSay("[MOTD] Adding to database...");
11 office 797 llInstantMessage(
798 wasKeyValueGet(
42 office 799 "corrade",
11 office 800 configuration
42 office 801 ),
11 office 802 wasKeyValueEncode(
803 [
804 "command", "database",
805 "group", wasURLEscape(
806 wasKeyValueGet(
42 office 807 "group",
11 office 808 configuration
809 )
810 ),
811 "password", wasURLEscape(
812 wasKeyValueGet(
42 office 813 "password",
11 office 814 configuration
815 )
816 ),
817 "SQL", wasURLEscape("REPLACE INTO \"" +
42 office 818 wasKeyValueGet("motd table", configuration) +
819 "\" (name, data) VALUES (:group, :message)"),
11 office 820 "data", wasURLEscape(
821 wasListToCSV(
822 [
42 office 823 "group",
24 office 824 wasURLEscape(
825 wasKeyValueGet(
42 office 826 "group",
24 office 827 configuration
828 )
829 ),
42 office 830 "message",
831 data
11 office 832 ]
833 )
834 ),
42 office 835 "callback", wasURLEscape(
836 wasKeyValueGet(
837 "URL",
838 configuration
839 )
840 )
11 office 841 ]
842 )
843 );
844 llSetTimerEvent(60);
845 }
42 office 846 link_message(integer sender, integer num, string body, key id) {
847 // Only process callbacks for the database command.
848 if(id != "callback" || wasKeyValueGet("command", body) != "database")
849 return;
850  
851 if(wasKeyValueGet("success", body) != "True") {
11 office 852 // DEBUG
42 office 853 llOwnerSay("[MOTD] Unable modify database: " +
11 office 854 wasURLUnescape(
855 wasKeyValueGet("error", body)
856 )
857 );
858 state listen_group;
859 }
860 data = "Saved";
861 state tell;
862 }
863 timer() {
864 state listen_group;
865 }
866 on_rez(integer num) {
867 llResetScript();
868 }
869 changed(integer change) {
42 office 870 if((change & CHANGED_INVENTORY) ||
871 (change & CHANGED_REGION_START) ||
11 office 872 (change & CHANGED_OWNER)) {
873 llResetScript();
874 }
875 }
876 state_exit() {
877 llSetTimerEvent(0);
878 }
879 }
42 office 880  
11 office 881 state tell {
882 state_entry() {
883 // DEBUG
884 llOwnerSay("[MOTD] Sending to group.");
885 llInstantMessage(
886 wasKeyValueGet(
42 office 887 "corrade",
11 office 888 configuration
42 office 889 ),
11 office 890 wasKeyValueEncode(
891 [
892 "command", "tell",
893 "group", wasURLEscape(
894 wasKeyValueGet(
42 office 895 "group",
11 office 896 configuration
897 )
898 ),
899 "password", wasURLEscape(
900 wasKeyValueGet(
42 office 901 "password",
11 office 902 configuration
903 )
904 ),
905 "entity", "group",
906 "message", wasURLEscape(data)
907 ]
908 )
909 );
910 state listen_group;
911 }
912 }