corrade-lsl-templates – Blame information for rev 42

Subversion Repositories:
Rev:
Rev Author Line No. Line
8 office 1 ///////////////////////////////////////////////////////////////////////////
42 office 2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
8 office 3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // A module that bans group members using fuzzy name matching.
6 //
7 ///////////////////////////////////////////////////////////////////////////
8  
9 ///////////////////////////////////////////////////////////////////////////
41 office 10 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
8 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);
8 office 18 return "";
19 }
42 office 20  
8 office 21 ///////////////////////////////////////////////////////////////////////////
42 office 22 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
8 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 }
35  
36 ///////////////////////////////////////////////////////////////////////////
42 office 37 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
8 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 }
47  
48 ///////////////////////////////////////////////////////////////////////////
42 office 49 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
8 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 }
71  
72 ///////////////////////////////////////////////////////////////////////////
42 office 73 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
8 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 }
110  
111 ///////////////////////////////////////////////////////////////////////////
42 office 112 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
8 office 113 ///////////////////////////////////////////////////////////////////////////
114 string wasListToCSV(list l) {
115 list v = [];
116 do {
117 string a = llDumpList2String(
118 llParseStringKeepNulls(
119 llList2String(
42 office 120 l,
8 office 121  
42 office 122 ),
123 ["\""],
8 office 124 []
125 ),
126 "\"\""
127 );
128 if(llParseStringKeepNulls(
42 office 129 a,
8 office 130 [" ", ",", "\n", "\""], []
42 office 131 ) !=
8 office 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 ///////////////////////////////////////////////////////////////////////////
42 office 141 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
8 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 ["+"],
8 office 152 []
42 office 153 ),
8 office 154 " "
42 office 155 ),
156 ["%0D%0A"],
8 office 157 []
42 office 158 ),
8 office 159 "\n"
160 )
161 );
162 }
163  
164 ///////////////////////////////////////////////////////////////////////////
42 office 165 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
8 office 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 // banee
181 string firstname = "";
182 string lastname = "";
15 office 183 string soft = "True";
8 office 184  
185 default {
186 state_entry() {
187 llOwnerSay("[Ban] Starting...");
188 llSetTimerEvent(10);
189 }
190 link_message(integer sender, integer num, string message, key id) {
191 if(id != "configuration") return;
192 llOwnerSay("[Ban] Got configuration...");
193 configuration = message;
194 state listen_group;
195 }
196 timer() {
197 llOwnerSay("[Ban] Requesting configuration...");
198 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
199 }
200 on_rez(integer num) {
201 llResetScript();
202 }
203 changed(integer change) {
42 office 204 if((change & CHANGED_INVENTORY) ||
205 (change & CHANGED_REGION_START) ||
8 office 206 (change & CHANGED_OWNER)) {
207 llResetScript();
208 }
209 }
210 state_exit() {
211 llSetTimerEvent(0);
212 }
213 }
214  
215 state listen_group {
216 state_entry() {
217 // DEBUG
218 llOwnerSay("[Ban] Waiting for group messages...");
219 }
220 link_message(integer sender, integer num, string message, key id) {
221 // We only care about notifications now.
222 if(id != "notification")
223 return;
42 office 224  
8 office 225 // This script only processes group notifications.
42 office 226 if(wasKeyValueGet("type", message) != "group" ||
227 (wasKeyValueGet("type", message) == "group" &&
228 wasURLUnescape(wasKeyValueGet("group", message)) !=
229 wasKeyValueGet("group", configuration)))
8 office 230 return;
42 office 231  
8 office 232 // Get the sent message.
233 data = wasURLUnescape(
234 wasKeyValueGet(
42 office 235 "message",
8 office 236 message
237 )
238 );
42 office 239  
11 office 240 // Check if this is an eggdrop command.
42 office 241 if(llGetSubString(data, 0, 0) !=
8 office 242 wasKeyValueGet("command", configuration))
243 return;
42 office 244  
11 office 245 // Check if the command matches the current module.
15 office 246 list command = llParseString2List(data, [" "], []);
42 office 247 if(llList2String(command, 0) !=
15 office 248 wasKeyValueGet("command", configuration) + "ban")
8 office 249 return;
42 office 250  
15 office 251 // Remove command.
252 command = llDeleteSubList(command, 0, 0);
42 office 253  
8 office 254 firstname = wasKeyValueGet("firstname", message);
255 lastname = wasKeyValueGet("lastname", message);
42 office 256  
8 office 257 if(firstname == "" || lastname == "") {
258 data = "And who would yarr be?";
259 state tell;
260 }
42 office 261  
8 office 262 // Dump the rest of the message.
263 data = llDumpList2String(command, " ");
264  
42 office 265 // Get roles of caller.
8 office 266 state get_caller_roles;
267 }
268 on_rez(integer num) {
269 llResetScript();
270 }
271 changed(integer change) {
42 office 272 if((change & CHANGED_INVENTORY) ||
273 (change & CHANGED_REGION_START) ||
8 office 274 (change & CHANGED_OWNER)) {
275 llResetScript();
276 }
277 }
278 }
279  
280 state get_caller_roles {
281 state_entry() {
282 // DEBUG
283 llOwnerSay("[Ban] Searching for caller...");
284 llInstantMessage(
285 wasKeyValueGet(
42 office 286 "corrade",
8 office 287 configuration
42 office 288 ),
8 office 289 wasKeyValueEncode(
290 [
291 "command", "getmemberroles",
292 "group", wasURLEscape(
293 wasKeyValueGet(
42 office 294 "group",
8 office 295 configuration
296 )
297 ),
298 "password", wasURLEscape(
299 wasKeyValueGet(
42 office 300 "password",
8 office 301 configuration
302 )
303 ),
304 "firstname", firstname,
305 "lastname", lastname,
42 office 306 "callback", wasURLEscape(
307 wasKeyValueGet(
308 "URL",
309 configuration
310 )
311 )
8 office 312 ]
313 )
314 );
42 office 315  
8 office 316 llSetTimerEvent(60);
317 }
42 office 318 link_message(integer sender, integer num, string body, key id) {
319 // Only process callbacks for the database command.
320 if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles")
321 return;
322  
8 office 323 if(wasKeyValueGet("command", body) != "getmemberroles" ||
324 wasKeyValueGet("success", body) != "True") {
325 // DEBUG
42 office 326 llOwnerSay("[Ban] Unable to get member roles: " +
8 office 327 wasURLUnescape(
328 wasKeyValueGet("error", body)
329 )
330 );
331 state listen_group;
332 }
42 office 333  
8 office 334 // Dump the roles to a list.
335 list roles = wasCSVToList(
336 wasURLUnescape(
337 wasKeyValueGet("data", body)
338 )
339 );
42 office 340  
8 office 341 if(llGetListLength(
42 office 342 wasSetIntersect(roles,
8 office 343 wasCSVToList(
344 wasKeyValueGet(
345 "admin roles", configuration
346 )
347 )
348 )
349 ) == 0) {
350 data = "You ain't got the cojones!";
351 state tell;
352 }
42 office 353  
8 office 354 list banee = llParseString2List(data, [" "], []);
42 office 355  
8 office 356 firstname = llList2String(banee, 0);
15 office 357 banee = llDeleteSubList(banee, 0, 0);
358 lastname = llList2String(banee, 0);
359 banee = llDeleteSubList(banee, 0, 0);
42 office 360  
8 office 361 if(firstname == "" || lastname == "") {
362 data = "Full name required.";
363 state tell;
364 }
42 office 365  
366 if(llGetListLength(banee) != 0 &&
15 office 367 llToLower(llList2String(banee, 0)) == "nosoft") {
368 soft = "False";
369 banee = llDeleteSubList(banee, 0, 0);
370 }
42 office 371  
8 office 372 // GC
373 banee = [];
374 state get_banee_roles;
375 }
376 timer() {
377 state listen_group;
378 }
379 on_rez(integer num) {
380 llResetScript();
381 }
382 changed(integer change) {
42 office 383 if((change & CHANGED_INVENTORY) ||
384 (change & CHANGED_REGION_START) ||
8 office 385 (change & CHANGED_OWNER)) {
386 llResetScript();
387 }
388 }
389 state_exit() {
390 llSetTimerEvent(0);
391 }
392 }
393  
394 state get_banee_roles {
395 state_entry() {
396 // DEBUG
397 llOwnerSay("[Ban] Searching for banee...");
398 llInstantMessage(
399 wasKeyValueGet(
42 office 400 "corrade",
8 office 401 configuration
42 office 402 ),
8 office 403 wasKeyValueEncode(
404 [
405 "command", "getmemberroles",
406 "group", wasURLEscape(
407 wasKeyValueGet(
42 office 408 "group",
8 office 409 configuration
410 )
411 ),
412 "password", wasURLEscape(
413 wasKeyValueGet(
42 office 414 "password",
8 office 415 configuration
416 )
417 ),
418 "firstname", firstname,
419 "lastname", lastname,
42 office 420 "callback", wasURLEscape(
421 wasKeyValueGet(
422 "URL",
423 configuration
424 )
425 )
8 office 426 ]
427 )
428 );
429 llSetTimerEvent(60);
430 }
42 office 431 link_message(integer sender, integer num, string body, key id) {
432 // Only process callbacks for the database command.
433 if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles")
434 return;
435  
436 if(wasKeyValueGet("success", body) != "True") {
15 office 437 if(wasKeyValueGet("status", body) == "19862") {
438 // DEBUG
439 llOwnerSay("[Ban] User not in group, but proceeding anyway...");
440 jump continue;
441 }
8 office 442 // DEBUG
42 office 443 llOwnerSay("[Ban] Unable to get member roles: " +
8 office 444 wasURLUnescape(
445 wasKeyValueGet("error", body)
446 )
447 );
448 state listen_group;
449 }
42 office 450  
15 office 451 @continue;
8 office 452 string result = wasURLUnescape(
453 wasKeyValueGet("data", body)
454 );
42 office 455  
8 office 456 if(result != "" && llListFindList(wasCSVToList(result), (list)"Owners") != -1) {
15 office 457 data = "Ejectee is an owner. I'm not gunna open the pod bay doors.";
8 office 458 state tell;
459 }
42 office 460  
8 office 461 state ban;
462 }
463 timer() {
464 state listen_group;
465 }
466 on_rez(integer num) {
467 llResetScript();
468 }
469 changed(integer change) {
42 office 470 if((change & CHANGED_INVENTORY) ||
471 (change & CHANGED_REGION_START) ||
8 office 472 (change & CHANGED_OWNER)) {
473 llResetScript();
474 }
475 }
476 state_exit() {
477 llSetTimerEvent(0);
478 }
479 }
480  
481 state ban {
482 state_entry() {
483 // DEBUG
484 llOwnerSay("[Ban] Banning...");
485 llInstantMessage(
486 wasKeyValueGet(
42 office 487 "corrade",
8 office 488 configuration
42 office 489 ),
8 office 490 wasKeyValueEncode(
491 [
492 "command", "ban",
493 "group", wasURLEscape(
494 wasKeyValueGet(
42 office 495 "group",
8 office 496 configuration
497 )
498 ),
499 "password", wasURLEscape(
500 wasKeyValueGet(
42 office 501 "password",
8 office 502 configuration
503 )
504 ),
15 office 505 "soft", soft,
8 office 506 "action", "ban",
507 "avatars", wasURLEscape(
508 wasListToCSV(
509 [
510 firstname + " " + lastname
511 ]
512 )
513 ),
514 "eject", "True",
42 office 515 "callback", wasURLEscape(
516 wasKeyValueGet(
517 "URL",
518 configuration
519 )
520 )
8 office 521 ]
522 )
523 );
524 llSetTimerEvent(60);
525 }
42 office 526 link_message(integer sender, integer num, string body, key id) {
527 // Only process callbacks for the database command.
528 if(id != "callback" || wasKeyValueGet("command", body) != "ban")
529 return;
530  
8 office 531 if(wasKeyValueGet("command", body) != "ban" ||
532 wasKeyValueGet("success", body) != "True") {
533 // DEBUG
42 office 534 llOwnerSay("[Ban] Unable to ban member: " +
8 office 535 wasURLUnescape(
536 wasKeyValueGet("error", body)
537 )
538 );
539 state listen_group;
540 }
42 office 541  
8 office 542 data = "Hasta la vista, baby!";
42 office 543  
8 office 544 state tell;
545 }
546 timer() {
547 state listen_group;
548 }
549 on_rez(integer num) {
550 llResetScript();
551 }
552 changed(integer change) {
42 office 553 if((change & CHANGED_INVENTORY) ||
554 (change & CHANGED_REGION_START) ||
8 office 555 (change & CHANGED_OWNER)) {
556 llResetScript();
557 }
558 }
559 state_exit() {
560 llSetTimerEvent(0);
561 }
562 }
563  
564 state tell {
565 state_entry() {
566 // DEBUG
567 llOwnerSay("[Ban] Sending to group.");
568 llInstantMessage(
569 wasKeyValueGet(
42 office 570 "corrade",
8 office 571 configuration
42 office 572 ),
8 office 573 wasKeyValueEncode(
574 [
575 "command", "tell",
576 "group", wasURLEscape(
577 wasKeyValueGet(
42 office 578 "group",
8 office 579 configuration
580 )
581 ),
582 "password", wasURLEscape(
583 wasKeyValueGet(
42 office 584 "password",
8 office 585 configuration
586 )
587 ),
588 "entity", "group",
589 "message", wasURLEscape(data)
590 ]
591 )
592 );
42 office 593  
15 office 594 // reset variables.
595 soft = "True";
42 office 596  
8 office 597 state listen_group;
598 }
599 }