corrade-lsl-templates – Blame information for rev 29

Subversion Repositories:
Rev:
Rev Author Line No. Line
2 office 1 ///////////////////////////////////////////////////////////////////////////
29 office 2 // Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 //
2 office 3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // This script is a message relay for Corrade that listens for local, group
6 // and instant messages. The script binds to Corrade's local, message and
7 // group notification and then any message received by Corrade gets sent
8 // to you.
9 //
10 // For more information on Corrade, please see:
11 // http://grimore.org/secondlife/scripted_agents/corrade
12 //
13 ///////////////////////////////////////////////////////////////////////////
14  
15 ///////////////////////////////////////////////////////////////////////////
29 office 16 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
2 office 17 ///////////////////////////////////////////////////////////////////////////
18 string wasKeyValueGet(string k, string data) {
19 if(llStringLength(data) == 0) return "";
20 if(llStringLength(k) == 0) return "";
21 list a = llParseString2List(data, ["&", "="], []);
22 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
23 if(i != -1) return llList2String(a, 2*i+1);
24 return "";
25 }
26  
27 ///////////////////////////////////////////////////////////////////////////
29 office 28 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 //
2 office 29 ///////////////////////////////////////////////////////////////////////////
30 string wasKeyValueEncode(list data) {
31 list k = llList2ListStrided(data, 0, -1, 2);
32 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
33 data = [];
34 do {
35 data += llList2String(k, 0) + "=" + llList2String(v, 0);
36 k = llDeleteSubList(k, 0, 0);
37 v = llDeleteSubList(v, 0, 0);
38 } while(llGetListLength(k) != 0);
39 return llDumpList2String(data, "&");
40 }
41  
42 ///////////////////////////////////////////////////////////////////////////
29 office 43 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
2 office 44 ///////////////////////////////////////////////////////////////////////////
45 // escapes a string in conformance with RFC1738
46 string wasURLEscape(string i) {
47 string o = "";
48 do {
49 string c = llGetSubString(i, 0, 0);
50 i = llDeleteSubString(i, 0, 0);
51 if(c == "") jump continue;
52 if(c == " ") {
53 o += "+";
54 jump continue;
55 }
56 if(c == "\n") {
57 o += "%0D" + llEscapeURL(c);
58 jump continue;
59 }
60 o += llEscapeURL(c);
61 @continue;
62 } while(i != "");
63 return o;
64 }
65  
66 ///////////////////////////////////////////////////////////////////////////
29 office 67 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
2 office 68 ///////////////////////////////////////////////////////////////////////////
69 list wasCSVToList(string csv) {
70 list l = [];
71 list s = [];
72 string m = "";
73 do {
74 string a = llGetSubString(csv, 0, 0);
75 csv = llDeleteSubString(csv, 0, 0);
76 if(a == ",") {
77 if(llList2String(s, -1) != "\"") {
78 l += m;
79 m = "";
80 jump continue;
81 }
82 m += a;
83 jump continue;
84 }
85 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
86 m += a;
87 csv = llDeleteSubString(csv, 0, 0);
88 jump continue;
89 }
90 if(a == "\"") {
91 if(llList2String(s, -1) != a) {
92 s += a;
93 jump continue;
94 }
95 s = llDeleteSubList(s, -1, -1);
96 jump continue;
97 }
98 m += a;
99 @continue;
100 } while(csv != "");
101 // postcondition: length(s) = 0
102 return l + m;
103 }
104  
105 ///////////////////////////////////////////////////////////////////////////
29 office 106 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
2 office 107 ///////////////////////////////////////////////////////////////////////////
108 string wasListToCSV(list l) {
109 list v = [];
110 do {
111 string a = llDumpList2String(
112 llParseStringKeepNulls(
113 llList2String(
114 l,
115  
116 ),
117 ["\""],
118 []
119 ),
120 "\"\""
121 );
122 if(llParseStringKeepNulls(
123 a,
124 [" ", ",", "\n", "\""], []
125 ) !=
126 (list) a
127 ) a = "\"" + a + "\"";
128 v += a;
129 l = llDeleteSubList(l, 0, 0);
130 } while(l != []);
131 return llDumpList2String(v, ",");
132 }
133  
134 ///////////////////////////////////////////////////////////////////////////
29 office 135 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
2 office 136 ///////////////////////////////////////////////////////////////////////////
137 // unescapes a string in conformance with RFC1738
138 string wasURLUnescape(string i) {
139 return llUnescapeURL(
140 llDumpList2String(
141 llParseString2List(
142 llDumpList2String(
143 llParseString2List(
144 i,
145 ["+"],
146 []
147 ),
148 " "
149 ),
150 ["%0D%0A"],
151 []
152 ),
153 "\n"
154 )
155 );
156 }
157  
158 // callback URL
159 string callback = "";
160 // configuration data
161 string configuration = "";
162  
163 default {
164 state_entry() {
165 llSetTimerEvent(1);
166 }
167 link_message(integer sender, integer num, string message, key id) {
168 if(sender != 1 || id != "configuration") return;
169 configuration = message;
170 state off;
171 }
172 timer() {
173 llMessageLinked(LINK_ROOT, 0, "configuration", NULL_KEY);
174 }
175 attach(key id) {
176 llResetScript();
177 }
178 on_rez(integer num) {
179 llResetScript();
180 }
181 changed(integer change) {
182 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
183 llResetScript();
184 }
185 }
186 state_exit() {
187 llSetTimerEvent(0);
188 }
189 }
190  
191 state off {
192 state_entry() {
193 llReleaseControls();
194 llSetColor(<.5,0,0>, ALL_SIDES);
195 }
196 touch_end(integer num) {
197 state on;
198 }
199 attach(key id) {
200 llResetScript();
201 }
202 on_rez(integer num) {
203 llResetScript();
204 }
205 changed(integer change) {
206 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
207 llResetScript();
208 }
209 }
210 }
211  
212 state on {
213 state_entry() {
214 llSetColor(<0,.5,0>, ALL_SIDES);
215 state url;
216 }
217 attach(key id) {
218 llResetScript();
219 }
220 on_rez(integer num) {
221 llResetScript();
222 }
223 changed(integer change) {
224 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
225 llResetScript();
226 }
227 }
228 }
229  
230 state url {
231 state_entry() {
232 // DEBUG
233 llOwnerSay("Requesting URL...");
234 llRequestURL();
235 }
236 touch_end(integer num) {
237 llSetColor(<.5,0,0>, ALL_SIDES);
238 llResetScript();
239 }
240 http_request(key id, string method, string body) {
241 if(method != URL_REQUEST_GRANTED) return;
242 callback = body;
243 // DEBUG
244 llOwnerSay("Got URL...");
245 state message;
246 }
247 attach(key id) {
248 llResetScript();
249 }
250 on_rez(integer num) {
251 llResetScript();
252 }
253 changed(integer change) {
254 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
255 llResetScript();
256 }
257 }
258 }
259  
260 state message {
261 state_entry() {
262 // DEBUG
263 llOwnerSay("Binding to the local, instant and group message notification...");
264 llInstantMessage(
265 (key)wasKeyValueGet(
266 "corrade",
267 configuration
268 ),
269 wasKeyValueEncode(
270 [
271 "command", "notify",
272 "group", wasURLEscape(
273 wasKeyValueGet(
274 "group",
275 configuration
276 )
277 ),
278 "password", wasURLEscape(
279 wasKeyValueGet(
280 "password",
281 configuration
282 )
283 ),
284 "action", "add",
285 "type", wasListToCSV(
286 [
287 "local",
288 "message",
289 "group"
290 ]
291 ),
292 "URL", wasURLEscape(callback),
293 "callback", wasURLEscape(callback)
294 ]
295 )
296 );
297 llSetTimerEvent(60);
298 }
299 touch_end(integer num) {
300 llSetColor(<.5,0,0>, ALL_SIDES);
301 llResetScript();
302 }
303 timer() {
304 // DEBUG
305 llOwnerSay("Timeout binding to the local, instant and group message notification...");
306 llResetScript();
307 }
308 http_request(key id, string method, string body) {
309 llHTTPResponse(id, 200, "OK");
310 if(wasKeyValueGet("command", body) != "notify" ||
311 wasKeyValueGet("success", body) != "True") {
312 // DEBUG
313 llOwnerSay("Failed to bind to the local, instant and group message notification..." + wasKeyValueGet("error", body));
314 llResetScript();
315 }
316 // DEBUG
317 llOwnerSay("Local, instant and group message notification installed...");
318 state main;
319 }
320 attach(key id) {
321 llResetScript();
322 }
323 on_rez(integer num) {
324 llResetScript();
325 }
326 changed(integer change) {
327 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
328 llResetScript();
329 }
330 }
331 state_exit() {
332 llSetTimerEvent(0);
333 }
334 }
335  
336 state main {
337 state_entry() {
338 // DEBUG
339 llOwnerSay("Waiting for local, instant or group messages...");
340 llSetTimerEvent(1);
341 }
342 touch_end(integer num) {
343 state uninstall;
344 }
345 timer() {
346 llRequestAgentData(
347 (key)wasKeyValueGet(
348 "corrade",
349 configuration
350 ), DATA_ONLINE);
351 }
352 dataserver(key id, string data) {
353 if(data != "1") llResetScript();
354 }
355 http_request(key id, string method, string body) {
356 llHTTPResponse(id, 200, "OK");
357  
358 // get the message
359 string message = wasURLUnescape(
360 wasKeyValueGet(
361 "message",
362 body
363 )
364 );
365  
366 // bail if message not audible
367 if(message == "") return;
368  
369 // get the message type
370 string type = wasURLUnescape(
371 wasKeyValueGet(
372 "type",
373 body
374 )
375 );
376  
377 // get the first name
378 string firstname = wasURLUnescape(
379 wasKeyValueGet(
380 "firstname",
381 body
382 )
383 );
384  
385 // get the last name
386 string lastname = wasURLUnescape(
387 wasKeyValueGet(
388 "lastname",
389 body
390 )
391 );
392  
393 // get the group
394 string group = wasURLUnescape(
395 wasKeyValueGet(
396 "group",
397 body
398 )
399 );
400  
401 if(group != "") {
402 llOwnerSay(firstname + " " + lastname + " [" + type + "] (" + group + ") : " + message);
403 return;
404 }
405 llOwnerSay(firstname + " " + lastname + " [" + type + "]: " + message);
406 }
407 attach(key id) {
408 llResetScript();
409 }
410 on_rez(integer num) {
411 llResetScript();
412 }
413 changed(integer change) {
414 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
415 llResetScript();
416 }
417 }
418 state_exit() {
419 llSetTimerEvent(0);
420 }
421 }
422  
423 state uninstall {
424 state_entry() {
425 // DEBUG
426 llOwnerSay("Uninstalling local, group and instant message chat notification...");
427 llInstantMessage(
428 (key)wasKeyValueGet(
429 "corrade",
430 configuration
431 ),
432 wasKeyValueEncode(
433 [
434 "command", "notify",
435 "group", wasURLEscape(
436 wasKeyValueGet(
437 "group",
438 configuration
439 )
440 ),
441 "password", wasURLEscape(
442 wasKeyValueGet(
443 "password",
444 configuration
445 )
446 ),
447 "action", "remove",
448 "type", wasListToCSV([
449 "group",
450 "local",
451 "message"
452 ]),
453 "URL", wasURLEscape(callback),
454 "callback", wasURLEscape(callback)
455 ]
456 )
457 );
458 llSetTimerEvent(60);
459 }
460 timer() {
461 // DEBUG
462 llOwnerSay("Timeout uninstalling the local and instant message chat notification...");
463 llResetScript();
464 }
465 http_request(key id, string method, string body) {
466 llHTTPResponse(id, 200, "OK");
467 if(wasKeyValueGet("command", body) != "notify" ||
468 wasKeyValueGet("success", body) != "True") {
469 // DEBUG
470 llOwnerSay("Failed to uninstall the local chat and instant message notification..." + wasKeyValueGet("error", body));
471 llResetScript();
472 }
473 // DEBUG
474 llOwnerSay("Local chat and instant message notifications uninstalled...");
475 llResetScript();
476 }
477 attach(key id) {
478 llResetScript();
479 }
480 on_rez(integer num) {
481 llResetScript();
482 }
483 changed(integer change) {
484 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
485 llResetScript();
486 }
487 }
488 }