corrade-lsl-templates – Blame information for rev 29

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 ///////////////////////////////////////////////////////////////////////////
29 office 2 // Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 //
1 office 3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // This script is a passthrough or proxy script for dialogs received by
6 // Corrade. The script binds to Corrade's dialog notification and then any
7 // dialog received by Corrade gets sent to you. When you press a button on
8 // the dialog, Corrade will press the button on the dialog it received.
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 //
1 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 //
1 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 //
1 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 //
1 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 //
1 office 107 ///////////////////////////////////////////////////////////////////////////
108 // unescapes a string in conformance with RFC1738
109 string wasURLUnescape(string i) {
110 return llUnescapeURL(
111 llDumpList2String(
112 llParseString2List(
113 llDumpList2String(
114 llParseString2List(
115 i,
116 ["+"],
117 []
118 ),
119 " "
120 ),
121 ["%0D%0A"],
122 []
123 ),
124 "\n"
125 )
126 );
127 }
128  
129 // callback URL
130 string callback = "";
131 // configuration data
132 string configuration = "";
133 // listen handle
134 integer listenHandle = 0;
135  
136 // store dialog details
137 key dialog_item = NULL_KEY;
138 key dialog_id = NULL_KEY;
139 integer dialog_channel = 0;
140 list dialog_buttons = [];
141 string dialog_message = "";
142  
143 default {
144 state_entry() {
145 llSetTimerEvent(1);
146 }
147 link_message(integer sender, integer num, string message, key id) {
148 if(sender != 1 || id != "configuration") return;
149 configuration = message;
150 state off;
151 }
152 timer() {
153 llMessageLinked(LINK_ROOT, 0, "configuration", NULL_KEY);
154 }
155 attach(key id) {
156 llResetScript();
157 }
158 on_rez(integer num) {
159 llResetScript();
160 }
161 changed(integer change) {
162 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
163 llResetScript();
164 }
165 }
166 state_exit() {
167 llSetTimerEvent(0);
168 }
169 }
170  
171 state off {
172 state_entry() {
173 llReleaseControls();
174 llSetColor(<.5,0,0>, ALL_SIDES);
175 }
176 touch_end(integer num) {
177 state on;
178 }
179 attach(key id) {
180 llResetScript();
181 }
182 on_rez(integer num) {
183 llResetScript();
184 }
185 changed(integer change) {
186 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
187 llResetScript();
188 }
189 }
190 }
191  
192 state on {
193 state_entry() {
194 llSetColor(<0,.5,0>, ALL_SIDES);
195 state url;
196 }
197 attach(key id) {
198 llResetScript();
199 }
200 on_rez(integer num) {
201 llResetScript();
202 }
203 changed(integer change) {
204 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
205 llResetScript();
206 }
207 }
208 }
209  
210 state url {
211 state_entry() {
212 // DEBUG
213 llOwnerSay("Requesting URL...");
214 llRequestURL();
215 }
216 touch_end(integer num) {
217 llSetColor(<.5,0,0>, ALL_SIDES);
218 llResetScript();
219 }
220 http_request(key id, string method, string body) {
221 if(method != URL_REQUEST_GRANTED) return;
222 callback = body;
223 // DEBUG
224 llOwnerSay("Got URL...");
225 state dialog;
226 }
227 attach(key id) {
228 llResetScript();
229 }
230 on_rez(integer num) {
231 llResetScript();
232 }
233 changed(integer change) {
234 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
235 llResetScript();
236 }
237 }
238 }
239  
240 state dialog {
241 state_entry() {
242 // DEBUG
243 llOwnerSay("Binding to the dialog notification...");
244 llInstantMessage(
245 (key)wasKeyValueGet(
246 "corrade",
247 configuration
248 ),
249 wasKeyValueEncode(
250 [
251 "command", "notify",
252 "group", wasURLEscape(
253 wasKeyValueGet(
254 "group",
255 configuration
256 )
257 ),
258 "password", wasURLEscape(
259 wasKeyValueGet(
260 "password",
261 configuration
262 )
263 ),
264 "action", "set",
265 "type", "dialog",
266 "URL", wasURLEscape(callback),
267 "callback", wasURLEscape(callback)
268 ]
269 )
270 );
271 llSetTimerEvent(60);
272 }
273 touch_end(integer num) {
274 llSetColor(<.5,0,0>, ALL_SIDES);
275 llResetScript();
276 }
277 timer() {
278 // DEBUG
279 llOwnerSay("Timeout binding to the dialog notification...");
280 llResetScript();
281 }
282 http_request(key id, string method, string body) {
283 llHTTPResponse(id, 200, "OK");
284 if(wasKeyValueGet("command", body) != "notify" ||
285 wasKeyValueGet("success", body) != "True") {
286 // DEBUG
287 llOwnerSay("Failed to bind to the dialog notification..." + wasKeyValueGet("error", body));
288 llResetScript();
289 }
290 // DEBUG
291 llOwnerSay("Dialog notification installed...");
292 state main;
293 }
294 attach(key id) {
295 llResetScript();
296 }
297 on_rez(integer num) {
298 llResetScript();
299 }
300 changed(integer change) {
301 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
302 llResetScript();
303 }
304 }
305 state_exit() {
306 llSetTimerEvent(0);
307 }
308 }
309  
310 state main {
311 state_entry() {
312 // DEBUG
313 llOwnerSay("Waiting for dialog...");
314 llSetTimerEvent(1);
315 }
316 touch_end(integer num) {
317 state uninstall;
318 }
319 timer() {
320 llRequestAgentData(
321 (key)wasKeyValueGet(
322 "corrade",
323 configuration
324 ), DATA_ONLINE);
325 }
326 dataserver(key id, string data) {
327 if(data != "1") llResetScript();
328 }
329 http_request(key id, string method, string body) {
330 llHTTPResponse(id, 200, "OK");
331  
332 // get the dialog id
333 dialog_id = (key)wasURLUnescape(
334 wasKeyValueGet(
335 "id",
336 body
337 )
338 );
339  
340 // get the dialog message
341 dialog_message = wasURLUnescape(
342 wasKeyValueGet(
343 "message",
344 body
345 )
346 );
347  
348 // get the UUID of the object sending the dialog
349 dialog_item = (key)wasURLUnescape(
350 wasKeyValueGet(
351 "item",
352 body
353 )
354 );
355  
356 // get the channel that the dialog was sent on
357 dialog_channel = (integer)wasURLUnescape(
358 wasKeyValueGet(
359 "channel",
360 body
361 )
362 );
363  
364 // get the buttons that the dialog has
365 dialog_buttons = llList2ListStrided(
366 llDeleteSubList(
367 wasCSVToList(
368 wasURLUnescape(
369 wasKeyValueGet(
370 "button",
371 body
372 )
373 )
374 ),
375 0,
376 1
377 ),
378 0,
379 -1,
380 2
381 );
382  
383 // DEBUG
384 llOwnerSay("Got buttons: " + llDumpList2String(dialog_buttons, "|"));
385 listenHandle = llListen(-14, "", llGetOwner(), "");
386 llDialog(llGetOwner(), "[CORRADE]: " + dialog_message, dialog_buttons, -14);
387 }
388 listen(integer channel, string name, key id, string message) {
389 llListenRemove(listenHandle);
390 integer index = llListFindList(dialog_buttons, (list)message);
391 if(index == -1) {
392 // DEBUG
393 llOwnerSay("Button index not found...");
394 return;
395 }
396  
397 llInstantMessage(
398 wasKeyValueGet(
399 "corrade",
400 configuration
401 ),
402 wasKeyValueEncode(
403 [
404 "command", "replytoscriptdialog",
405 "group", wasURLEscape(
406 wasKeyValueGet(
407 "group",
408 configuration
409 )
410 ),
411 "password", wasURLEscape(
412 wasKeyValueGet(
413 "password",
414 configuration
415 )
416 ),
417 "action", "reply",
418 "dialog", dialog_id,
419 "button", wasURLEscape(message),
420 "index", index
421 ]
422 )
423 );
424 }
425 attach(key id) {
426 llResetScript();
427 }
428 on_rez(integer num) {
429 llResetScript();
430 }
431 changed(integer change) {
432 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
433 llResetScript();
434 }
435 }
436 state_exit() {
437 llSetTimerEvent(0);
438 }
439 }
440  
441 state uninstall {
442 state_entry() {
443 // DEBUG
444 llOwnerSay("Uninstalling dialog notification...");
445 llInstantMessage(
446 (key)wasKeyValueGet(
447 "corrade",
448 configuration
449 ),
450 wasKeyValueEncode(
451 [
452 "command", "notify",
453 "group", wasURLEscape(
454 wasKeyValueGet(
455 "group",
456 configuration
457 )
458 ),
459 "password", wasURLEscape(
460 wasKeyValueGet(
461 "password",
462 configuration
463 )
464 ),
465 "action", "remove",
466 "type", "dialog",
467 "URL", wasURLEscape(callback),
468 "callback", wasURLEscape(callback)
469 ]
470 )
471 );
472 llSetTimerEvent(60);
473 }
474 timer() {
475 // DEBUG
476 llOwnerSay("Timeout uninstalling the dialog notification...");
477 llResetScript();
478 }
479 http_request(key id, string method, string body) {
480 llHTTPResponse(id, 200, "OK");
481 if(wasKeyValueGet("command", body) != "notify" ||
482 wasKeyValueGet("success", body) != "True") {
483 // DEBUG
484 llOwnerSay("Failed to uninstall the dialog notification..." + wasKeyValueGet("error", body));
485 llResetScript();
486 }
487 // DEBUG
488 llOwnerSay("Dialog notification uninstalled...");
489 llResetScript();
490 }
491 attach(key id) {
492 llResetScript();
493 }
494 on_rez(integer num) {
495 llResetScript();
496 }
497 changed(integer change) {
498 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START) || (change & CHANGED_OWNER)) {
499 llResetScript();
500 }
501 }
502 }