corrade-lsl-templates – Blame information for rev 42

Subversion Repositories:
Rev:
Rev Author Line No. Line
42 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // A module that sends a group notice.
6 //
7 ///////////////////////////////////////////////////////////////////////////
8  
9 ///////////////////////////////////////////////////////////////////////////
10 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
11 ///////////////////////////////////////////////////////////////////////////
12 string wasKeyValueGet(string k, string data) {
13 if(llStringLength(data) == 0) return "";
14 if(llStringLength(k) == 0) return "";
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);
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 ///////////////////////////////////////////////////////////////////////////
165 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
166 ///////////////////////////////////////////////////////////////////////////
167 list wasSetIntersect(list a, list b) {
168 if(llGetListLength(a) == 0) return [];
169 string i = llList2String(a, 0);
170 a = llDeleteSubList(a, 0, 0);
171 if(llListFindList(b, (list)i) == -1)
172 return wasSetIntersect(a, b);
173 return i + wasSetIntersect(a, b);
174 }
175  
176 // configuration data
177 string configuration = "";
178 // store message over state.
179 string data = "";
180 // callee
181 string firstname = "";
182 string lastname = "";
183  
184 // yhe notice parameters
185 string noticeSubject = "";
186 string noticeMessage = "";
187 string noticeItem = "";
188  
189 default {
190 state_entry() {
191 llOwnerSay("[Notice] Starting...");
192 llSetTimerEvent(10);
193 }
194 link_message(integer sender, integer num, string message, key id) {
195 if(id != "configuration") return;
196 llOwnerSay("[Notice] Got configuration...");
197 configuration = message;
198 state listen_group;
199 }
200 timer() {
201 llOwnerSay("[Notice] Requesting configuration...");
202 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
203 }
204 on_rez(integer num) {
205 llResetScript();
206 }
207 changed(integer change) {
208 if((change & CHANGED_INVENTORY) ||
209 (change & CHANGED_REGION_START) ||
210 (change & CHANGED_OWNER)) {
211 llResetScript();
212 }
213 }
214 state_exit() {
215 llSetTimerEvent(0);
216 }
217 }
218  
219 state listen_group {
220 state_entry() {
221 // DEBUG
222 llOwnerSay("[Notice] Waiting for group messages...");
223 }
224 link_message(integer sender, integer num, string message, key id) {
225 // We only care about notifications now.
226 if(id != "notification")
227 return;
228  
229 // This script only processes group notifications.
230 if(wasKeyValueGet("type", message) != "group" ||
231 (wasKeyValueGet("type", message) == "group" &&
232 wasURLUnescape(wasKeyValueGet("group", message)) !=
233 wasKeyValueGet("group", configuration)))
234 return;
235  
236 // Get the sent message.
237 data = wasURLUnescape(
238 wasKeyValueGet(
239 "message",
240 message
241 )
242 );
243  
244 // Check if this is an eggdrop command.
245 if(llGetSubString(data, 0, 0) !=
246 wasKeyValueGet("command", configuration))
247 return;
248  
249 // Check if the command matches the current module.
250 list command = llParseString2List(data, [" "], []);
251 if(llList2String(command, 0) !=
252 wasKeyValueGet("command", configuration) + "notice")
253 return;
254  
255 // Remove command.
256 command = llDeleteSubList(command, 0, 0);
257  
258 firstname = wasKeyValueGet("firstname", message);
259 lastname = wasKeyValueGet("lastname", message);
260  
261 if(firstname == "" || lastname == "") {
262 data = "And who would yarr be?";
263 state tell;
264 }
265  
266 // Tokenize the message.
267 list noticeData = llParseString2List(
268 llDumpList2String(command, " "),
269 [],
270 [ "(", ")" ]
271 );
272  
273 // Build the notification data.
274 noticeSubject = "";
275 noticeMessage = "";
276 noticeItem = "";
277  
278 // Dyck parser.
279 integer select = 0;
280 list sym = [];
281 do {
282 string slice = llList2String(noticeData, 0);
283 noticeData = llDeleteSubList(noticeData, 0, 0);
284  
285 // Opening bracket.
286 if(slice == "(" && llGetListLength(sym) == 0) {
287 ++select;
288 sym += slice;
289 jump continue;
290 }
291  
292 // Closing bracket lookahead.
293 if(slice == ")" && (
294 llGetListLength(noticeData) == 0 ||
295 llList2String(noticeData, 0) == " ")) {
296 sym = llDeleteSubList(sym, 0, 0);
297 jump continue;
298 }
299  
300 if(select == 1) {
301 noticeSubject += slice;
302 jump continue;
303 }
304 if(select == 2) {
305 noticeMessage += slice;
306 jump continue;
307 }
308 if(select == 3) {
309 noticeItem += slice;
310 jump continue;
311 }
312  
313 @continue;
314 } while(llGetListLength(noticeData) != 0);
315  
316 // Get roles of caller.
317 state get_caller_roles;
318 }
319 on_rez(integer num) {
320 llResetScript();
321 }
322 changed(integer change) {
323 if((change & CHANGED_INVENTORY) ||
324 (change & CHANGED_REGION_START) ||
325 (change & CHANGED_OWNER)) {
326 llResetScript();
327 }
328 }
329 }
330  
331 state get_caller_roles {
332 state_entry() {
333 // DEBUG
334 llOwnerSay("[Notice] Searching for caller...");
335 llInstantMessage(
336 wasKeyValueGet(
337 "corrade",
338 configuration
339 ),
340 wasKeyValueEncode(
341 [
342 "command", "getmemberroles",
343 "group", wasURLEscape(
344 wasKeyValueGet(
345 "group",
346 configuration
347 )
348 ),
349 "password", wasURLEscape(
350 wasKeyValueGet(
351 "password",
352 configuration
353 )
354 ),
355 "firstname", firstname,
356 "lastname", lastname,
357 "callback", wasURLEscape(
358 wasKeyValueGet(
359 "URL",
360 configuration
361 )
362 )
363 ]
364 )
365 );
366 llSetTimerEvent(60);
367 }
368 link_message(integer sender, integer num, string body, key id) {
369 // Only process callbacks for the database command.
370 if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles")
371 return;
372  
373 if(wasKeyValueGet("success", body) != "True") {
374 // DEBUG
375 llOwnerSay("[Notice] Unable to get member roles: " +
376 wasURLUnescape(
377 wasKeyValueGet("error", body)
378 )
379 );
380 state listen_group;
381 }
382  
383 // Dump the roles to a list.
384 list roles = wasCSVToList(
385 wasURLUnescape(
386 wasKeyValueGet("data", body)
387 )
388 );
389  
390 if(llGetListLength(
391 wasSetIntersect(roles,
392 wasCSVToList(
393 wasKeyValueGet(
394 "admin roles", configuration
395 )
396 )
397 )
398 ) == 0) {
399 data = "You ain't got the cojones!";
400 state tell;
401 }
402  
403 state notice;
404 }
405 timer() {
406 state listen_group;
407 }
408 on_rez(integer num) {
409 llResetScript();
410 }
411 changed(integer change) {
412 if((change & CHANGED_INVENTORY) ||
413 (change & CHANGED_REGION_START) ||
414 (change & CHANGED_OWNER)) {
415 llResetScript();
416 }
417 }
418 state_exit() {
419 llSetTimerEvent(0);
420 }
421 }
422  
423 state notice {
424 state_entry() {
425 // DEBUG
426 llOwnerSay("[Notice] Sending notice...");
427 llInstantMessage(
428 wasKeyValueGet(
429 "corrade",
430 configuration
431 ),
432 wasKeyValueEncode(
433 [
434 "command", "notice",
435 "group", wasURLEscape(
436 wasKeyValueGet(
437 "group",
438 configuration
439 )
440 ),
441 "password", wasURLEscape(
442 wasKeyValueGet(
443 "password",
444 configuration
445 )
446 ),
447 "action", "send",
448 "subject", wasURLEscape(noticeSubject),
449 "message", wasURLEscape(noticeMessage),
450 "item", wasURLEscape(noticeItem),
451 "callback", wasURLEscape(
452 wasKeyValueGet(
453 "URL",
454 configuration
455 )
456 )
457 ]
458 )
459 );
460 llSetTimerEvent(60);
461 }
462 link_message(integer sender, integer num, string body, key id) {
463 // Only process callbacks for the database command.
464 if(id != "callback" || wasKeyValueGet("command", body) != "notice")
465 return;
466  
467 if(wasKeyValueGet("success", body) != "True") {
468 // DEBUG
469 llOwnerSay("[Notice] Unable to send notice: " +
470 wasURLUnescape(
471 wasKeyValueGet("error", body)
472 )
473 );
474 state listen_group;
475 }
476  
477 data = "Notice sent.";
478  
479 state tell;
480 }
481 timer() {
482 state listen_group;
483 }
484 on_rez(integer num) {
485 llResetScript();
486 }
487 changed(integer change) {
488 if((change & CHANGED_INVENTORY) ||
489 (change & CHANGED_REGION_START) ||
490 (change & CHANGED_OWNER)) {
491 llResetScript();
492 }
493 }
494 state_exit() {
495 llSetTimerEvent(0);
496 }
497 }
498  
499 state tell {
500 state_entry() {
501 // DEBUG
502 llOwnerSay("[Notice] Sending to group.");
503 llInstantMessage(
504 wasKeyValueGet(
505 "corrade",
506 configuration
507 ),
508 wasKeyValueEncode(
509 [
510 "command", "tell",
511 "group", wasURLEscape(
512 wasKeyValueGet(
513 "group",
514 configuration
515 )
516 ),
517 "password", wasURLEscape(
518 wasKeyValueGet(
519 "password",
520 configuration
521 )
522 ),
523 "entity", "group",
524 "message", wasURLEscape(data)
525 ]
526 )
527 );
528 state listen_group;
529 }
530 }