corrade-lsl-templates – Diff between revs 39 and 40
?pathlinks?
Rev 39 | Rev 40 | |||
---|---|---|---|---|
Line 11... | Line 11... | |||
11 | list a = llParseStringKeepNulls(data, ["&", "="], []); |
11 | list a = llParseStringKeepNulls(data, ["&", "="], []); |
|
12 | integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
12 | integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
|
13 | if(i != -1) return llList2String(a, 2*i+1); |
13 | if(i != -1) return llList2String(a, 2*i+1); |
|
14 | return ""; |
14 | return ""; |
|
15 | } |
15 | } |
|
16 | |
16 | |
|
17 | /////////////////////////////////////////////////////////////////////////// |
17 | /////////////////////////////////////////////////////////////////////////// |
|
18 | // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
18 | // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
|
19 | /////////////////////////////////////////////////////////////////////////// |
19 | /////////////////////////////////////////////////////////////////////////// |
|
20 | string wasKeyValueEncode(list data) { |
20 | string wasKeyValueEncode(list data) { |
|
21 | list k = llList2ListStrided(data, 0, -1, 2); |
21 | list k = llList2ListStrided(data, 0, -1, 2); |
|
22 | list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
22 | list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
|
23 | data = []; |
23 | data = []; |
|
Line 28... | Line 28... | |||
28 | } while(llGetListLength(k) != 0); |
28 | } while(llGetListLength(k) != 0); |
|
29 | return llDumpList2String(data, "&"); |
29 | return llDumpList2String(data, "&"); |
|
30 | } |
30 | } |
|
Line 31... | Line 31... | |||
31 | |
31 | |
|
32 | /////////////////////////////////////////////////////////////////////////// |
32 | /////////////////////////////////////////////////////////////////////////// |
|
33 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
33 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
34 | /////////////////////////////////////////////////////////////////////////// |
34 | /////////////////////////////////////////////////////////////////////////// |
|
35 | // escapes a string in conformance with RFC1738 |
35 | // escapes a string in conformance with RFC1738 |
|
36 | string wasURLEscape(string i) { |
36 | string wasURLEscape(string i) { |
|
37 | string o = ""; |
37 | string o = ""; |
|
Line 52... | Line 52... | |||
52 | } while(i != ""); |
52 | } while(i != ""); |
|
53 | return o; |
53 | return o; |
|
54 | } |
54 | } |
|
Line 55... | Line 55... | |||
55 | |
55 | |
|
56 | /////////////////////////////////////////////////////////////////////////// |
56 | /////////////////////////////////////////////////////////////////////////// |
|
57 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
57 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
58 | /////////////////////////////////////////////////////////////////////////// |
58 | /////////////////////////////////////////////////////////////////////////// |
|
59 | // unescapes a string in conformance with RFC1738 |
59 | // unescapes a string in conformance with RFC1738 |
|
60 | string wasURLUnescape(string i) { |
60 | string wasURLUnescape(string i) { |
|
61 | return llUnescapeURL( |
61 | return llUnescapeURL( |
|
Line 76... | Line 76... | |||
76 | ) |
76 | ) |
|
77 | ); |
77 | ); |
|
78 | } |
78 | } |
|
Line 79... | Line 79... | |||
79 | |
79 | |
|
80 | /////////////////////////////////////////////////////////////////////////// |
80 | /////////////////////////////////////////////////////////////////////////// |
|
81 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
81 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
82 | /////////////////////////////////////////////////////////////////////////// |
82 | /////////////////////////////////////////////////////////////////////////// |
|
83 | list wasCSVToList(string csv) { |
83 | list wasCSVToList(string csv) { |
|
84 | list l = []; |
84 | list l = []; |
|
85 | list s = []; |
85 | list s = []; |
|
Line 114... | Line 114... | |||
114 | } while(csv != ""); |
114 | } while(csv != ""); |
|
115 | // postcondition: length(s) = 0 |
115 | // postcondition: length(s) = 0 |
|
116 | return l + m; |
116 | return l + m; |
|
117 | } |
117 | } |
|
Line -... | Line 118... | |||
- | 118 | |
||
- | 119 | |
||
- | 120 | |
||
- | 121 | /////////////////////////////////////////////////////////////////////////// |
||
- | 122 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
||
- | 123 | /////////////////////////////////////////////////////////////////////////// |
||
- | 124 | string wasListToCSV(list l) { |
||
- | 125 | list v = []; |
||
- | 126 | do { |
||
- | 127 | string a = llDumpList2String( |
||
- | 128 | llParseStringKeepNulls( |
||
- | 129 | llList2String( |
||
- | 130 | l, |
||
- | 131 | 0 |
||
- | 132 | ), |
||
- | 133 | ["\""], |
||
- | 134 | [] |
||
- | 135 | ), |
||
- | 136 | "\"\"" |
||
- | 137 | ); |
||
- | 138 | if(llParseStringKeepNulls( |
||
- | 139 | a, |
||
- | 140 | [" ", ",", "\n", "\""], [] |
||
- | 141 | ) != |
||
- | 142 | (list) a |
||
- | 143 | ) a = "\"" + a + "\""; |
||
- | 144 | v += a; |
||
- | 145 | l = llDeleteSubList(l, 0, 0); |
||
- | 146 | } while(l != []); |
||
- | 147 | return llDumpList2String(v, ","); |
||
- | 148 | } |
||
- | 149 | |
||
- | 150 | /////////////////////////////////////////////////////////////////////////// |
||
- | 151 | // SQL STATEMENT DEFINITIONS // |
||
- | 152 | /////////////////////////////////////////////////////////////////////////// |
||
- | 153 | |
||
- | 154 | string SQL_INSERT_VISITOR = "INSERT OR REPLACE INTO visitors (firstname, lastname, lastseen, time, memory) VALUES(:firstname, :lastname, :time, COALESCE((SELECT time FROM visitors WHERE firstname=:firstname AND lastname=:lastname), 0) + 1, :memory)"; |
||
- | 155 | string SQL_CREATE_TABLE = "CREATE TABLE IF NOT EXISTS visitors ('firstname' TEXT NOT NULL, 'lastname' TEXT NOT NULL, 'lastseen' TEXT NOT NULL, 'time' INTEGER NOT NULL, 'memory' INTEGER NOT NULL, PRIMARY KEY ('firstname', 'lastname'))"; |
||
- | 156 | string SQL_COUNT_VISITORS = "SELECT COUNT(*) AS 'Visits', AVG(time) AS 'Time', AVG(memory) AS 'Memory' FROM visitors"; |
||
- | 157 | string SQL_SELECT_VISITOR = "SELECT * FROM visitors ORDER BY lastseen DESC LIMIT 1 OFFSET :offset"; |
||
- | 158 | string SQL_DROP_TABLE = "DROP TABLE IF EXISTS visitors"; |
||
- | 159 | |
||
- | 160 | /////////////////////////////////////////////////////////////////////////// |
||
118 | |
161 | |
|
119 | // corrade data |
162 | // corrade data |
|
120 | key CORRADE = NULL_KEY; |
163 | key CORRADE = NULL_KEY; |
|
121 | string GROUP = ""; |
164 | string GROUP = ""; |
|
Line 127... | Line 170... | |||
127 | // for notecard reading |
170 | // for notecard reading |
|
128 | integer line = 0; |
171 | integer line = 0; |
|
Line 129... | Line 172... | |||
129 | |
172 | |
|
130 | // key-value data will be read into this list |
173 | // key-value data will be read into this list |
|
- | 174 | list tuples = []; |
||
- | 175 | list agents = []; |
||
Line 131... | Line 176... | |||
131 | list tuples = []; |
176 | string agentName = ""; |
|
132 | |
177 | |
|
133 | |
178 | |
|
Line 264... | Line 309... | |||
264 | // DEBUG |
309 | // DEBUG |
|
265 | llOwnerSay("Detecting if Corrade is online..."); |
310 | llOwnerSay("Detecting if Corrade is online..."); |
|
266 | llSetTimerEvent(5); |
311 | llSetTimerEvent(5); |
|
267 | } |
312 | } |
|
268 | timer() { |
313 | timer() { |
|
269 | llRequestAgentData((key)CORRADE, DATA_ONLINE); |
314 | llRequestAgentData(CORRADE, DATA_ONLINE); |
|
270 | } |
315 | } |
|
271 | dataserver(key id, string data) { |
316 | dataserver(key id, string data) { |
|
272 | if(data != "1") { |
317 | if(data != "1") { |
|
273 | // DEBUG |
318 | // DEBUG |
|
274 | llOwnerSay("Corrade is not online, sleeping..."); |
319 | llOwnerSay("Corrade is not online, sleeping..."); |
|
Line 290... | Line 335... | |||
290 | state initialize { |
335 | state initialize { |
|
291 | state_entry() { |
336 | state_entry() { |
|
292 | // DEBUG |
337 | // DEBUG |
|
293 | llOwnerSay("Creating the database if it does not exist..."); |
338 | llOwnerSay("Creating the database if it does not exist..."); |
|
294 | llInstantMessage( |
339 | llInstantMessage( |
|
295 | (key)CORRADE, |
340 | CORRADE, |
|
296 | wasKeyValueEncode( |
341 | wasKeyValueEncode( |
|
297 | [ |
342 | [ |
|
298 | "command", "database", |
343 | "command", "database", |
|
299 | "group", wasURLEscape(GROUP), |
344 | "group", wasURLEscape(GROUP), |
|
300 | "password", wasURLEscape(PASSWORD), |
345 | "password", wasURLEscape(PASSWORD), |
|
301 | "SQL", wasURLEscape( |
346 | "SQL", wasURLEscape(SQL_CREATE_TABLE), |
|
302 | "CREATE TABLE IF NOT EXISTS visitors ( |
- | ||
303 | 'firstname' TEXT NOT NULL, |
- | ||
304 | 'lastname' TEXT NOT NULL, |
- | ||
305 | 'lastseen' TEXT NOT NULL, |
- | ||
306 | 'time' INTEGER NOT NULL, |
- | ||
307 | 'memory' INTEGER NOT NULL, |
- | ||
308 | PRIMARY KEY ('firstname', 'lastname') |
- | ||
309 | )" |
- | ||
310 | ), |
- | ||
311 | "callback", wasURLEscape(callback) |
347 | "callback", wasURLEscape(callback) |
|
312 | ] |
348 | ] |
|
313 | ) |
349 | ) |
|
314 | ); |
350 | ); |
|
315 | // alarm 60 |
351 | // alarm 60 |
|
Line 320... | Line 356... | |||
320 | llOwnerSay("Timeout creating table..."); |
356 | llOwnerSay("Timeout creating table..."); |
|
321 | llResetScript(); |
357 | llResetScript(); |
|
322 | } |
358 | } |
|
323 | http_request(key id, string method, string body) { |
359 | http_request(key id, string method, string body) { |
|
324 | llHTTPResponse(id, 200, "OK"); |
360 | llHTTPResponse(id, 200, "OK"); |
|
325 | if(wasKeyValueGet("command", body) != "database") return; |
361 | if(wasKeyValueGet("command", body) == "database") { |
|
326 | if(wasKeyValueGet("success", body) != "True") { |
362 | integer success = wasKeyValueGet("success", body) == "True"; |
|
- | 363 | if(!success) { |
||
327 | // DEBUG |
364 | // DEBUG |
|
328 | llOwnerSay("Failed to create the table: " + |
365 | llOwnerSay("Failed to create the table: " + |
|
329 | wasURLUnescape( |
366 | wasURLUnescape( |
|
330 | wasKeyValueGet( |
367 | wasKeyValueGet( |
|
331 | "error", |
368 | "error", |
|
332 | body |
369 | body |
|
- | 370 | ) |
||
333 | ) |
371 | ) |
|
334 | ) |
372 | ); |
|
- | 373 | return; |
||
335 | ); |
374 | } |
|
- | 375 | |
||
336 | return; |
376 | // DEBUG |
|
- | 377 | llOwnerSay("Table created..."); |
||
- | 378 | state show; |
||
- | 379 | } |
||
- | 380 | } |
||
- | 381 | link_message(integer sender_num, integer num, string str, key id) { |
||
- | 382 | if(str == "reset") { |
||
- | 383 | state reset; |
||
337 | } |
384 | } |
|
338 | // DEBUG |
- | ||
339 | llOwnerSay("Table created..."); |
- | ||
340 | state show; |
- | ||
341 | } |
385 | } |
|
342 | on_rez(integer num) { |
386 | on_rez(integer num) { |
|
343 | llResetScript(); |
387 | llResetScript(); |
|
344 | } |
388 | } |
|
345 | changed(integer change) { |
389 | changed(integer change) { |
|
Line 355... | Line 399... | |||
355 | state show { |
399 | state show { |
|
356 | state_entry() { |
400 | state_entry() { |
|
357 | // DEBUG |
401 | // DEBUG |
|
358 | llOwnerSay("Updating display with the number of recorded visitors..."); |
402 | llOwnerSay("Updating display with the number of recorded visitors..."); |
|
359 | llInstantMessage( |
403 | llInstantMessage( |
|
360 | (key)CORRADE, |
404 | CORRADE, |
|
361 | wasKeyValueEncode( |
405 | wasKeyValueEncode( |
|
362 | [ |
406 | [ |
|
363 | "command", "database", |
407 | "command", "database", |
|
364 | "group", wasURLEscape(GROUP), |
408 | "group", wasURLEscape(GROUP), |
|
365 | "password", wasURLEscape(PASSWORD), |
409 | "password", wasURLEscape(PASSWORD), |
|
366 | "SQL", wasURLEscape( |
410 | "SQL", wasURLEscape(SQL_COUNT_VISITORS), |
|
367 | "SELECT |
- | ||
368 | COUNT(*) AS 'Visits', |
- | ||
369 | AVG(time) AS 'Time', |
- | ||
370 | AVG(memory) AS 'Memory' |
- | ||
371 | FROM visitors" |
- | ||
372 | ), |
- | ||
373 | "callback", wasURLEscape(callback) |
411 | "callback", wasURLEscape(callback) |
|
374 | ] |
412 | ] |
|
375 | ) |
413 | ) |
|
376 | ); |
414 | ); |
|
377 | // alarm 60 |
415 | // alarm 60 |
|
Line 382... | Line 420... | |||
382 | llOwnerSay("Timeout reading rows from visitors table..."); |
420 | llOwnerSay("Timeout reading rows from visitors table..."); |
|
383 | llResetScript(); |
421 | llResetScript(); |
|
384 | } |
422 | } |
|
385 | http_request(key id, string method, string body) { |
423 | http_request(key id, string method, string body) { |
|
386 | llHTTPResponse(id, 200, "OK"); |
424 | llHTTPResponse(id, 200, "OK"); |
|
387 | if(wasKeyValueGet("command", body) != "database") return; |
425 | if(wasKeyValueGet("command", body) == "database") { |
|
388 | if(wasKeyValueGet("success", body) != "True") { |
426 | integer success = wasKeyValueGet("success", body) == "True"; |
|
- | 427 | if(!success) { |
||
389 | // DEBUG |
428 | // DEBUG |
|
390 | llOwnerSay("Failed to enumerate visitors: " + |
429 | llOwnerSay("Failed to enumerate visitors: " + |
|
- | 430 | wasURLUnescape( |
||
- | 431 | wasKeyValueGet( |
||
- | 432 | "error", |
||
- | 433 | body |
||
- | 434 | ) |
||
- | 435 | ) |
||
- | 436 | ); |
||
- | 437 | llResetScript(); |
||
- | 438 | } |
||
- | 439 | list data = wasCSVToList( |
||
391 | wasURLUnescape( |
440 | wasURLUnescape( |
|
392 | wasKeyValueGet( |
441 | wasKeyValueGet( |
|
393 | "error", |
442 | "data", |
|
394 | body |
443 | body |
|
395 | ) |
444 | ) |
|
396 | ) |
445 | ) |
|
397 | ); |
446 | ); |
|
398 | llResetScript(); |
- | ||
399 | } |
447 | |
|
400 | list data = wasCSVToList( |
- | ||
401 | wasURLUnescape( |
448 | // DEBUG |
|
402 | wasKeyValueGet( |
- | ||
403 | "data", |
449 | //llOwnerSay("Data: " + llDumpList2String(data, ",")); |
|
404 | body |
- | ||
405 | ) |
- | ||
406 | ) |
- | ||
407 | ); |
450 | |
|
408 | integer visits = llList2Integer( |
451 | integer visits = llList2Integer( |
|
409 | data, |
- | ||
410 | llListFindList( |
- | ||
411 | data, |
452 | data, |
|
412 | (list)"Visits" |
453 | llListFindList( |
|
413 | ) + 1 |
454 | data, |
|
414 | ); |
455 | (list)"Visits" |
|
415 | integer time = llList2Integer( |
456 | ) + 1 |
|
416 | data, |
457 | ); |
|
417 | llListFindList( |
458 | integer time = llList2Integer( |
|
418 | data, |
459 | data, |
|
419 | (list)"Time" |
460 | llListFindList( |
|
420 | ) + 1 |
461 | data, |
|
421 | ); |
462 | (list)"Time" |
|
422 | integer memory = llList2Integer( |
463 | ) + 1 |
|
423 | data, |
464 | ); |
|
424 | llListFindList( |
465 | integer memory = llList2Integer( |
|
425 | data, |
466 | data, |
|
- | 467 | llListFindList( |
||
- | 468 | data, |
||
426 | (list)"Memory" |
469 | (list)"Memory" |
|
427 | ) + 1 |
470 | ) + 1 |
|
428 | ); |
471 | ); |
|
- | 472 | |
||
- | 473 | // Send message to xyz script. |
||
429 | llMessageLinked(LINK_ROOT, 204000, "V:" + (string)visits, "0"); |
474 | llMessageLinked(LINK_ROOT, 204000, "V:" + (string)visits, "0"); |
|
430 | llMessageLinked(LINK_ROOT, 204000, "T:" + (string)time + "m", "1"); |
475 | llMessageLinked(LINK_ROOT, 204000, "T:" + (string)time + "m", "1"); |
|
431 | llMessageLinked(LINK_ROOT, 204000, "M:" + (string)memory + "k", "2"); |
476 | llMessageLinked(LINK_ROOT, 204000, "M:" + (string)memory + "k", "2"); |
|
- | 477 | |
||
- | 478 | // Get the list of agents. |
||
- | 479 | agents = llGetAgentList(AGENT_LIST_REGION, []); |
||
432 | state scan; |
480 | state insert_trampoline; |
|
- | 481 | } |
||
433 | } |
482 | } |
|
434 | link_message(integer sender_num, integer num, string str, key id) { |
483 | link_message(integer sender_num, integer num, string str, key id) { |
|
435 | if(str == "reset") |
484 | if(str == "reset") |
|
436 | state reset; |
485 | state reset; |
|
437 | if(str == "display") { |
486 | if(str == "display") { |
|
Line 450... | Line 499... | |||
450 | state_exit() { |
499 | state_exit() { |
|
451 | llSetTimerEvent(0); |
500 | llSetTimerEvent(0); |
|
452 | } |
501 | } |
|
453 | } |
502 | } |
|
Line 454... | Line 503... | |||
454 | |
503 | |
|
455 | state scan { |
504 | state insert_trampoline { |
|
456 | state_entry() { |
- | ||
457 | // DEBUG |
- | ||
458 | llOwnerSay("Scanning for visitors..."); |
- | ||
459 | // Scan for visitors every 60 seconds. |
505 | state_entry() { |
|
460 | llSetTimerEvent(60); |
506 | llSetTimerEvent(1); |
|
461 | } |
507 | } |
|
462 | timer() { |
- | ||
463 | // Check if Corrade is online. |
- | ||
464 | llRequestAgentData((key)CORRADE, DATA_ONLINE); |
- | ||
465 | // Get agents |
- | ||
466 | list as = llGetAgentList(AGENT_LIST_REGION, []); |
- | ||
467 | do { |
- | ||
468 | key a = llList2Key(as, 0); |
- | ||
469 | as = llDeleteSubList(as, 0, 0); |
- | ||
470 | list name = llParseString2List(llKey2Name(a), [" "], []); |
- | ||
471 | if(llGetListLength(name) != 2) return; |
- | ||
472 | string fn = llList2String(name, 0); |
- | ||
473 | string ln = llList2String(name, 1); |
- | ||
474 | // The command sent to Corrade responsible for adding a visitor |
- | ||
475 | // or updating the data for the visitor in case the visitor is |
- | ||
476 | // already entered into the visitors table. This is performed |
- | ||
477 | // with an INSER OR REPLACE sqlite command given the first name |
- | ||
478 | // and the last name of the avatar are unique primary keys. |
- | ||
479 | llInstantMessage( |
- | ||
480 | (key)CORRADE, |
- | ||
481 | wasKeyValueEncode( |
- | ||
482 | [ |
- | ||
483 | "command", "database", |
- | ||
484 | "group", wasURLEscape(GROUP), |
- | ||
485 | "password", wasURLEscape(PASSWORD), |
- | ||
486 | "SQL", wasURLEscape( |
- | ||
487 | "INSERT OR REPLACE INTO visitors ( |
- | ||
488 | firstname, |
- | ||
489 | lastname, |
- | ||
490 | lastseen, |
- | ||
491 | time, |
- | ||
492 | memory |
- | ||
493 | ) VALUES( |
- | ||
494 | '" + fn + "', '" + ln + "', '" + llGetTimestamp() + "', |
- | ||
495 | COALESCE( |
- | ||
496 | ( |
- | ||
497 | SELECT time FROM visitors WHERE |
- | ||
498 | firstname='" + fn + "' AND lastname='" + ln + "' |
- | ||
499 | ) + 1 |
- | ||
500 | , |
- | ||
501 | 1 |
- | ||
502 | ), " + |
- | ||
503 | (string)( |
- | ||
504 | (integer)( |
- | ||
505 | llList2Float( |
- | ||
506 | llGetObjectDetails( |
- | ||
507 | a, |
- | ||
508 | [OBJECT_SCRIPT_MEMORY] |
- | ||
509 | ), |
- | ||
510 | 0 |
- | ||
511 | ) |
- | ||
512 | / |
- | ||
513 | 1024 /*in kib, to mib 1048576*/ |
- | ||
514 | ) |
- | ||
515 | |
- | ||
516 | ) + |
- | ||
517 | ")" |
- | ||
518 | ) |
- | ||
519 | ] |
- | ||
520 | ) |
- | ||
521 | ); |
- | ||
522 | } while(llGetListLength(as)); |
508 | timer() { |
|
523 | state show; |
509 | state insert; |
|
524 | } |
510 | } |
|
525 | link_message(integer sender_num, integer num, string str, key id) { |
511 | link_message(integer sender_num, integer num, string str, key id) { |
|
526 | if(str == "reset") |
512 | if(str == "reset") |
|
527 | state reset; |
513 | state reset; |
|
528 | if(str == "display") { |
514 | if(str == "display") { |
|
529 | line = 0; |
515 | line = 0; |
|
530 | state display; |
516 | state display; |
|
531 | } |
517 | } |
|
- | 518 | } |
||
- | 519 | on_rez(integer num) { |
||
- | 520 | llResetScript(); |
||
532 | } |
521 | } |
|
- | 522 | changed(integer change) { |
||
- | 523 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
||
- | 524 | llResetScript(); |
||
- | 525 | } |
||
- | 526 | } |
||
- | 527 | state_exit() { |
||
- | 528 | llSetTimerEvent(0); |
||
- | 529 | } |
||
- | 530 | } |
||
- | 531 | |
||
- | 532 | state insert { |
||
- | 533 | state_entry() { |
||
- | 534 | // Once the list is empty, go back to display. |
||
- | 535 | if(llGetListLength(agents) == 0) { |
||
- | 536 | state show; |
||
- | 537 | } |
||
- | 538 | |
||
- | 539 | key agent = llList2Key(agents, 0); |
||
- | 540 | agents = llDeleteSubList(agents, 0, 0); |
||
- | 541 | list name = llParseString2List(llKey2Name(agent), [" "], []); |
||
533 | dataserver(key id, string data) { |
542 | if(llGetListLength(name) != 2) { |
|
- | 543 | return; |
||
- | 544 | } |
||
- | 545 | string firstname = llList2String(name, 0); |
||
- | 546 | string lastname = llList2String(name, 1); |
||
- | 547 | agentName = firstname + " " + lastname; |
||
- | 548 | string memory = (string)( |
||
- | 549 | (integer)( |
||
- | 550 | llList2Float( |
||
- | 551 | llGetObjectDetails( |
||
- | 552 | agent, |
||
- | 553 | [OBJECT_SCRIPT_MEMORY] |
||
- | 554 | ), |
||
- | 555 | 0 |
||
- | 556 | ) |
||
- | 557 | / |
||
- | 558 | 1024 /*in kib, to mib 1048576*/ |
||
- | 559 | ) |
||
- | 560 | |
||
534 | if(data == "1") return; |
561 | ); |
|
- | 562 | // DEBUG |
||
- | 563 | //llOwnerSay("Memory: " + memory); |
||
- | 564 | // The command sent to Corrade responsible for adding a visitor |
||
- | 565 | // or updating the data for the visitor in case the visitor is |
||
- | 566 | // already entered into the visitors table. This is performed |
||
- | 567 | // with an INSER OR REPLACE sqlite command given the first name |
||
- | 568 | // and the last name of the avatar are unique primary keys. |
||
- | 569 | llInstantMessage( |
||
- | 570 | CORRADE, |
||
- | 571 | wasKeyValueEncode( |
||
- | 572 | [ |
||
- | 573 | "command", "database", |
||
- | 574 | "group", wasURLEscape(GROUP), |
||
- | 575 | "password", wasURLEscape(PASSWORD), |
||
- | 576 | "SQL", wasURLEscape(SQL_INSERT_VISITOR), |
||
- | 577 | "data", wasListToCSV( |
||
- | 578 | [ |
||
- | 579 | "firstname", |
||
- | 580 | firstname, |
||
- | 581 | "lastname", |
||
- | 582 | lastname, |
||
- | 583 | "time", |
||
- | 584 | llGetTimestamp(), |
||
- | 585 | "memory", |
||
- | 586 | memory |
||
- | 587 | ] |
||
- | 588 | ), |
||
- | 589 | "callback", wasURLEscape(callback) |
||
- | 590 | ] |
||
- | 591 | ) |
||
- | 592 | ); |
||
- | 593 | |
||
- | 594 | // Command timeout. |
||
- | 595 | llSetTimerEvent(60); |
||
- | 596 | } |
||
- | 597 | http_request(key id, string method, string body) { |
||
- | 598 | llHTTPResponse(id, 200, "OK"); |
||
- | 599 | |
||
- | 600 | // DEBUG |
||
- | 601 | //llOwnerSay(wasURLUnescape(body)); |
||
- | 602 | |
||
- | 603 | if(wasKeyValueGet("command", body) == "database") { |
||
- | 604 | integer success = wasKeyValueGet("success", body) == "True"; |
||
- | 605 | if(!success) { |
||
- | 606 | // DEBUG |
||
- | 607 | llOwnerSay("Failed to insert visitor " + agentName + " due to: " + |
||
- | 608 | wasURLUnescape( |
||
- | 609 | wasKeyValueGet( |
||
- | 610 | "error", |
||
- | 611 | body |
||
- | 612 | ) |
||
- | 613 | ) |
||
- | 614 | ); |
||
- | 615 | state insert_trampoline; |
||
- | 616 | } |
||
- | 617 | |
||
- | 618 | // DEBUG |
||
- | 619 | llOwnerSay("Processed visitor named " + agentName + "..."); |
||
- | 620 | |
||
- | 621 | state insert_trampoline; |
||
- | 622 | } |
||
- | 623 | } |
||
- | 624 | timer() { |
||
535 | // DEBUG |
625 | // DEBUG |
|
- | 626 | llOwnerSay("Inserting visitors has timed out, resetting..."); |
||
- | 627 | |
||
- | 628 | state insert_trampoline; |
||
536 | llOwnerSay("Corrade is not online, sleeping..."); |
629 | } |
|
- | 630 | link_message(integer sender_num, integer num, string str, key id) { |
||
537 | // Switch to detect loop and wait there for Corrade to come online. |
631 | if(str == "reset") { |
|
- | 632 | state reset; |
||
- | 633 | } |
||
- | 634 | if(str == "display") { |
||
- | 635 | line = 0; |
||
- | 636 | state display; |
||
538 | state detect; |
637 | } |
|
539 | } |
638 | } |
|
540 | on_rez(integer num) { |
639 | on_rez(integer num) { |
|
541 | llResetScript(); |
640 | llResetScript(); |
|
542 | } |
641 | } |
|
Line 562... | Line 661... | |||
562 | } |
661 | } |
|
Line 563... | Line 662... | |||
563 | |
662 | |
|
564 | state display { |
663 | state display { |
|
565 | state_entry() { |
664 | state_entry() { |
|
566 | llInstantMessage( |
665 | llInstantMessage( |
|
567 | (key)CORRADE, |
666 | CORRADE, |
|
568 | wasKeyValueEncode( |
667 | wasKeyValueEncode( |
|
569 | [ |
668 | [ |
|
570 | "command", "database", |
669 | "command", "database", |
|
571 | "group", wasURLEscape(GROUP), |
670 | "group", wasURLEscape(GROUP), |
|
572 | "password", wasURLEscape(PASSWORD), |
671 | "password", wasURLEscape(PASSWORD), |
|
573 | "SQL", wasURLEscape( |
672 | "SQL", wasURLEscape(SQL_SELECT_VISITOR), |
|
574 | "SELECT * FROM visitors |
673 | "data", wasListToCSV( |
|
575 | ORDER BY lastseen DESC |
674 | [ |
|
576 | LIMIT 1 |
675 | "offset", |
|
- | 676 | (string)line |
||
577 | OFFSET " + (string)line |
677 | ] |
|
578 | ), |
678 | ), |
|
579 | "callback", wasURLEscape(callback) |
679 | "callback", wasURLEscape(callback) |
|
580 | ] |
680 | ] |
|
581 | ) |
681 | ) |
|
- | 682 | ); |
||
582 | ); |
683 | |
|
583 | // alarm 60 |
684 | // alarm 60 |
|
584 | llSetTimerEvent(60); |
685 | llSetTimerEvent(60); |
|
585 | } |
686 | } |
|
586 | http_request(key id, string method, string body) { |
687 | http_request(key id, string method, string body) { |
|
- | 688 | llHTTPResponse(id, 200, "OK"); |
||
587 | llHTTPResponse(id, 200, "OK"); |
689 | |
|
588 | if(wasKeyValueGet("command", body) != "database") return; |
690 | if(wasKeyValueGet("command", body) == "database") { |
|
- | 691 | integer success = wasKeyValueGet("success", body) == "True"; |
||
589 | if(wasKeyValueGet("success", body) != "True") { |
692 | if(!success) { |
|
590 | // DEBUG |
693 | // DEBUG |
|
591 | llOwnerSay("Failed to query the table: " + |
694 | llOwnerSay("Failed to query the visitors table: " + |
|
592 | wasURLUnescape( |
695 | wasURLUnescape( |
|
593 | wasKeyValueGet( |
696 | wasKeyValueGet( |
|
594 | "error", |
697 | "error", |
|
- | 698 | body |
||
595 | body |
699 | ) |
|
- | 700 | ) |
||
- | 701 | ); |
||
- | 702 | return; |
||
- | 703 | } |
||
- | 704 | |
||
- | 705 | // Grab the data key if it exists. |
||
- | 706 | string dataKey = wasURLUnescape( |
||
- | 707 | wasKeyValueGet( |
||
- | 708 | "data", |
||
596 | ) |
709 | body |
|
597 | ) |
710 | ) |
|
598 | ); |
- | ||
599 | return; |
- | ||
600 | } |
- | ||
601 | // Grab the data key if it exists. |
- | ||
602 | string dataKey = wasURLUnescape( |
- | ||
603 | wasKeyValueGet( |
- | ||
604 | "data", |
- | ||
605 | body |
- | ||
606 | ) |
- | ||
607 | ); |
- | ||
608 | |
- | ||
609 | // We got no more rows, so switch back to scanning. |
- | ||
610 | if(dataKey == "") |
- | ||
611 | state scan; |
- | ||
612 | |
- | ||
Line 613... | Line 711... | |||
613 | list data = wasCSVToList(dataKey); |
711 | ); |
|
614 | |
712 | |
|
615 | string firstname = llList2String( |
713 | // We got no more rows, so switch back to scanning. |
|
- | 714 | if(dataKey == "") |
||
- | 715 | state show; |
||
- | 716 | |
||
- | 717 | list data = wasCSVToList(dataKey); |
||
616 | data, |
718 | |
|
617 | llListFindList( |
719 | string firstname = llList2String( |
|
618 | data, |
720 | data, |
|
619 | (list)"firstname" |
721 | llListFindList( |
|
620 | ) + 1 |
722 | data, |
|
621 | ); |
723 | (list)"firstname" |
|
622 | string lastname = llList2String( |
724 | ) + 1 |
|
623 | data, |
725 | ); |
|
624 | llListFindList( |
726 | string lastname = llList2String( |
|
625 | data, |
727 | data, |
|
626 | (list)"lastname" |
728 | llListFindList( |
|
627 | ) + 1 |
729 | data, |
|
628 | ); |
730 | (list)"lastname" |
|
629 | string lastseen = llList2String( |
731 | ) + 1 |
|
630 | data, |
732 | ); |
|
- | 733 | string lastseen = llList2String( |
||
- | 734 | data, |
||
631 | llListFindList( |
735 | llListFindList( |
|
632 | data, |
736 | data, |
|
633 | (list)"lastseen" |
737 | (list)"lastseen" |
|
634 | ) + 1 |
738 | ) + 1 |
|
635 | ); |
739 | ); |
|
- | 740 | |
||
636 | |
741 | llOwnerSay(firstname + " " + lastname + " @ " + lastseen); |
|
- | 742 | |
||
637 | llOwnerSay(firstname + " " + lastname + " @ " + lastseen); |
743 | state display_trampoline; |
|
638 | state display_trampoline; |
744 | } |
|
639 | } |
745 | } |
|
640 | link_message(integer sender_num, integer num, string str, key id) { |
746 | link_message(integer sender_num, integer num, string str, key id) { |
|
- | 747 | if(str == "reset") { |
||
- | 748 | state reset; |
||
- | 749 | } |
||
- | 750 | // If the display button is pressed again, go back to the display and stop. |
||
- | 751 | if(str == "display") { |
||
641 | if(str == "reset") |
752 | state show; |
|
642 | state reset; |
753 | } |
|
643 | } |
754 | } |
|
644 | timer() { |
755 | timer() { |
|
645 | // DEBUG |
756 | // DEBUG |
|
Line 662... | Line 773... | |||
662 | state reset { |
773 | state reset { |
|
663 | state_entry() { |
774 | state_entry() { |
|
664 | // DEBUG |
775 | // DEBUG |
|
665 | llOwnerSay("Resetting all visitors..."); |
776 | llOwnerSay("Resetting all visitors..."); |
|
666 | llInstantMessage( |
777 | llInstantMessage( |
|
667 | (key)CORRADE, |
778 | CORRADE, |
|
668 | wasKeyValueEncode( |
779 | wasKeyValueEncode( |
|
669 | [ |
780 | [ |
|
670 | "command", "database", |
781 | "command", "database", |
|
671 | "group", wasURLEscape(GROUP), |
782 | "group", wasURLEscape(GROUP), |
|
672 | "password", wasURLEscape(PASSWORD), |
783 | "password", wasURLEscape(PASSWORD), |
|
673 | "SQL", "DROP TABLE visitors", |
784 | "SQL", wasURLEscape(SQL_DROP_TABLE), |
|
674 | "callback", wasURLEscape(callback) |
785 | "callback", wasURLEscape(callback) |
|
675 | ] |
786 | ] |
|
676 | ) |
787 | ) |
|
677 | ); |
788 | ); |
|
- | 789 | |
||
678 | // alarm 60 |
790 | // alarm 60 |
|
679 | llSetTimerEvent(60); |
791 | llSetTimerEvent(60); |
|
680 | } |
792 | } |
|
681 | timer() { |
793 | timer() { |
|
682 | // DEBUG |
794 | // DEBUG |
|
683 | llOwnerSay("Timeout deleting database..."); |
795 | llOwnerSay("Timeout deleting database..."); |
|
684 | llResetScript(); |
796 | llResetScript(); |
|
685 | } |
797 | } |
|
686 | http_request(key id, string method, string body) { |
798 | http_request(key id, string method, string body) { |
|
687 | llHTTPResponse(id, 200, "OK"); |
799 | llHTTPResponse(id, 200, "OK"); |
|
688 | if(wasKeyValueGet("command", body) != "database") return; |
800 | if(wasKeyValueGet("command", body) == "database") { |
|
689 | if(wasKeyValueGet("success", body) != "True") { |
801 | integer success = wasKeyValueGet("success", body) == "True"; |
|
- | 802 | if(!success) { |
||
690 | // DEBUG |
803 | // DEBUG |
|
691 | llOwnerSay("Failed to drop the visitors table: " + |
804 | llOwnerSay("Failed to drop the visitors table: " + |
|
692 | wasURLUnescape( |
805 | wasURLUnescape( |
|
693 | wasKeyValueGet( |
806 | wasKeyValueGet( |
|
694 | "error", |
807 | "error", |
|
695 | body |
808 | body |
|
- | 809 | ) |
||
696 | ) |
810 | ) |
|
697 | ) |
811 | ); |
|
- | 812 | llResetScript(); |
||
698 | ); |
813 | } |
|
- | 814 | // DEBUG |
||
- | 815 | llOwnerSay("Table dropped..."); |
||
699 | llResetScript(); |
816 | llResetScript(); |
|
700 | } |
817 | } |
|
701 | // DEBUG |
- | ||
702 | llOwnerSay("Table dropped..."); |
- | ||
703 | llResetScript(); |
- | ||
704 | } |
818 | } |
|
705 | on_rez(integer num) { |
819 | on_rez(integer num) { |
|
706 | llResetScript(); |
820 | llResetScript(); |
|
707 | } |
821 | } |
|
708 | changed(integer change) { |
822 | changed(integer change) { |