corrade-lsl-templates – Diff between revs 41 and 42

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 41 Rev 42
Line 1... Line 1...
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // 2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // 4 //
5 // A wiki module that can memorize strings and recall them by path. 5 // A wiki module that can memorize strings and recall them by path.
6 // 6 //
7 /////////////////////////////////////////////////////////////////////////// 7 ///////////////////////////////////////////////////////////////////////////
Line 8... Line 8...
8   8  
9 /////////////////////////////////////////////////////////////////////////// 9 ///////////////////////////////////////////////////////////////////////////
10 // Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 // 10 // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
11 /////////////////////////////////////////////////////////////////////////// 11 ///////////////////////////////////////////////////////////////////////////
12 integer wasIsAlNum(string a) { 12 integer wasIsAlNum(string a) {
13 if(a == "") return FALSE; 13 if(a == "") return FALSE;
14 integer x = llBase64ToInteger("AAAA" + 14 integer x = llBase64ToInteger("AAAA" +
15 llStringToBase64(llGetSubString(a, 0, 0))); 15 llStringToBase64(llGetSubString(a, 0, 0)));
16 return (x >= 65 && x <= 90) || (x >= 97 && x <= 122) || 16 return (x >= 65 && x <= 90) || (x >= 97 && x <= 122) ||
17 (x >= 48 && x <= 57); 17 (x >= 48 && x <= 57);
Line 26... Line 26...
26 list a = llParseStringKeepNulls(data, ["&", "="], []); 26 list a = llParseStringKeepNulls(data, ["&", "="], []);
27 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); 27 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
28 if(i != -1) return llList2String(a, 2*i+1); 28 if(i != -1) return llList2String(a, 2*i+1);
29 return ""; 29 return "";
30 } 30 }
31 31  
32 /////////////////////////////////////////////////////////////////////////// 32 ///////////////////////////////////////////////////////////////////////////
33 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // 33 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
34 /////////////////////////////////////////////////////////////////////////// 34 ///////////////////////////////////////////////////////////////////////////
35 string wasKeyValueEncode(list data) { 35 string wasKeyValueEncode(list data) {
36 list k = llList2ListStrided(data, 0, -1, 2); 36 list k = llList2ListStrided(data, 0, -1, 2);
37 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 37 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
38 data = []; 38 data = [];
Line 43... Line 43...
43 } while(llGetListLength(k) != 0); 43 } while(llGetListLength(k) != 0);
44 return llDumpList2String(data, "&"); 44 return llDumpList2String(data, "&");
45 } 45 }
Line 46... Line 46...
46   46  
47 /////////////////////////////////////////////////////////////////////////// 47 ///////////////////////////////////////////////////////////////////////////
48 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 48 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
49 /////////////////////////////////////////////////////////////////////////// 49 ///////////////////////////////////////////////////////////////////////////
50 // escapes a string in conformance with RFC1738 50 // escapes a string in conformance with RFC1738
51 string wasURLEscape(string i) { 51 string wasURLEscape(string i) {
52 string o = ""; 52 string o = "";
Line 67... Line 67...
67 } while(i != ""); 67 } while(i != "");
68 return o; 68 return o;
69 } 69 }
Line 70... Line 70...
70   70  
71 /////////////////////////////////////////////////////////////////////////// 71 ///////////////////////////////////////////////////////////////////////////
72 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 72 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
73 /////////////////////////////////////////////////////////////////////////// 73 ///////////////////////////////////////////////////////////////////////////
74 list wasCSVToList(string csv) { 74 list wasCSVToList(string csv) {
75 list l = []; 75 list l = [];
76 list s = []; 76 list s = [];
Line 106... Line 106...
106 // postcondition: length(s) = 0 106 // postcondition: length(s) = 0
107 return l + m; 107 return l + m;
108 } 108 }
Line 109... Line 109...
109   109  
110 /////////////////////////////////////////////////////////////////////////// 110 ///////////////////////////////////////////////////////////////////////////
111 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 111 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
112 /////////////////////////////////////////////////////////////////////////// 112 ///////////////////////////////////////////////////////////////////////////
113 string wasListToCSV(list l) { 113 string wasListToCSV(list l) {
114 list v = []; 114 list v = [];
115 do { 115 do {
116 string a = llDumpList2String( 116 string a = llDumpList2String(
117 llParseStringKeepNulls( 117 llParseStringKeepNulls(
118 llList2String( 118 llList2String(
119 l, 119 l,
120 0 120 0
121 ), 121 ),
122 ["\""], 122 ["\""],
123 [] 123 []
124 ), 124 ),
125 "\"\"" 125 "\"\""
126 ); 126 );
127 if(llParseStringKeepNulls( 127 if(llParseStringKeepNulls(
128 a, 128 a,
129 [" ", ",", "\n", "\""], [] 129 [" ", ",", "\n", "\""], []
130 ) != 130 ) !=
131 (list) a 131 (list) a
132 ) a = "\"" + a + "\""; 132 ) a = "\"" + a + "\"";
133 v += a; 133 v += a;
134 l = llDeleteSubList(l, 0, 0); 134 l = llDeleteSubList(l, 0, 0);
135 } while(l != []); 135 } while(l != []);
136 return llDumpList2String(v, ","); 136 return llDumpList2String(v, ",");
Line 137... Line 137...
137 } 137 }
138   138  
139 /////////////////////////////////////////////////////////////////////////// 139 ///////////////////////////////////////////////////////////////////////////
140 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 140 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
141 /////////////////////////////////////////////////////////////////////////// 141 ///////////////////////////////////////////////////////////////////////////
142 // unescapes a string in conformance with RFC1738 142 // unescapes a string in conformance with RFC1738
143 string wasURLUnescape(string i) { 143 string wasURLUnescape(string i) {
144 return llUnescapeURL( 144 return llUnescapeURL(
145 llDumpList2String( 145 llDumpList2String(
146 llParseString2List( 146 llParseString2List(
147 llDumpList2String( 147 llDumpList2String(
148 llParseString2List( 148 llParseString2List(
149 i, 149 i,
150 ["+"], 150 ["+"],
151 [] 151 []
152 ), 152 ),
153 " " 153 " "
154 ), 154 ),
155 ["%0D%0A"], 155 ["%0D%0A"],
156 [] 156 []
157 ), 157 ),
158 "\n" 158 "\n"
159 ) 159 )
Line 160... Line 160...
160 ); 160 );
161 } 161 }
162   -  
163 // configuration data -  
164 string configuration = ""; 162  
165 // callback URL 163 // configuration data
166 string URL = ""; 164 string configuration = "";
167 // store message over state. 165 // store message over state.
168 string path = ""; 166 string path = "";
Line 179... Line 177...
179 link_message(integer sender, integer num, string message, key id) { 177 link_message(integer sender, integer num, string message, key id) {
180 if(id != "configuration") return; 178 if(id != "configuration") return;
181 llOwnerSay("[Wiki] Got configuration..."); 179 llOwnerSay("[Wiki] Got configuration...");
182 configuration = message; 180 configuration = message;
183 action = "create"; 181 action = "create";
184 state url; 182 state trampoline;
185 } 183 }
186 timer() { 184 timer() {
187 llOwnerSay("[Wiki] Requesting configuration..."); 185 llOwnerSay("[Wiki] Requesting configuration...");
188 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); 186 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
189 } 187 }
190 on_rez(integer num) { 188 on_rez(integer num) {
191 llResetScript(); 189 llResetScript();
192 } 190 }
193 changed(integer change) { 191 changed(integer change) {
194 if((change & CHANGED_INVENTORY) || 192 if((change & CHANGED_INVENTORY) ||
195 (change & CHANGED_REGION_START) || 193 (change & CHANGED_REGION_START) ||
196 (change & CHANGED_OWNER)) { 194 (change & CHANGED_OWNER)) {
197 llResetScript(); 195 llResetScript();
198 } 196 }
199 } 197 }
200 state_exit() { 198 state_exit() {
201 llSetTimerEvent(0); 199 llSetTimerEvent(0);
202 } 200 }
203 } 201 }
Line 204... Line 202...
204   202  
205 state url { 203 state trampoline {
206 state_entry() { -  
207 // DEBUG -  
208 llOwnerSay("[Wiki] Requesting URL..."); -  
209 llRequestURL(); -  
210 } -  
211 http_request(key id, string method, string body) { -  
212 if(method != URL_REQUEST_GRANTED) return; -  
213 URL = body; -  
214 // DEBUG -  
215 llOwnerSay("[Wiki] Got URL."); -  
216 204 state_entry() {
217 if(action == "create") { 205 if(action == "create") {
218 statement = wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + 206 statement = wasURLEscape("CREATE TABLE IF NOT EXISTS \"" +
219 wasKeyValueGet("wiki table", configuration) + 207 wasKeyValueGet("wiki table", configuration) +
220 "\" (path text unique collate nocase, data text)"); 208 "\" (path text unique collate nocase, data text)");
221 state query; 209 state query;
222 } 210 }
223 211  
224 if(action == "get") { 212 if(action == "get") {
225 statement = wasURLEscape("SELECT data FROM \"" + 213 statement = wasURLEscape("SELECT data FROM \"" +
226 wasKeyValueGet("wiki table", configuration) + 214 wasKeyValueGet("wiki table", configuration) +
227 "\" WHERE path=:path"); 215 "\" WHERE path=:path");
228 parameters = wasURLEscape( 216 parameters = wasURLEscape(
229 wasListToCSV( 217 wasListToCSV(
230 [ 218 [
Line 233... Line 221...
233 ] 221 ]
234 ) 222 )
235 ); 223 );
236 state query; 224 state query;
237 } 225 }
238 226  
239 if(action == "set") { 227 if(action == "set") {
240 if(data == "") { 228 if(data == "") {
241 statement = wasURLEscape("DELETE FROM \"" + 229 statement = wasURLEscape("DELETE FROM \"" +
242 wasKeyValueGet("wiki table", configuration) + 230 wasKeyValueGet("wiki table", configuration) +
243 "\" WHERE path=:path"); 231 "\" WHERE path=:path");
244 parameters = wasURLEscape( 232 parameters = wasURLEscape(
245 wasListToCSV( 233 wasListToCSV(
246 [ 234 [
247 "path", 235 "path",
Line 250... Line 238...
250 ) 238 )
251 ); 239 );
252 state query; 240 state query;
253 } 241 }
254 statement = wasURLEscape("REPLACE INTO \"" + 242 statement = wasURLEscape("REPLACE INTO \"" +
255 wasKeyValueGet("wiki table", configuration) + 243 wasKeyValueGet("wiki table", configuration) +
256 "\" (path, data) VALUES (:path, :data)"); 244 "\" (path, data) VALUES (:path, :data)");
257 parameters = wasURLEscape( 245 parameters = wasURLEscape(
258 wasListToCSV( 246 wasListToCSV(
259 [ 247 [
260 "path", 248 "path",
Line 264... Line 252...
264 ] 252 ]
265 ) 253 )
266 ); 254 );
267 state query; 255 state query;
268 } 256 }
269 257  
270 if(action == "dir") { 258 if(action == "dir") {
271 if(path == "/") { 259 if(path == "/") {
272 path = ""; 260 path = "";
273 statement = wasURLEscape( 261 statement = wasURLEscape(
274 "SELECT DISTINCT SUBSTR(path, 1, LENGTH(path) - LENGTH(LTRIM(SUBSTR(path,2), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" + 262 "SELECT DISTINCT SUBSTR(path, 1, LENGTH(path) - LENGTH(LTRIM(SUBSTR(path,2), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" +
275 wasKeyValueGet("wiki table", configuration) + 263 wasKeyValueGet("wiki table", configuration) +
276 "\" WHERE path LIKE '/%' LIMIT " + 264 "\" WHERE path LIKE '/%' LIMIT " +
277 wasKeyValueGet("wiki results limit", configuration) 265 wasKeyValueGet("wiki results limit", configuration)
278 ); 266 );
279 state query; 267 state query;
280 } 268 }
281 statement = wasURLEscape( 269 statement = wasURLEscape(
282 "SELECT DISTINCT SUBSTR(REPLACE(path, :base, ''),1, LENGTH(REPLACE(path, :base, '')) - LENGTH(LTRIM(REPLACE(path, :base, ''), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" + 270 "SELECT DISTINCT SUBSTR(REPLACE(path, :base, ''),1, LENGTH(REPLACE(path, :base, '')) - LENGTH(LTRIM(REPLACE(path, :base, ''), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" +
283 wasKeyValueGet("wiki table", configuration) + 271 wasKeyValueGet("wiki table", configuration) +
284 "\" WHERE path LIKE :path LIMIT " + 272 "\" WHERE path LIKE :path LIMIT " +
285 wasKeyValueGet("wiki results limit", configuration) 273 wasKeyValueGet("wiki results limit", configuration)
286 ); 274 );
287 parameters = wasURLEscape( 275 parameters = wasURLEscape(
288 wasListToCSV( 276 wasListToCSV(
289 [ 277 [
290 "path", 278 "path",
291 wasURLEscape(path + "/" + "%"), 279 wasURLEscape(path + "/" + "%"),
292 "base", 280 "base",
293 wasURLEscape("/" + 281 wasURLEscape("/" +
294 llDumpList2String( 282 llDumpList2String(
295 llParseString2List( 283 llParseString2List(
296 path, 284 path,
297 ["/"], 285 ["/"],
298 [] 286 []
299 ), 287 ),
300 "/" 288 "/"
301 ) + 289 ) +
302 "/" 290 "/"
303 ) 291 )
304 ] 292 ]
305 ) 293 )
306 ); 294 );
307 state query; 295 state query;
308 } 296 }
309 297  
310 if(action == "find") { 298 if(action == "find") {
311 if(data == "") { 299 if(data == "") {
312 data = "Command requires two parameters: a path followed by a search term."; 300 data = "Command requires two parameters: a path followed by a search term.";
313 state tell; 301 state tell;
314 } 302 }
315 if(path == "/") 303 if(path == "/")
316 path = ""; 304 path = "";
317 statement = wasURLEscape( 305 statement = wasURLEscape(
318 "SELECT DISTINCT path FROM \"" + 306 "SELECT DISTINCT path FROM \"" +
319 wasKeyValueGet("wiki table", configuration) + 307 wasKeyValueGet("wiki table", configuration) +
320 "\" WHERE path LIKE :path AND ( data LIKE :data OR path LIKE :data ) COLLATE NOCASE LIMIT " + 308 "\" WHERE path LIKE :path AND ( data LIKE :data OR path LIKE :data ) COLLATE NOCASE LIMIT " +
321 wasKeyValueGet("wiki search limit", configuration) 309 wasKeyValueGet("wiki search limit", configuration)
322 ); 310 );
323 parameters = wasURLEscape( 311 parameters = wasURLEscape(
324 wasListToCSV( 312 wasListToCSV(
Line 330... Line 318...
330 ] 318 ]
331 ) 319 )
332 ); 320 );
333 state query; 321 state query;
334 } 322 }
335 323  
336 // DEBUG 324 // DEBUG
337 llOwnerSay("[Wiki] Jump table corrupted, please contact creator..."); 325 llOwnerSay("[Wiki] Jump table corrupted, please contact creator...");
338 llResetScript(); 326 llResetScript();
339 } 327 }
340 on_rez(integer num) { 328 on_rez(integer num) {
341 llResetScript(); 329 llResetScript();
342 } 330 }
343 changed(integer change) { 331 changed(integer change) {
344 if((change & CHANGED_INVENTORY) || 332 if((change & CHANGED_INVENTORY) ||
345 (change & CHANGED_REGION_START) || 333 (change & CHANGED_REGION_START) ||
346 (change & CHANGED_OWNER)) { 334 (change & CHANGED_OWNER)) {
347 llResetScript(); 335 llResetScript();
348 } 336 }
349 } 337 }
350 } 338 }
Line 356... Line 344...
356 } 344 }
357 link_message(integer sender, integer num, string message, key id) { 345 link_message(integer sender, integer num, string message, key id) {
358 // We only care about notifications now. 346 // We only care about notifications now.
359 if(id != "notification") 347 if(id != "notification")
360 return; 348 return;
361 349  
362 // This script only processes group notifications. 350 // This script only processes group notifications.
363 if(wasKeyValueGet("type", message) != "group") 351 if(wasKeyValueGet("type", message) != "group" ||
-   352 (wasKeyValueGet("type", message) == "group" &&
-   353 wasURLUnescape(wasKeyValueGet("group", message)) !=
-   354 wasKeyValueGet("group", configuration)))
364 return; 355 return;
365 356  
366 // Get the sent message. 357 // Get the sent message.
367 data = wasURLUnescape( 358 data = wasURLUnescape(
368 wasKeyValueGet( 359 wasKeyValueGet(
369 "message", 360 "message",
370 message 361 message
371 ) 362 )
372 ); 363 );
373 364  
374 // Check if this is an eggdrop command. 365 // Check if this is an eggdrop command.
375 if(llGetSubString(data, 0, 0) != 366 if(llGetSubString(data, 0, 0) !=
376 wasKeyValueGet("command", configuration)) 367 wasKeyValueGet("command", configuration))
377 return; 368 return;
378 369  
379 // Check if the command matches the current module. 370 // Check if the command matches the current module.
380 list command = llParseString2List(data, [" "], []); 371 list command = llParseString2List(data, [" "], []);
381 if(llList2String(command, 0) != 372 if(llList2String(command, 0) !=
382 wasKeyValueGet("command", configuration) + "wiki") 373 wasKeyValueGet("command", configuration) + "wiki")
383 return; 374 return;
384 375  
385 // Remove command. 376 // Remove command.
386 command = llDeleteSubList(command, 0, 0); 377 command = llDeleteSubList(command, 0, 0);
387 378  
388 // Check for supported sub-commands. 379 // Check for supported sub-commands.
389 if(llList2String(command, 0) != "set" && 380 if(llList2String(command, 0) != "set" &&
390 llList2String(command, 0) != "get" && 381 llList2String(command, 0) != "get" &&
391 llList2String(command, 0) != "dir" && 382 llList2String(command, 0) != "dir" &&
392 llList2String(command, 0) != "find") { 383 llList2String(command, 0) != "find") {
393 data = "Subcommands are: get, set, dir or find"; 384 data = "Subcommands are: get, set, dir or find";
394 state tell; 385 state tell;
395 } 386 }
396 387  
397 // Get the sub-command and store it as a jump state. 388 // Get the sub-command and store it as a jump state.
398 action = llList2String(command, 0); 389 action = llList2String(command, 0);
399 390  
400 // Remove sub-command. 391 // Remove sub-command.
401 command = llDeleteSubList(command, 0, 0); 392 command = llDeleteSubList(command, 0, 0);
402 393  
403 // Get the path parts. 394 // Get the path parts.
404 list path_parts = llParseString2List( 395 list path_parts = llParseString2List(
405 llList2String(command, 0), ["/"], [] 396 llList2String(command, 0), ["/"], []
406 ); 397 );
407 398  
408 // Dump the path and store it over states. 399 // Dump the path and store it over states.
409 path = llStringTrim( 400 path = llStringTrim(
410 llDumpList2String( 401 llDumpList2String(
411 path_parts, 402 path_parts,
412 "/" 403 "/"
413 ), 404 ),
414 STRING_TRIM 405 STRING_TRIM
415 ); 406 );
416 407  
417 if(path != "") { 408 if(path != "") {
418 integer i = llStringLength(path) - 1; 409 integer i = llStringLength(path) - 1;
419 do { 410 do {
420 string c = llGetSubString(path, i, i); 411 string c = llGetSubString(path, i, i);
421 if(c != "/" && !wasIsAlNum(c)) { 412 if(c != "/" && !wasIsAlNum(c)) {
422 data = "Only alpha-numerics accepted in the path string."; 413 data = "Only alpha-numerics accepted in the path string.";
423 state tell; 414 state tell;
424 } 415 }
425 } while(--i > -1); 416 } while(--i > -1);
426 } 417 }
427 418  
428 path = "/" + path; 419 path = "/" + path;
429 420  
430 // Remove path. 421 // Remove path.
431 command = llDeleteSubList(command, 0, 0); 422 command = llDeleteSubList(command, 0, 0);
432 423  
433 // Dump the rest of the message. 424 // Dump the rest of the message.
434 data = llDumpList2String(command, " "); 425 data = llDumpList2String(command, " ");
435 426  
436 // Get an URL. -  
437 state url; 427 state trampoline;
438 } 428 }
439 on_rez(integer num) { 429 on_rez(integer num) {
440 llResetScript(); 430 llResetScript();
441 } 431 }
442 changed(integer change) { 432 changed(integer change) {
443 if((change & CHANGED_INVENTORY) || 433 if((change & CHANGED_INVENTORY) ||
444 (change & CHANGED_REGION_START) || 434 (change & CHANGED_REGION_START) ||
445 (change & CHANGED_OWNER)) { 435 (change & CHANGED_OWNER)) {
446 llResetScript(); 436 llResetScript();
447 } 437 }
448 } 438 }
449 } 439 }
Line 454... Line 444...
454 string message = wasKeyValueEncode( 444 string message = wasKeyValueEncode(
455 [ 445 [
456 "command", "database", 446 "command", "database",
457 "group", wasURLEscape( 447 "group", wasURLEscape(
458 wasKeyValueGet( 448 wasKeyValueGet(
459 "group", 449 "group",
460 configuration 450 configuration
461 ) 451 )
462 ), 452 ),
463 "password", wasURLEscape( 453 "password", wasURLEscape(
464 wasKeyValueGet( 454 wasKeyValueGet(
465 "password", 455 "password",
466 configuration 456 configuration
467 ) 457 )
468 ), 458 ),
469 "SQL", statement, 459 "SQL", statement,
470 "data", parameters, 460 "data", parameters,
471 "callback", wasURLEscape(URL) 461 "callback", wasURLEscape(
-   462 wasKeyValueGet(
-   463 "URL",
-   464 configuration
-   465 )
-   466 )
472 ] 467 ]
473 ); 468 );
-   469  
474 // GC - none of these are needed anymore. 470 // GC - none of these are needed anymore.
475 statement = ""; 471 statement = "";
476 parameters = ""; 472 parameters = "";
-   473  
-   474 // Message length check.
477 if(llStringLength(message) > 1023) { 475 if(llStringLength(message) > 1023) {
478 data = "Message length exceeded 1023 characters."; 476 data = "Message length exceeded 1023 characters.";
479 state tell; 477 state tell;
480 } 478 }
-   479  
481 // DEBUG 480 // DEBUG
482 llOwnerSay("[Wiki] Executing action: " + action); 481 llOwnerSay("[Wiki] Executing action: " + action);
483 llInstantMessage( 482 llInstantMessage(
484 wasKeyValueGet( 483 wasKeyValueGet(
485 "corrade", 484 "corrade",
486 configuration 485 configuration
487 ), 486 ),
488 message 487 message
489 ); 488 );
490 // GC 489 // GC
491 message = ""; 490 message = "";
492 llSetTimerEvent(60); 491 llSetTimerEvent(60);
493 } 492 }
494 http_request(key id, string method, string body) { 493 link_message(integer sender, integer num, string body, key id) {
495 llHTTPResponse(id, 200, "OK"); 494 // Only process callbacks for the database command.
496 llReleaseURL(URL); -  
497 if(wasKeyValueGet("command", body) != "database" || 495 if(id != "callback" || wasKeyValueGet("command", body) != "database")
-   496 return;
-   497  
498 wasKeyValueGet("success", body) != "True") { 498 if(wasKeyValueGet("success", body) != "True") {
499 // DEBUG 499 // DEBUG
500 llOwnerSay("[Wiki] Unable query database: " + 500 llOwnerSay("[Wiki] Unable query database: " +
501 wasURLUnescape( 501 wasURLUnescape(
502 wasKeyValueGet("error", body) 502 wasKeyValueGet("error", body)
503 ) 503 )
504 ); 504 );
505 state listen_group; 505 state listen_group;
506 } 506 }
507 507  
508 // Process actions. 508 // Process actions.
509 -  
510 if(action == "set") { 509 if(action == "set") {
511 if(data == "") { 510 if(data == "") {
512 data = "Deleted from " + path; 511 data = "Deleted from " + path;
513 state tell; 512 state tell;
514 } 513 }
Line 552... Line 551...
552 0, 551 0,
553 0 552 0
554 ), 553 ),
555 "" 554 ""
556 ); 555 );
557 556  
558 if(data == "") { 557 if(data == "") {
559 data = "Sorry, that path contains no data."; 558 data = "Sorry, that path contains no data.";
560 state tell; 559 state tell;
561 } 560 }
562 561  
563 data = path + ": " + data; 562 data = path + ": " + data;
564 state tell; 563 state tell;
565 } 564 }
566 565  
567 if(action == "dir") { 566 if(action == "dir") {
568 list paths = llList2ListStrided( 567 list paths = llList2ListStrided(
569 llDeleteSubList( 568 llDeleteSubList(
570 wasCSVToList( 569 wasCSVToList(
571 wasURLUnescape( 570 wasURLUnescape(
Line 577... Line 576...
577 ), 576 ),
578 0, 577 0,
579 -1, 578 -1,
580 2 579 2
581 ); 580 );
582 581  
583 if(llGetListLength(paths) == 0) { 582 if(llGetListLength(paths) == 0) {
584 data = "Sorry, that path contains no sub-paths."; 583 data = "Sorry, that path contains no sub-paths.";
585 state tell; 584 state tell;
586 } 585 }
587 586  
588 // Eliminate path component. 587 // Eliminate path component.
589 if(path == "/") 588 if(path == "/")
590 path = ""; 589 path = "";
591 590  
592 list sibling = []; 591 list sibling = [];
593 do { 592 do {
594 // Get the path part. 593 // Get the path part.
595 string part = llList2String(paths, 0); 594 string part = llList2String(paths, 0);
596 595  
597 // Remove the path component. 596 // Remove the path component.
598 string child = llStringTrim( 597 string child = llStringTrim(
599 llDumpList2String( 598 llDumpList2String(
600 llParseString2List( 599 llParseString2List(
601 part, 600 part,
602 [path, "/"], 601 [path, "/"],
603 [] 602 []
604 ), 603 ),
605 "/" 604 "/"
606 ), 605 ),
607 STRING_TRIM 606 STRING_TRIM
608 607  
609 ); 608 );
610 609  
611 integer i = llSubStringIndex(child, "/"); 610 integer i = llSubStringIndex(child, "/");
612 if(i == -1) { 611 if(i == -1) {
613 sibling += path + "/" + child; 612 sibling += path + "/" + child;
614 jump continue_dir; 613 jump continue_dir;
615 } 614 }
Line 617... Line 616...
617 if(llListFindList(sibling, (list)child) == -1) 616 if(llListFindList(sibling, (list)child) == -1)
618 sibling += child; 617 sibling += child;
619 @continue_dir; 618 @continue_dir;
620 paths = llDeleteSubList(paths, 0, 0); 619 paths = llDeleteSubList(paths, 0, 0);
621 } while(llGetListLength(paths) != 0); 620 } while(llGetListLength(paths) != 0);
622 621  
623 data = llList2CSV(sibling); 622 data = llList2CSV(sibling);
624 // GC 623 // GC
625 sibling = []; 624 sibling = [];
626 625  
627 state tell; 626 state tell;
628 } 627 }
629 628  
630 // Don't announce creating table. 629 // Don't announce creating table.
631 if(action == "create") 630 if(action == "create")
632 state listen_group; 631 state listen_group;
633 632  
634 // DEBUG 633 // DEBUG
635 llOwnerSay("[Wiki] Jump table corrupted, please contact creator..."); 634 llOwnerSay("[Wiki] Jump table corrupted, please contact creator...");
636 state listen_group; 635 state listen_group;
637 } 636 }
638 timer() { 637 timer() {
639 llReleaseURL(URL); -  
640 state listen_group; 638 state listen_group;
641 } 639 }
642 on_rez(integer num) { 640 on_rez(integer num) {
643 llResetScript(); 641 llResetScript();
644 } 642 }
645 changed(integer change) { 643 changed(integer change) {
646 if((change & CHANGED_INVENTORY) || 644 if((change & CHANGED_INVENTORY) ||
647 (change & CHANGED_REGION_START) || 645 (change & CHANGED_REGION_START) ||
648 (change & CHANGED_OWNER)) { 646 (change & CHANGED_OWNER)) {
649 llResetScript(); 647 llResetScript();
650 } 648 }
651 } 649 }
652 state_exit() { 650 state_exit() {
Line 658... Line 656...
658 state_entry() { 656 state_entry() {
659 // DEBUG 657 // DEBUG
660 llOwnerSay("[Wiki] Sending to group."); 658 llOwnerSay("[Wiki] Sending to group.");
661 llInstantMessage( 659 llInstantMessage(
662 wasKeyValueGet( 660 wasKeyValueGet(
663 "corrade", 661 "corrade",
664 configuration 662 configuration
665 ), 663 ),
666 wasKeyValueEncode( 664 wasKeyValueEncode(
667 [ 665 [
668 "command", "tell", 666 "command", "tell",
669 "group", wasURLEscape( 667 "group", wasURLEscape(
670 wasKeyValueGet( 668 wasKeyValueGet(
671 "group", 669 "group",
672 configuration 670 configuration
673 ) 671 )
674 ), 672 ),
675 "password", wasURLEscape( 673 "password", wasURLEscape(
676 wasKeyValueGet( 674 wasKeyValueGet(
677 "password", 675 "password",
678 configuration 676 configuration
679 ) 677 )
680 ), 678 ),
681 "entity", "group", 679 "entity", "group",
682 "message", wasURLEscape(data) 680 "message", wasURLEscape(data)