corrade-lsl-templates – Blame information for rev 15

Subversion Repositories:
Rev:
Rev Author Line No. Line
11 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // A MOTD module for Corrade Eggdrop.
6 //
7 ///////////////////////////////////////////////////////////////////////////
8  
9 ///////////////////////////////////////////////////////////////////////////
10 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
11 ///////////////////////////////////////////////////////////////////////////
12 string wasKeyValueGet(string k, string data) {
13 if(llStringLength(data) == 0) return "";
14 if(llStringLength(k) == 0) return "";
15 list a = llParseString2List(data, ["&", "="], []);
16 integer i = llListFindList(a, [ k ]);
17 if(i != -1) return llList2String(a, i+1);
18 return "";
19 }
20  
21 ///////////////////////////////////////////////////////////////////////////
22 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
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 }
35  
36 ///////////////////////////////////////////////////////////////////////////
37 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
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 }
47  
48 ///////////////////////////////////////////////////////////////////////////
49 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
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 }
71  
72 ///////////////////////////////////////////////////////////////////////////
73 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
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 }
110  
111 ///////////////////////////////////////////////////////////////////////////
112 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
113 ///////////////////////////////////////////////////////////////////////////
114 string wasListToCSV(list l) {
115 list v = [];
116 do {
117 string a = llDumpList2String(
118 llParseStringKeepNulls(
119 llList2String(
120 l,
121  
122 ),
123 ["\""],
124 []
125 ),
126 "\"\""
127 );
128 if(llParseStringKeepNulls(
129 a,
130 [" ", ",", "\n", "\""], []
131 ) !=
132 (list) a
133 ) a = "\"" + a + "\"";
134 v += a;
135 l = llDeleteSubList(l, 0, 0);
136 } while(l != []);
137 return llDumpList2String(v, ",");
138 }
139  
140 ///////////////////////////////////////////////////////////////////////////
141 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
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(
150 i,
151 ["+"],
152 []
153 ),
154 " "
155 ),
156 ["%0D%0A"],
157 []
158 ),
159 "\n"
160 )
161 );
162 }
163  
164 // configuration data
165 string configuration = "";
166 // callback URL
167 string URL = "";
168 // store message over state.
169 string firstname = "";
170 string lastname = "";
171 string group = "";
172 string data = "";
173 string jump_state = "";
174  
175 default {
176 state_entry() {
177 llOwnerSay("[MOTD] Starting module...");
178 llSetTimerEvent(10);
179 }
180 link_message(integer sender, integer num, string message, key id) {
181 if(id != "configuration") return;
182 llOwnerSay("[MOTD] Got configuration...");
183 configuration = message;
184 jump_state = "create_database";
185 state url;
186 }
187 timer() {
188 llOwnerSay("[MOTD] Requesting configuration...");
189 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
190 }
191 on_rez(integer num) {
192 llResetScript();
193 }
194 changed(integer change) {
195 if((change & CHANGED_INVENTORY) ||
196 (change & CHANGED_REGION_START) ||
197 (change & CHANGED_OWNER)) {
198 llResetScript();
199 }
200 }
201 state_exit() {
202 llSetTimerEvent(0);
203 }
204 }
205  
206 state url {
207 state_entry() {
208 // DEBUG
209 llOwnerSay("[MOTD] Requesting URL...");
210 llRequestURL();
211 }
212 http_request(key id, string method, string body) {
213 if(method != URL_REQUEST_GRANTED) return;
214 URL = body;
215 // DEBUG
216 llOwnerSay("[MOTD] Got URL...");
217 if(jump_state == "create_database")
218 state create_database;
219 if(jump_state == "greet")
220 state greet;
221 if(jump_state == "get")
222 state get;
223 if(jump_state == "set")
224 state set;
225 if(jump_state == "listen_group")
226 state listen_group;
227  
228 // DEBUG
229 llOwnerSay("[MOTD] Jump table corrupted, please contact creator...");
230 llResetScript();
231 }
232 on_rez(integer num) {
233 llResetScript();
234 }
235 changed(integer change) {
236 if((change & CHANGED_INVENTORY) ||
237 (change & CHANGED_REGION_START) ||
238 (change & CHANGED_OWNER)) {
239 llResetScript();
240 }
241 }
242 }
243  
244 state create_database {
245 state_entry() {
246 // DEBUG
247 llOwnerSay("[MOTD] Creating database.");
248 llInstantMessage(
249 wasKeyValueGet(
250 "corrade",
251 configuration
252 ),
253 wasKeyValueEncode(
254 [
255 "command", "database",
256 "group", wasURLEscape(
257 wasKeyValueGet(
258 "group",
259 configuration
260 )
261 ),
262 "password", wasURLEscape(
263 wasKeyValueGet(
264 "password",
265 configuration
266 )
267 ),
268 "SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS \"" +
269 wasKeyValueGet("motd table", configuration) +
270 "\" (name text unique collate nocase, data text)"),
271 "callback", wasURLEscape(URL)
272 ]
273 )
274 );
275 llSetTimerEvent(60);
276 }
277 http_request(key id, string method, string body) {
278 llHTTPResponse(id, 200, "OK");
279 llReleaseURL(URL);
280 if(wasKeyValueGet("command", body) != "database" ||
281 wasKeyValueGet("success", body) != "True") {
282 // DEBUG
283 llOwnerSay("[MOTD] Unable modify database: " +
284 wasURLUnescape(
285 wasKeyValueGet("error", body)
286 )
287 );
288 llResetScript();
289 }
290 llOwnerSay("[MOTD] Database created!");
291 state listen_group;
292 }
293 timer() {
294 llReleaseURL(URL);
295 state listen_group;
296 }
297 on_rez(integer num) {
298 llResetScript();
299 }
300 changed(integer change) {
301 if((change & CHANGED_INVENTORY) ||
302 (change & CHANGED_REGION_START) ||
303 (change & CHANGED_OWNER)) {
304 llResetScript();
305 }
306 }
307 state_exit() {
308 llSetTimerEvent(0);
309 }
310 }
311  
312  
313 state listen_group {
314 state_entry() {
315 // DEBUG
316 llOwnerSay("[MOTD] Waiting for group messages and new group members.");
317 }
318 link_message(integer sender, integer num, string message, key id) {
319 // We only care about notifications now.
320 if(id != "notification")
321 return;
322  
323 // Get the group.
324 group = wasURLUnescape(
325 wasKeyValueGet(
326 "group",
327 message
328 )
329 );
330  
331 // Retrieve the membership notification.
332 if(wasKeyValueGet("type", message) == "membership" &&
333 wasKeyValueGet("action", message) == "joined") {
334 firstname = wasURLUnescape(
335 wasKeyValueGet(
336 "firstname",
337 message
338 )
339 );
340 lastname = wasURLUnescape(
341 wasKeyValueGet(
342 "lastname",
343 message
344 )
345 );
346 jump_state = "greet";
347 state url;
348 }
349  
350 // This script only processes group notifications.
351 if(wasKeyValueGet("type", message) != "group")
352 return;
353  
354 // Get the sent message.
355 data = wasURLUnescape(
356 wasKeyValueGet(
357 "message",
358 message
359 )
360 );
361  
362 // Check if this is an eggdrop command.
363 if(llGetSubString(data, 0, 0) !=
364 wasKeyValueGet("command", configuration))
365 return;
366  
367 // Check if the command matches the current module.
15 office 368 list command = llParseString2List(data, [" "], []);
369 if(llList2String(command, 0) !=
370 wasKeyValueGet("command", configuration) + "motd")
11 office 371 return;
372  
373 // Remove command.
374 command = llDeleteSubList(command, 0, 0);
375  
376 // Dump the rest of the message.
377 data = llDumpList2String(command, " ");
378  
379 // Get the sent message.
380 if(data == "") {
381 jump_state = "get";
382 state url;
383 }
384  
385 jump_state = "set";
386 state url;
387 }
388 on_rez(integer num) {
389 llResetScript();
390 }
391 changed(integer change) {
392 if((change & CHANGED_INVENTORY) ||
393 (change & CHANGED_REGION_START) ||
394 (change & CHANGED_OWNER)) {
395 llResetScript();
396 }
397 }
398 }
399  
400 state greet {
401 state_entry() {
402 // DEBUG
403 llOwnerSay("[MOTD] Member joined, retrieving MOTD...");
404 llInstantMessage(
405 wasKeyValueGet(
406 "corrade",
407 configuration
408 ),
409 wasKeyValueEncode(
410 [
411 "command", "database",
412 "group", wasURLEscape(
413 wasKeyValueGet(
414 "group",
415 configuration
416 )
417 ),
418 "password", wasURLEscape(
419 wasKeyValueGet(
420 "password",
421 configuration
422 )
423 ),
424 "SQL", wasURLEscape("SELECT data FROM \"" +
425 wasKeyValueGet("motd table", configuration) +
426 "\" WHERE name=:group"),
427 "data", wasURLEscape(
428 wasListToCSV(
429 [
430 "group",
431 wasURLEscape(group)
432 ]
433 )
434 ),
435 "callback", wasURLEscape(URL)
436 ]
437 )
438 );
439 llSetTimerEvent(60);
440 }
441 http_request(key id, string method, string body) {
442 llHTTPResponse(id, 200, "OK");
443 llReleaseURL(URL);
444 if(wasKeyValueGet("command", body) != "database" ||
445 wasKeyValueGet("success", body) != "True") {
446 // DEBUG
447 llOwnerSay("[MOTD] Unable retrieve from database: " +
448 wasURLUnescape(
449 wasKeyValueGet("error", body)
450 )
451 );
452 state listen_group;
453 }
454  
455 data = llDumpList2String(
456 llDeleteSubList(
457 wasCSVToList(
458 wasURLUnescape(
459 wasKeyValueGet("data", body)
460 )
461 ),
462 0,
463  
464 ),
465 ""
466 );
467  
468 if(data == "")
469 state listen_group;
470  
471 data = "Hello " + firstname + " " + lastname + "!" + " " + data;
472 state tell;
473 }
474 timer() {
475 llReleaseURL(URL);
476 state listen_group;
477 }
478 on_rez(integer num) {
479 llResetScript();
480 }
481 changed(integer change) {
482 if((change & CHANGED_INVENTORY) ||
483 (change & CHANGED_REGION_START) ||
484 (change & CHANGED_OWNER)) {
485 llResetScript();
486 }
487 }
488 state_exit() {
489 llSetTimerEvent(0);
490 }
491 }
492  
493 state get {
494 state_entry() {
495 // DEBUG
496 llOwnerSay("[MOTD] Retrieving from database.");
497 llInstantMessage(
498 wasKeyValueGet(
499 "corrade",
500 configuration
501 ),
502 wasKeyValueEncode(
503 [
504 "command", "database",
505 "group", wasURLEscape(
506 wasKeyValueGet(
507 "group",
508 configuration
509 )
510 ),
511 "password", wasURLEscape(
512 wasKeyValueGet(
513 "password",
514 configuration
515 )
516 ),
517 "SQL", wasURLEscape("SELECT data FROM \"" +
518 wasKeyValueGet("motd table", configuration) +
519 "\" WHERE name=:group"),
520 "data", wasURLEscape(
521 wasListToCSV(
522 [
523 "group",
524 wasURLEscape(group)
525 ]
526 )
527 ),
528 "callback", wasURLEscape(URL)
529 ]
530 )
531 );
532 llSetTimerEvent(60);
533 }
534 http_request(key id, string method, string body) {
535 llHTTPResponse(id, 200, "OK");
536 llReleaseURL(URL);
537 if(wasKeyValueGet("command", body) != "database" ||
538 wasKeyValueGet("success", body) != "True") {
539 // DEBUG
540 llOwnerSay("[MOTD] Unable retrieve from database: " +
541 wasURLUnescape(
542 wasKeyValueGet("error", body)
543 )
544 );
545 state listen_group;
546 }
547  
548 data = llDumpList2String(
549 llDeleteSubList(
550 wasCSVToList(
551 wasURLUnescape(
552 wasKeyValueGet("data", body)
553 )
554 ),
555 0,
556  
557 ),
558 ""
559 );
560  
561 if(data == "") {
562 data = "Sorry, no MOTD is currently set.";
563 state tell;
564 }
565  
566 state tell;
567 }
568 timer() {
569 llReleaseURL(URL);
570 state listen_group;
571 }
572 on_rez(integer num) {
573 llResetScript();
574 }
575 changed(integer change) {
576 if((change & CHANGED_INVENTORY) ||
577 (change & CHANGED_REGION_START) ||
578 (change & CHANGED_OWNER)) {
579 llResetScript();
580 }
581 }
582 state_exit() {
583 llSetTimerEvent(0);
584 }
585 }
586  
587 state set {
588 state_entry() {
589 // DEBUG
590 llOwnerSay("[MOTD] Adding to database.");
591 llInstantMessage(
592 wasKeyValueGet(
593 "corrade",
594 configuration
595 ),
596 wasKeyValueEncode(
597 [
598 "command", "database",
599 "group", wasURLEscape(
600 wasKeyValueGet(
601 "group",
602 configuration
603 )
604 ),
605 "password", wasURLEscape(
606 wasKeyValueGet(
607 "password",
608 configuration
609 )
610 ),
611 "SQL", wasURLEscape("REPLACE INTO \"" +
612 wasKeyValueGet("motd table", configuration) +
613 "\" (name, data) VALUES (:name, :data)"),
614 "data", wasURLEscape(
615 wasListToCSV(
616 [
617 "name",
618 wasURLEscape(group),
619 "data",
620 wasURLEscape(data)
621 ]
622 )
623 ),
624 "callback", wasURLEscape(URL)
625 ]
626 )
627 );
628 llSetTimerEvent(60);
629 }
630 http_request(key id, string method, string body) {
631 llHTTPResponse(id, 200, "OK");
632 llReleaseURL(URL);
633 if(wasKeyValueGet("command", body) != "database" ||
634 wasKeyValueGet("success", body) != "True") {
635 // DEBUG
636 llOwnerSay("[MOTD] Unable modify database: " +
637 wasURLUnescape(
638 wasKeyValueGet("error", body)
639 )
640 );
641 state listen_group;
642 }
643 data = "Saved";
644 state tell;
645 }
646 timer() {
647 llReleaseURL(URL);
648 state listen_group;
649 }
650 on_rez(integer num) {
651 llResetScript();
652 }
653 changed(integer change) {
654 if((change & CHANGED_INVENTORY) ||
655 (change & CHANGED_REGION_START) ||
656 (change & CHANGED_OWNER)) {
657 llResetScript();
658 }
659 }
660 state_exit() {
661 llSetTimerEvent(0);
662 }
663 }
664  
665 state tell {
666 state_entry() {
667 // DEBUG
668 llOwnerSay("[MOTD] Sending to group.");
669 llInstantMessage(
670 wasKeyValueGet(
671 "corrade",
672 configuration
673 ),
674 wasKeyValueEncode(
675 [
676 "command", "tell",
677 "group", wasURLEscape(
678 wasKeyValueGet(
679 "group",
680 configuration
681 )
682 ),
683 "password", wasURLEscape(
684 wasKeyValueGet(
685 "password",
686 configuration
687 )
688 ),
689 "entity", "group",
690 "message", wasURLEscape(data)
691 ]
692 )
693 );
694 state listen_group;
695 }
696 }