corrade-lsl-templates – Diff between revs 5 and 29

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 5 Rev 29
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // All inventory offers made to Corrade can be processed for rejection // 4 // All inventory offers made to Corrade can be processed for rejection //
5 // approval by scripts. Corrade by default accepts inventory offers from // 5 // approval by scripts. Corrade by default accepts inventory offers from //
6 // masters defined in Corrade.ini - however, it would be useful to write // 6 // masters defined in Corrade.ini - however, it would be useful to write //
7 // an example script that takes a list of avatars and automatically // 7 // an example script that takes a list of avatars and automatically //
8 // accepts all the items. More information on the Corrade scripted agent // 8 // accepts all the items. More information on the Corrade scripted agent //
9 // can be found at: http://was.fm/secondlife/scripted_agents/corrade // 9 // can be found at: http://was.fm/secondlife/scripted_agents/corrade //
10 // 10 //
11 // The script works in combination with a "configuration" notecard that // 11 // The script works in combination with a "configuration" notecard that //
12 // must be placed in the same primitive as this script. The purpose of // 12 // must be placed in the same primitive as this script. The purpose of //
13 // this script is to demonstrate accepting inventory offers with the // 13 // this script is to demonstrate accepting inventory offers with the //
14 // Corrade scripted agent and you are free to use, and commercialize it // 14 // Corrade scripted agent and you are free to use, and commercialize it //
15 // under the terms of the GNU/GPLv3 license which can be found at: // 15 // under the terms of the CC BY 2.0 license which can be found at: //
16 // http://www.gnu.org/licenses/gpl.html // 16 // https://creativecommons.org/licenses/by/2.0 //
17 /////////////////////////////////////////////////////////////////////////// 17 ///////////////////////////////////////////////////////////////////////////
18   18  
19 /////////////////////////////////////////////////////////////////////////// 19 ///////////////////////////////////////////////////////////////////////////
20 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 20 // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 //
21 /////////////////////////////////////////////////////////////////////////// 21 ///////////////////////////////////////////////////////////////////////////
22 string wasKeyValueGet(string k, string data) { 22 string wasKeyValueGet(string k, string data) {
23 if(llStringLength(data) == 0) return ""; 23 if(llStringLength(data) == 0) return "";
24 if(llStringLength(k) == 0) return ""; 24 if(llStringLength(k) == 0) return "";
25 list a = llParseString2List(data, ["&", "="], []); 25 list a = llParseString2List(data, ["&", "="], []);
26 integer i = llListFindList(a, [ k ]); 26 integer i = llListFindList(a, [ k ]);
27 if(i != -1) return llList2String(a, i+1); 27 if(i != -1) return llList2String(a, i+1);
28 return ""; 28 return "";
29 } 29 }
30 30
31 /////////////////////////////////////////////////////////////////////////// 31 ///////////////////////////////////////////////////////////////////////////
32 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // 32 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 //
33 /////////////////////////////////////////////////////////////////////////// 33 ///////////////////////////////////////////////////////////////////////////
34 string wasKeyValueEncode(list data) { 34 string wasKeyValueEncode(list data) {
35 list k = llList2ListStrided(data, 0, -1, 2); 35 list k = llList2ListStrided(data, 0, -1, 2);
36 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 36 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
37 data = []; 37 data = [];
38 do { 38 do {
39 data += llList2String(k, 0) + "=" + llList2String(v, 0); 39 data += llList2String(k, 0) + "=" + llList2String(v, 0);
40 k = llDeleteSubList(k, 0, 0); 40 k = llDeleteSubList(k, 0, 0);
41 v = llDeleteSubList(v, 0, 0); 41 v = llDeleteSubList(v, 0, 0);
42 } while(llGetListLength(k) != 0); 42 } while(llGetListLength(k) != 0);
43 return llDumpList2String(data, "&"); 43 return llDumpList2String(data, "&");
44 } 44 }
45   45  
46 /////////////////////////////////////////////////////////////////////////// 46 ///////////////////////////////////////////////////////////////////////////
47 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 47 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
48 /////////////////////////////////////////////////////////////////////////// 48 ///////////////////////////////////////////////////////////////////////////
49 // escapes a string in conformance with RFC1738 49 // escapes a string in conformance with RFC1738
50 string wasURLEscape(string i) { 50 string wasURLEscape(string i) {
51 string o = ""; 51 string o = "";
52 do { 52 do {
53 string c = llGetSubString(i, 0, 0); 53 string c = llGetSubString(i, 0, 0);
54 i = llDeleteSubString(i, 0, 0); 54 i = llDeleteSubString(i, 0, 0);
55 if(c == "") jump continue; 55 if(c == "") jump continue;
56 if(c == " ") { 56 if(c == " ") {
57 o += "+"; 57 o += "+";
58 jump continue; 58 jump continue;
59 } 59 }
60 if(c == "\n") { 60 if(c == "\n") {
61 o += "%0D" + llEscapeURL(c); 61 o += "%0D" + llEscapeURL(c);
62 jump continue; 62 jump continue;
63 } 63 }
64 o += llEscapeURL(c); 64 o += llEscapeURL(c);
65 @continue; 65 @continue;
66 } while(i != ""); 66 } while(i != "");
67 return o; 67 return o;
68 } 68 }
69   69  
70 /////////////////////////////////////////////////////////////////////////// 70 ///////////////////////////////////////////////////////////////////////////
71 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 71 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
72 /////////////////////////////////////////////////////////////////////////// 72 ///////////////////////////////////////////////////////////////////////////
73 // unescapes a string in conformance with RFC1738 73 // unescapes a string in conformance with RFC1738
74 string wasURLUnescape(string i) { 74 string wasURLUnescape(string i) {
75 return llUnescapeURL( 75 return llUnescapeURL(
76 llDumpList2String( 76 llDumpList2String(
77 llParseString2List( 77 llParseString2List(
78 llDumpList2String( 78 llDumpList2String(
79 llParseString2List( 79 llParseString2List(
80 i, 80 i,
81 ["+"], 81 ["+"],
82 [] 82 []
83 ), 83 ),
84 " " 84 " "
85 ), 85 ),
86 ["%0D%0A"], 86 ["%0D%0A"],
87 [] 87 []
88 ), 88 ),
89 "\n" 89 "\n"
90 ) 90 )
91 ); 91 );
92 } 92 }
93   93  
94 /////////////////////////////////////////////////////////////////////////// 94 ///////////////////////////////////////////////////////////////////////////
95 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 95 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
96 /////////////////////////////////////////////////////////////////////////// 96 ///////////////////////////////////////////////////////////////////////////
97 list wasCSVToList(string csv) { 97 list wasCSVToList(string csv) {
98 list l = []; 98 list l = [];
99 list s = []; 99 list s = [];
100 string m = ""; 100 string m = "";
101 do { 101 do {
102 string a = llGetSubString(csv, 0, 0); 102 string a = llGetSubString(csv, 0, 0);
103 csv = llDeleteSubString(csv, 0, 0); 103 csv = llDeleteSubString(csv, 0, 0);
104 if(a == ",") { 104 if(a == ",") {
105 if(llList2String(s, -1) != "\"") { 105 if(llList2String(s, -1) != "\"") {
106 l += m; 106 l += m;
107 m = ""; 107 m = "";
108 jump continue; 108 jump continue;
109 } 109 }
110 m += a; 110 m += a;
111 jump continue; 111 jump continue;
112 } 112 }
113 if(a == "\"" && llGetSubString(csv, 0, 0) == a) { 113 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
114 m += a; 114 m += a;
115 csv = llDeleteSubString(csv, 0, 0); 115 csv = llDeleteSubString(csv, 0, 0);
116 jump continue; 116 jump continue;
117 } 117 }
118 if(a == "\"") { 118 if(a == "\"") {
119 if(llList2String(s, -1) != a) { 119 if(llList2String(s, -1) != a) {
120 s += a; 120 s += a;
121 jump continue; 121 jump continue;
122 } 122 }
123 s = llDeleteSubList(s, -1, -1); 123 s = llDeleteSubList(s, -1, -1);
124 jump continue; 124 jump continue;
125 } 125 }
126 m += a; 126 m += a;
127 @continue; 127 @continue;
128 } while(csv != ""); 128 } while(csv != "");
129 // postcondition: length(s) = 0 129 // postcondition: length(s) = 0
130 return l + m; 130 return l + m;
131 } 131 }
132   132  
133 // corrade data and configuration parameters 133 // corrade data and configuration parameters
134 key CORRADE = NULL_KEY; 134 key CORRADE = NULL_KEY;
135 string GROUP = ""; 135 string GROUP = "";
136 string PASSWORD = ""; 136 string PASSWORD = "";
137 list WHITELIST = []; 137 list WHITELIST = [];
138   138  
139 // for holding the callback URL 139 // for holding the callback URL
140 string callback = ""; 140 string callback = "";
141   141  
142 // for notecard reading 142 // for notecard reading
143 integer line = 0; 143 integer line = 0;
144 144
145 // key-value data will be read into this list 145 // key-value data will be read into this list
146 list tuples = []; 146 list tuples = [];
147   147  
148 default { 148 default {
149 state_entry() { 149 state_entry() {
150 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { 150 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
151 llOwnerSay("Sorry, could not find a configuration inventory notecard."); 151 llOwnerSay("Sorry, could not find a configuration inventory notecard.");
152 return; 152 return;
153 } 153 }
154 // DEBUG 154 // DEBUG
155 llOwnerSay("Reading configuration file..."); 155 llOwnerSay("Reading configuration file...");
156 llGetNotecardLine("configuration", line); 156 llGetNotecardLine("configuration", line);
157 } 157 }
158 dataserver(key id, string data) { 158 dataserver(key id, string data) {
159 if(data == EOF) { 159 if(data == EOF) {
160 // invariant, length(tuples) % 2 == 0 160 // invariant, length(tuples) % 2 == 0
161 if(llGetListLength(tuples) % 2 != 0) { 161 if(llGetListLength(tuples) % 2 != 0) {
162 llOwnerSay("Error in configuration notecard."); 162 llOwnerSay("Error in configuration notecard.");
163 return; 163 return;
164 } 164 }
165 CORRADE = llList2Key( 165 CORRADE = llList2Key(
166 tuples, 166 tuples,
167 llListFindList( 167 llListFindList(
168 tuples, 168 tuples,
169 [ 169 [
170 "corrade" 170 "corrade"
171 ] 171 ]
172 ) 172 )
173 +1 173 +1
174 ); 174 );
175 if(CORRADE == NULL_KEY) { 175 if(CORRADE == NULL_KEY) {
176 llOwnerSay("Error in configuration notecard: corrade"); 176 llOwnerSay("Error in configuration notecard: corrade");
177 return; 177 return;
178 } 178 }
179 GROUP = llList2String( 179 GROUP = llList2String(
180 tuples, 180 tuples,
181 llListFindList( 181 llListFindList(
182 tuples, 182 tuples,
183 [ 183 [
184 "group" 184 "group"
185 ] 185 ]
186 ) 186 )
187 +1 187 +1
188 ); 188 );
189 if(GROUP == "") { 189 if(GROUP == "") {
190 llOwnerSay("Error in configuration notecard: group"); 190 llOwnerSay("Error in configuration notecard: group");
191 return; 191 return;
192 } 192 }
193 PASSWORD = llList2String( 193 PASSWORD = llList2String(
194 tuples, 194 tuples,
195 llListFindList( 195 llListFindList(
196 tuples, 196 tuples,
197 [ 197 [
198 "password" 198 "password"
199 ] 199 ]
200 ) 200 )
201 +1 201 +1
202 ); 202 );
203 if(PASSWORD == "") { 203 if(PASSWORD == "") {
204 llOwnerSay("Error in configuration notecard: password"); 204 llOwnerSay("Error in configuration notecard: password");
205 return; 205 return;
206 } 206 }
207 WHITELIST = wasCSVToList( 207 WHITELIST = wasCSVToList(
208 llToUpper( 208 llToUpper(
209 llList2String( 209 llList2String(
210 tuples, 210 tuples,
211 llListFindList( 211 llListFindList(
212 tuples, 212 tuples,
213 [ 213 [
214 "whitelist" 214 "whitelist"
215 ] 215 ]
216 ) 216 )
217 +1 217 +1
218 ) 218 )
219 ) 219 )
220 ); 220 );
221 if(WHITELIST == []) { 221 if(WHITELIST == []) {
222 llOwnerSay("Error in configuration notecard: whitelist"); 222 llOwnerSay("Error in configuration notecard: whitelist");
223 return; 223 return;
224 } 224 }
225 // DEBUG 225 // DEBUG
226 llOwnerSay("Read configuration notecard..."); 226 llOwnerSay("Read configuration notecard...");
227 state url; 227 state url;
228 } 228 }
229 if(data == "") jump continue; 229 if(data == "") jump continue;
230 integer i = llSubStringIndex(data, "#"); 230 integer i = llSubStringIndex(data, "#");
231 if(i != -1) data = llDeleteSubString(data, i, -1); 231 if(i != -1) data = llDeleteSubString(data, i, -1);
232 list o = llParseString2List(data, ["="], []); 232 list o = llParseString2List(data, ["="], []);
233 // get rid of starting and ending quotes 233 // get rid of starting and ending quotes
234 string k = llDumpList2String( 234 string k = llDumpList2String(
235 llParseString2List( 235 llParseString2List(
236 llStringTrim( 236 llStringTrim(
237 llList2String( 237 llList2String(
238 o, 238 o,
239 0 239 0
240 ), 240 ),
241 STRING_TRIM), 241 STRING_TRIM),
242 ["\""], [] 242 ["\""], []
243 ), "\""); 243 ), "\"");
244 string v = llDumpList2String( 244 string v = llDumpList2String(
245 llParseString2List( 245 llParseString2List(
246 llStringTrim( 246 llStringTrim(
247 llList2String( 247 llList2String(
248 o, 248 o,
249 1 249 1
250 ), 250 ),
251 STRING_TRIM), 251 STRING_TRIM),
252 ["\""], [] 252 ["\""], []
253 ), "\""); 253 ), "\"");
254 if(k == "" || v == "") jump continue; 254 if(k == "" || v == "") jump continue;
255 tuples += k; 255 tuples += k;
256 tuples += v; 256 tuples += v;
257 @continue; 257 @continue;
258 llGetNotecardLine("configuration", ++line); 258 llGetNotecardLine("configuration", ++line);
259 } 259 }
260 on_rez(integer num) { 260 on_rez(integer num) {
261 llResetScript(); 261 llResetScript();
262 } 262 }
263 changed(integer change) { 263 changed(integer change) {
264 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 264 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
265 llResetScript(); 265 llResetScript();
266 } 266 }
267 } 267 }
268 } 268 }
269   269  
270 state url { 270 state url {
271 state_entry() { 271 state_entry() {
272 // DEBUG 272 // DEBUG
273 llOwnerSay("Requesting URL..."); 273 llOwnerSay("Requesting URL...");
274 llRequestURL(); 274 llRequestURL();
275 } 275 }
276 http_request(key id, string method, string body) { 276 http_request(key id, string method, string body) {
277 if(method != URL_REQUEST_GRANTED) return; 277 if(method != URL_REQUEST_GRANTED) return;
278 callback = body; 278 callback = body;
279 // DEBUG 279 // DEBUG
280 llOwnerSay("Got URL..."); 280 llOwnerSay("Got URL...");
281 state detect; 281 state detect;
282 } 282 }
283 on_rez(integer num) { 283 on_rez(integer num) {
284 llResetScript(); 284 llResetScript();
285 } 285 }
286 changed(integer change) { 286 changed(integer change) {
287 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 287 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
288 llResetScript(); 288 llResetScript();
289 } 289 }
290 } 290 }
291 } 291 }
292 292
293 state detect { 293 state detect {
294 state_entry() { 294 state_entry() {
295 // DEBUG 295 // DEBUG
296 llOwnerSay("Detecting if Corrade is online..."); 296 llOwnerSay("Detecting if Corrade is online...");
297 llSetTimerEvent(5); 297 llSetTimerEvent(5);
298 } 298 }
299 timer() { 299 timer() {
300 llRequestAgentData((key)CORRADE, DATA_ONLINE); 300 llRequestAgentData((key)CORRADE, DATA_ONLINE);
301 } 301 }
302 dataserver(key id, string data) { 302 dataserver(key id, string data) {
303 if(data != "1") { 303 if(data != "1") {
304 // DEBUG 304 // DEBUG
305 llOwnerSay("Corrade is not online, sleeping..."); 305 llOwnerSay("Corrade is not online, sleeping...");
306 llSetTimerEvent(30); 306 llSetTimerEvent(30);
307 return; 307 return;
308 } 308 }
309 state notify; 309 state notify;
310 } 310 }
311 on_rez(integer num) { 311 on_rez(integer num) {
312 llResetScript(); 312 llResetScript();
313 } 313 }
314 changed(integer change) { 314 changed(integer change) {
315 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 315 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
316 llResetScript(); 316 llResetScript();
317 } 317 }
318 } 318 }
319 } 319 }
320 320
321 state notify { 321 state notify {
322 state_entry() { 322 state_entry() {
323 // DEBUG 323 // DEBUG
324 llOwnerSay("Binding to the inventory notification..."); 324 llOwnerSay("Binding to the inventory notification...");
325 llInstantMessage( 325 llInstantMessage(
326 (key)CORRADE, 326 (key)CORRADE,
327 wasKeyValueEncode( 327 wasKeyValueEncode(
328 [ 328 [
329 "command", "notify", 329 "command", "notify",
330 "group", wasURLEscape(GROUP), 330 "group", wasURLEscape(GROUP),
331 "password", wasURLEscape(PASSWORD), 331 "password", wasURLEscape(PASSWORD),
332 "action", "set", 332 "action", "set",
333 "type", "inventory", 333 "type", "inventory",
334 "URL", wasURLEscape(callback), 334 "URL", wasURLEscape(callback),
335 "callback", wasURLEscape(callback) 335 "callback", wasURLEscape(callback)
336 ] 336 ]
337 ) 337 )
338 ); 338 );
339 } 339 }
340 http_request(key id, string method, string body) { 340 http_request(key id, string method, string body) {
341 llHTTPResponse(id, 200, "OK"); 341 llHTTPResponse(id, 200, "OK");
342 if(wasKeyValueGet("command", body) != "notify" || 342 if(wasKeyValueGet("command", body) != "notify" ||
343 wasKeyValueGet("success", body) != "True") { 343 wasKeyValueGet("success", body) != "True") {
344 // DEBUG 344 // DEBUG
345 llOwnerSay("Failed to bind to the inventory notification: " + 345 llOwnerSay("Failed to bind to the inventory notification: " +
346 wasURLUnescape( 346 wasURLUnescape(
347 wasKeyValueGet( 347 wasKeyValueGet(
348 "error", 348 "error",
349 body 349 body
350 ) 350 )
351 ) 351 )
352 ); 352 );
353 state detect; 353 state detect;
354 } 354 }
355 // DEBUG 355 // DEBUG
356 llOwnerSay("Inventory notification installed..."); 356 llOwnerSay("Inventory notification installed...");
357 state accept; 357 state accept;
358 } 358 }
359 on_rez(integer num) { 359 on_rez(integer num) {
360 llResetScript(); 360 llResetScript();
361 } 361 }
362 changed(integer change) { 362 changed(integer change) {
363 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 363 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
364 llResetScript(); 364 llResetScript();
365 } 365 }
366 } 366 }
367 } 367 }
368   368  
369 state accept { 369 state accept {
370 state_entry() { 370 state_entry() {
371 // DEBUG 371 // DEBUG
372 llOwnerSay("Waiting for inventory offers..."); 372 llOwnerSay("Waiting for inventory offers...");
373 } 373 }
374 timer() { 374 timer() {
375 llRequestAgentData((key)CORRADE, DATA_ONLINE); 375 llRequestAgentData((key)CORRADE, DATA_ONLINE);
376 } 376 }
377 dataserver(key id, string data) { 377 dataserver(key id, string data) {
378 if(data == "1") return; 378 if(data == "1") return;
379 // DEBUG 379 // DEBUG
380 llOwnerSay("Corrade is not online, sleeping..."); 380 llOwnerSay("Corrade is not online, sleeping...");
381 // Switch to detect loop and wait there for Corrade to come online. 381 // Switch to detect loop and wait there for Corrade to come online.
382 state detect; 382 state detect;
383 } 383 }
384 http_request(key id, string method, string body) { 384 http_request(key id, string method, string body) {
385 llHTTPResponse(id, 200, "OK"); 385 llHTTPResponse(id, 200, "OK");
386 386
387 string direction = wasURLUnescape( 387 string direction = wasURLUnescape(
388 wasKeyValueGet( 388 wasKeyValueGet(
389 "direction", 389 "direction",
390 body 390 body
391 ) 391 )
392 ); 392 );
393 393
394 // Only care about offers being sent to Corrade. 394 // Only care about offers being sent to Corrade.
395 if(direction != "offer") return; 395 if(direction != "offer") return;
396 396
397 // Search the whitelist for the full name in case 397 // Search the whitelist for the full name in case
398 // an agent is sending the inventory item. 398 // an agent is sending the inventory item.
399 string firstname = llToUpper( 399 string firstname = llToUpper(
400 wasURLUnescape( 400 wasURLUnescape(
401 wasKeyValueGet( 401 wasKeyValueGet(
402 "firstname", 402 "firstname",
403 body 403 body
404 ) 404 )
405 ) 405 )
406 ); 406 );
407 string lastname = llToUpper( 407 string lastname = llToUpper(
408 wasURLUnescape( 408 wasURLUnescape(
409 wasKeyValueGet( 409 wasKeyValueGet(
410 "lastname", 410 "lastname",
411 body 411 body
412 ) 412 )
413 ) 413 )
414 ); 414 );
415 415
416 if(firstname != "" && 416 if(firstname != "" &&
417 lastname != "" && 417 lastname != "" &&
418 llListFindList(WHITELIST, (list)(firstname + " " + lastname)) != -1) 418 llListFindList(WHITELIST, (list)(firstname + " " + lastname)) != -1)
419 jump accept; 419 jump accept;
420 420
421 // Search the whitelist for the UUID of the owner 421 // Search the whitelist for the UUID of the owner
422 // of the object offering the item in case an object 422 // of the object offering the item in case an object
423 // is offering the inventory item 423 // is offering the inventory item
424 string agent = llToUpper( 424 string agent = llToUpper(
425 wasURLUnescape( 425 wasURLUnescape(
426 wasKeyValueGet( 426 wasKeyValueGet(
427 "agent", 427 "agent",
428 body 428 body
429 ) 429 )
430 ) 430 )
431 ); 431 );
432 432
433 // Also search by UUID in case one was provided 433 // Also search by UUID in case one was provided
434 if(agent != NULL_KEY && 434 if(agent != NULL_KEY &&
435 llListFindList(WHITELIST, (list) agent) != -1) 435 llListFindList(WHITELIST, (list) agent) != -1)
436 jump accept; 436 jump accept;
437 437
438 // No matches so return. 438 // No matches so return.
439 return; 439 return;
440 440
441 @accept; 441 @accept;
442   442  
443 key session = (key)wasURLUnescape( 443 key session = (key)wasURLUnescape(
444 wasKeyValueGet( 444 wasKeyValueGet(
445 "session", 445 "session",
446 body 446 body
447 ) 447 )
448 ); 448 );
449 449
450 // Oops, this should not happen! 450 // Oops, this should not happen!
451 if(session == NULL_KEY) return; 451 if(session == NULL_KEY) return;
452   452  
453 // Accept the inventory item. 453 // Accept the inventory item.
454 llInstantMessage(CORRADE, 454 llInstantMessage(CORRADE,
455 wasKeyValueEncode( 455 wasKeyValueEncode(
456 [ 456 [
457   457  
458 "command", "replytoinventoryoffer", 458 "command", "replytoinventoryoffer",
459 "group", wasURLEscape(GROUP), 459 "group", wasURLEscape(GROUP),
460 "password", wasURLEscape(PASSWORD), 460 "password", wasURLEscape(PASSWORD),
461 "action", "accept", // or decline 461 "action", "accept", // or decline
462 // can be retrieved from the inventory notification 462 // can be retrieved from the inventory notification
463 "session", (string)session 463 "session", (string)session
464 // "callback", wasURLEscape(URL) // we do not care 464 // "callback", wasURLEscape(URL) // we do not care
465 ] 465 ]
466 ) 466 )
467 ); 467 );
468 468
469 // DEBUG 469 // DEBUG
470 string item = wasURLUnescape( 470 string item = wasURLUnescape(
471 wasKeyValueGet( 471 wasKeyValueGet(
472 "item", 472 "item",
473 body 473 body
474 ) 474 )
475 ); 475 );
476 string asset = wasURLUnescape( 476 string asset = wasURLUnescape(
477 wasKeyValueGet( 477 wasKeyValueGet(
478 "asset", 478 "asset",
479 body 479 body
480 ) 480 )
481 ); 481 );
482 llOwnerSay("Accepted: " + asset + " " + item); 482 llOwnerSay("Accepted: " + asset + " " + item);
483 483
484 } 484 }
485 on_rez(integer num) { 485 on_rez(integer num) {
486 llResetScript(); 486 llResetScript();
487 } 487 }
488 changed(integer change) { 488 changed(integer change) {
489 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 489 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
490 llResetScript(); 490 llResetScript();
491 } 491 }
492 } 492 }
493 } 493 }
494   494