corrade-lsl-templates – Diff between revs 10 and 11

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 10 Rev 11
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // 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 ///////////////////////////////////////////////////////////////////////////
8   8  
9 /////////////////////////////////////////////////////////////////////////// 9 ///////////////////////////////////////////////////////////////////////////
10 // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // 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);
18 } 18 }
19 /////////////////////////////////////////////////////////////////////////// 19 ///////////////////////////////////////////////////////////////////////////
20 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 20 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
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: GNU GPLv3 //
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) 2011 Wizardry and Steamworks - License: GNU GPLv3 // 47 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
48 /////////////////////////////////////////////////////////////////////////// 48 ///////////////////////////////////////////////////////////////////////////
49 // http://was.fm/secondlife/wanderer 49 // http://was.fm/secondlife/wanderer
50 vector wasCirclePoint(float radius) { 50 vector wasCirclePoint(float radius) {
51 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 51 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
52 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 52 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
53 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) 53 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
54 return <x, y, 0>; 54 return <x, y, 0>;
55 return wasCirclePoint(radius); 55 return wasCirclePoint(radius);
56 } 56 }
57   57  
58 /////////////////////////////////////////////////////////////////////////// 58 ///////////////////////////////////////////////////////////////////////////
59 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 59 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
60 /////////////////////////////////////////////////////////////////////////// 60 ///////////////////////////////////////////////////////////////////////////
61 // escapes a string in conformance with RFC1738 61 // escapes a string in conformance with RFC1738
62 string wasURLEscape(string i) { 62 string wasURLEscape(string i) {
63 string o = ""; 63 string o = "";
64 do { 64 do {
65 string c = llGetSubString(i, 0, 0); 65 string c = llGetSubString(i, 0, 0);
66 i = llDeleteSubString(i, 0, 0); 66 i = llDeleteSubString(i, 0, 0);
67 if(c == "") jump continue; 67 if(c == "") jump continue;
68 if(c == " ") { 68 if(c == " ") {
69 o += "+"; 69 o += "+";
70 jump continue; 70 jump continue;
71 } 71 }
72 if(c == "\n") { 72 if(c == "\n") {
73 o += "%0D" + llEscapeURL(c); 73 o += "%0D" + llEscapeURL(c);
74 jump continue; 74 jump continue;
75 } 75 }
76 o += llEscapeURL(c); 76 o += llEscapeURL(c);
77 @continue; 77 @continue;
78 } while(i != ""); 78 } while(i != "");
79 return o; 79 return o;
80 } 80 }
81   81  
82 /////////////////////////////////////////////////////////////////////////// 82 ///////////////////////////////////////////////////////////////////////////
83 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 83 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
84 /////////////////////////////////////////////////////////////////////////// 84 ///////////////////////////////////////////////////////////////////////////
85 list wasCSVToList(string csv) { 85 list wasCSVToList(string csv) {
86 list l = []; 86 list l = [];
87 list s = []; 87 list s = [];
88 string m = ""; 88 string m = "";
89 do { 89 do {
90 string a = llGetSubString(csv, 0, 0); 90 string a = llGetSubString(csv, 0, 0);
91 csv = llDeleteSubString(csv, 0, 0); 91 csv = llDeleteSubString(csv, 0, 0);
92 if(a == ",") { 92 if(a == ",") {
93 if(llList2String(s, -1) != "\"") { 93 if(llList2String(s, -1) != "\"") {
94 l += m; 94 l += m;
95 m = ""; 95 m = "";
96 jump continue; 96 jump continue;
97 } 97 }
98 m += a; 98 m += a;
99 jump continue; 99 jump continue;
100 } 100 }
101 if(a == "\"" && llGetSubString(csv, 0, 0) == a) { 101 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
102 m += a; 102 m += a;
103 csv = llDeleteSubString(csv, 0, 0); 103 csv = llDeleteSubString(csv, 0, 0);
104 jump continue; 104 jump continue;
105 } 105 }
106 if(a == "\"") { 106 if(a == "\"") {
107 if(llList2String(s, -1) != a) { 107 if(llList2String(s, -1) != a) {
108 s += a; 108 s += a;
109 jump continue; 109 jump continue;
110 } 110 }
111 s = llDeleteSubList(s, -1, -1); 111 s = llDeleteSubList(s, -1, -1);
112 jump continue; 112 jump continue;
113 } 113 }
114 m += a; 114 m += a;
115 @continue; 115 @continue;
116 } while(csv != ""); 116 } while(csv != "");
117 // postcondition: length(s) = 0 117 // postcondition: length(s) = 0
118 return l + m; 118 return l + m;
119 } 119 }
120   120  
121 /////////////////////////////////////////////////////////////////////////// 121 ///////////////////////////////////////////////////////////////////////////
122 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 122 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
123 /////////////////////////////////////////////////////////////////////////// 123 ///////////////////////////////////////////////////////////////////////////
124 string wasListToCSV(list l) { 124 string wasListToCSV(list l) {
125 list v = []; 125 list v = [];
126 do { 126 do {
127 string a = llDumpList2String( 127 string a = llDumpList2String(
128 llParseStringKeepNulls( 128 llParseStringKeepNulls(
129 llList2String( 129 llList2String(
130 l, 130 l,
131 0 131 0
132 ), 132 ),
133 ["\""], 133 ["\""],
134 [] 134 []
135 ), 135 ),
136 "\"\"" 136 "\"\""
137 ); 137 );
138 if(llParseStringKeepNulls( 138 if(llParseStringKeepNulls(
139 a, 139 a,
140 [" ", ",", "\n", "\""], [] 140 [" ", ",", "\n", "\""], []
141 ) != 141 ) !=
142 (list) a 142 (list) a
143 ) a = "\"" + a + "\""; 143 ) a = "\"" + a + "\"";
144 v += a; 144 v += a;
145 l = llDeleteSubList(l, 0, 0); 145 l = llDeleteSubList(l, 0, 0);
146 } while(l != []); 146 } while(l != []);
147 return llDumpList2String(v, ","); 147 return llDumpList2String(v, ",");
148 } 148 }
149   149  
150 /////////////////////////////////////////////////////////////////////////// 150 ///////////////////////////////////////////////////////////////////////////
151 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 151 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
152 /////////////////////////////////////////////////////////////////////////// 152 ///////////////////////////////////////////////////////////////////////////
153 // unescapes a string in conformance with RFC1738 153 // unescapes a string in conformance with RFC1738
154 string wasURLUnescape(string i) { 154 string wasURLUnescape(string i) {
155 return llUnescapeURL( 155 return llUnescapeURL(
156 llDumpList2String( 156 llDumpList2String(
157 llParseString2List( 157 llParseString2List(
158 llDumpList2String( 158 llDumpList2String(
159 llParseString2List( 159 llParseString2List(
160 i, 160 i,
161 ["+"], 161 ["+"],
162 [] 162 []
163 ), 163 ),
164 " " 164 " "
165 ), 165 ),
166 ["%0D%0A"], 166 ["%0D%0A"],
167 [] 167 []
168 ), 168 ),
169 "\n" 169 "\n"
170 ) 170 )
171 ); 171 );
172 } 172 }
173   173  
174 // configuration data 174 // configuration data
175 string configuration = ""; 175 string configuration = "";
176 // callback URL 176 // callback URL
177 string URL = ""; 177 string URL = "";
178 // store message over state. 178 // store message over state.
179 string data = ""; 179 string data = "";
180 string path = ""; 180 string path = "";
181 string jump_state = ""; 181 string jump_state = "";
182   182  
183 default { 183 default {
184 state_entry() { 184 state_entry() {
185 llOwnerSay("[Wiki] Starting..."); 185 llOwnerSay("[Wiki] Starting...");
186 llSetTimerEvent(10); 186 llSetTimerEvent(10);
187 } 187 }
188 link_message(integer sender, integer num, string message, key id) { 188 link_message(integer sender, integer num, string message, key id) {
189 if(id != "configuration") return; 189 if(id != "configuration") return;
190 llOwnerSay("[Wiki] Got configuration..."); 190 llOwnerSay("[Wiki] Got configuration...");
191 configuration = message; 191 configuration = message;
192 jump_state = "create_database"; 192 jump_state = "create_database";
193 state url; 193 state url;
194 } 194 }
195 timer() { 195 timer() {
196 llOwnerSay("[Wiki] Requesting configuration..."); 196 llOwnerSay("[Wiki] Requesting configuration...");
197 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); 197 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
198 } 198 }
199 on_rez(integer num) { 199 on_rez(integer num) {
200 llResetScript(); 200 llResetScript();
201 } 201 }
202 changed(integer change) { 202 changed(integer change) {
203 if((change & CHANGED_INVENTORY) || 203 if((change & CHANGED_INVENTORY) ||
204 (change & CHANGED_REGION_START) || 204 (change & CHANGED_REGION_START) ||
205 (change & CHANGED_OWNER)) { 205 (change & CHANGED_OWNER)) {
206 llResetScript(); 206 llResetScript();
207 } 207 }
208 } 208 }
209 state_exit() { 209 state_exit() {
210 llSetTimerEvent(0); 210 llSetTimerEvent(0);
211 } 211 }
212 } 212 }
213   213  
214 state url { 214 state url {
215 state_entry() { 215 state_entry() {
216 // DEBUG 216 // DEBUG
217 llOwnerSay("[Wiki] Requesting URL..."); 217 llOwnerSay("[Wiki] Requesting URL...");
218 llRequestURL(); 218 llRequestURL();
219 } 219 }
220 http_request(key id, string method, string body) { 220 http_request(key id, string method, string body) {
221 if(method != URL_REQUEST_GRANTED) return; 221 if(method != URL_REQUEST_GRANTED) return;
222 URL = body; 222 URL = body;
223 // DEBUG 223 // DEBUG
224 llOwnerSay("[Wiki] Got URL..."); 224 llOwnerSay("[Wiki] Got URL...");
225 if(jump_state == "create_database") 225 if(jump_state == "create_database")
226 state create_database; 226 state create_database;
227 if(jump_state == "get") 227 if(jump_state == "get")
228 state get; 228 state get;
229 if(jump_state == "set") 229 if(jump_state == "set")
230 state set; 230 state set;
231 if(jump_state == "dir") 231 if(jump_state == "dir")
232 state dir; 232 state dir;
233 if(jump_state == "listen_group") 233 if(jump_state == "listen_group")
234 state listen_group; 234 state listen_group;
235 235
236 // DEBUG 236 // DEBUG
237 llOwnerSay("[Wiki] Jump table corrupted, please contact creator..."); 237 llOwnerSay("[Wiki] Jump table corrupted, please contact creator...");
238 llResetScript(); 238 llResetScript();
239 } 239 }
240 on_rez(integer num) { 240 on_rez(integer num) {
241 llResetScript(); 241 llResetScript();
242 } 242 }
243 changed(integer change) { 243 changed(integer change) {
244 if((change & CHANGED_INVENTORY) || 244 if((change & CHANGED_INVENTORY) ||
245 (change & CHANGED_REGION_START) || 245 (change & CHANGED_REGION_START) ||
246 (change & CHANGED_OWNER)) { 246 (change & CHANGED_OWNER)) {
247 llResetScript(); 247 llResetScript();
248 } 248 }
249 } 249 }
250 } 250 }
251   251  
252 state create_database { 252 state create_database {
253 state_entry() { 253 state_entry() {
254 // DEBUG 254 // DEBUG
255 llOwnerSay("[Wiki] Creating database."); 255 llOwnerSay("[Wiki] Creating database.");
256 llInstantMessage( 256 llInstantMessage(
257 wasKeyValueGet( 257 wasKeyValueGet(
258 "corrade", 258 "corrade",
259 configuration 259 configuration
260 ), 260 ),
261 wasKeyValueEncode( 261 wasKeyValueEncode(
262 [ 262 [
263 "command", "database", 263 "command", "database",
264 "group", wasURLEscape( 264 "group", wasURLEscape(
265 wasKeyValueGet( 265 wasKeyValueGet(
266 "group", 266 "group",
267 configuration 267 configuration
268 ) 268 )
269 ), 269 ),
270 "password", wasURLEscape( 270 "password", wasURLEscape(
271 wasKeyValueGet( 271 wasKeyValueGet(
272 "password", 272 "password",
273 configuration 273 configuration
274 ) 274 )
275 ), 275 ),
-   276 "SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS \"" +
-   277 wasKeyValueGet("wiki table", configuration) +
276 "SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS corradeeggdrop (path text unique collate nocase, data text)"), 278 "\" (path text unique collate nocase, data text)"),
277 "callback", wasURLEscape(URL) 279 "callback", wasURLEscape(URL)
278 ] 280 ]
279 ) 281 )
280 ); 282 );
281 llSetTimerEvent(60); 283 llSetTimerEvent(60);
282 } 284 }
283 http_request(key id, string method, string body) { 285 http_request(key id, string method, string body) {
284 llHTTPResponse(id, 200, "OK"); 286 llHTTPResponse(id, 200, "OK");
285 llReleaseURL(URL); 287 llReleaseURL(URL);
286 if(wasKeyValueGet("command", body) != "database" || 288 if(wasKeyValueGet("command", body) != "database" ||
287 wasKeyValueGet("success", body) != "True") { 289 wasKeyValueGet("success", body) != "True") {
288 // DEBUG 290 // DEBUG
289 llOwnerSay("[Wiki] Unable modify database: " + 291 llOwnerSay("[Wiki] Unable modify database: " +
290 wasURLUnescape( 292 wasURLUnescape(
291 wasKeyValueGet("error", body) 293 wasKeyValueGet("error", body)
292 ) 294 )
293 ); 295 );
294 state listen_group; 296 state listen_group;
295 } 297 }
296 llOwnerSay("[Wiki] Database created!"); 298 llOwnerSay("[Wiki] Database created!");
297 state listen_group; 299 state listen_group;
298 } 300 }
299 timer() { 301 timer() {
300 llReleaseURL(URL); 302 llReleaseURL(URL);
301 state listen_group; 303 state listen_group;
302 } 304 }
303 on_rez(integer num) { 305 on_rez(integer num) {
304 llResetScript(); 306 llResetScript();
305 } 307 }
306 changed(integer change) { 308 changed(integer change) {
307 if((change & CHANGED_INVENTORY) || 309 if((change & CHANGED_INVENTORY) ||
308 (change & CHANGED_REGION_START) || 310 (change & CHANGED_REGION_START) ||
309 (change & CHANGED_OWNER)) { 311 (change & CHANGED_OWNER)) {
310 llResetScript(); 312 llResetScript();
311 } 313 }
312 } 314 }
313 state_exit() { 315 state_exit() {
314 llSetTimerEvent(0); 316 llSetTimerEvent(0);
315 } 317 }
316 } 318 }
317   319  
318 state listen_group { 320 state listen_group {
319 state_entry() { 321 state_entry() {
320 // DEBUG 322 // DEBUG
321 llOwnerSay("[Wiki] Waiting for group messages..."); 323 llOwnerSay("[Wiki] Waiting for group messages...");
322 } 324 }
323 link_message(integer sender, integer num, string message, key id) { 325 link_message(integer sender, integer num, string message, key id) {
324 // We only care about notifications now. 326 // We only care about notifications now.
325 if(id != "notification") 327 if(id != "notification")
326 return; 328 return;
327 329
328 // This script only processes group notifications. 330 // This script only processes group notifications.
329 if(wasKeyValueGet("type", message) != "group") 331 if(wasKeyValueGet("type", message) != "group")
330 return; 332 return;
331 333
332 // Get the sent message. 334 // Get the sent message.
333 data = wasURLUnescape( 335 data = wasURLUnescape(
334 wasKeyValueGet( 336 wasKeyValueGet(
335 "message", 337 "message",
336 message 338 message
337 ) 339 )
338 ); 340 );
-   341
339 342 // Check if this is an eggdrop command.
340 if(llGetSubString(data, 0, 0) != 343 if(llGetSubString(data, 0, 0) !=
341 wasKeyValueGet("command", configuration)) 344 wasKeyValueGet("command", configuration))
342 return; 345 return;
343 346
-   347 // Check if the command matches the current module.
344 list command = llParseString2List(data, 348 list command = llParseString2List(data,
345 [wasKeyValueGet("command", configuration), " "], []); 349 [wasKeyValueGet("command", configuration), " "], ["@"]);
346 if(llList2String(command, 0) != "wiki") 350 if(llList2String(command, 0) != "wiki")
347 return; 351 return;
348 352
349 // Remove command. 353 // Remove command.
350 command = llDeleteSubList(command, 0, 0); 354 command = llDeleteSubList(command, 0, 0);
351 355
352 // Check for supported sub-commands. 356 // Check for supported sub-commands.
353 if(llList2String(command, 0) != "set" && 357 if(llList2String(command, 0) != "set" &&
354 llList2String(command, 0) != "get" && 358 llList2String(command, 0) != "get" &&
355 llList2String(command, 0) != "dir") { 359 llList2String(command, 0) != "dir") {
356 data = "Subcommands are: get, set, dir"; 360 data = "Subcommands are: get, set, dir";
357 state tell; 361 state tell;
358 } 362 }
359 363
360 // Get the sub-command and store it as a jump state. 364 // Get the sub-command and store it as a jump state.
361 jump_state = llList2String(command, 0); 365 jump_state = llList2String(command, 0);
362 366
363 // Remove sub-command. 367 // Remove sub-command.
364 command = llDeleteSubList(command, 0, 0); 368 command = llDeleteSubList(command, 0, 0);
365 369
366 // Get the path parts. 370 // Get the path parts.
367 list path_parts = llParseString2List( 371 list path_parts = llParseString2List(
368 llList2String(command, 0), ["/"], [] 372 llList2String(command, 0), ["/"], []
369 ); 373 );
370 374
371 // Dump the path and store it over states. 375 // Dump the path and store it over states.
372 path = llStringTrim( 376 path = llStringTrim(
373 llDumpList2String( 377 llDumpList2String(
374 path_parts, 378 path_parts,
375 "/" 379 "/"
376 ), 380 ),
377 STRING_TRIM 381 STRING_TRIM
378 ); 382 );
379 383
380 if(path != "") { 384 if(path != "") {
381 integer i = llStringLength(path) - 1; 385 integer i = llStringLength(path) - 1;
382 do { 386 do {
383 string c = llGetSubString(path, i, i); 387 string c = llGetSubString(path, i, i);
384 if(c != "/" && !wasIsAlNum(c)) { 388 if(c != "/" && !wasIsAlNum(c)) {
385 data = "Only alpha-numerics accepted in the path string."; 389 data = "Only alpha-numerics accepted in the path string.";
386 state tell; 390 state tell;
387 } 391 }
388 } while(--i > -1); 392 } while(--i > -1);
389 } 393 }
390 394
391 path = "/" + path; 395 path = "/" + path;
392 396
393 // Remove path. 397 // Remove path.
394 command = llDeleteSubList(command, 0, 0); 398 command = llDeleteSubList(command, 0, 0);
395 399
396 // Dump the rest of the message. 400 // Dump the rest of the message.
397 data = llDumpList2String(command, " "); 401 data = llDumpList2String(command, " ");
398 402
399 // Get an URL. 403 // Get an URL.
400 state url; 404 state url;
401 } 405 }
402 on_rez(integer num) { 406 on_rez(integer num) {
403 llResetScript(); 407 llResetScript();
404 } 408 }
405 changed(integer change) { 409 changed(integer change) {
406 if((change & CHANGED_INVENTORY) || 410 if((change & CHANGED_INVENTORY) ||
407 (change & CHANGED_REGION_START) || 411 (change & CHANGED_REGION_START) ||
408 (change & CHANGED_OWNER)) { 412 (change & CHANGED_OWNER)) {
409 llResetScript(); 413 llResetScript();
410 } 414 }
411 } 415 }
412 } 416 }
413   417  
414 state set { 418 state set {
415 state_entry() { 419 state_entry() {
416 if(data == "") { 420 if(data == "") {
417 // DEBUG 421 // DEBUG
418 llOwnerSay("[Wiki] Removing from database."); 422 llOwnerSay("[Wiki] Removing from database.");
419 llInstantMessage( 423 llInstantMessage(
420 wasKeyValueGet( 424 wasKeyValueGet(
421 "corrade", 425 "corrade",
422 configuration 426 configuration
423 ), 427 ),
424 wasKeyValueEncode( 428 wasKeyValueEncode(
425 [ 429 [
426 "command", "database", 430 "command", "database",
427 "group", wasURLEscape( 431 "group", wasURLEscape(
428 wasKeyValueGet( 432 wasKeyValueGet(
429 "group", 433 "group",
430 configuration 434 configuration
431 ) 435 )
432 ), 436 ),
433 "password", wasURLEscape( 437 "password", wasURLEscape(
434 wasKeyValueGet( 438 wasKeyValueGet(
435 "password", 439 "password",
436 configuration 440 configuration
437 ) 441 )
438 ), 442 ),
439 "SQL", wasURLEscape("DELETE FROM corradeeggdrop WHERE path=:path"), 443 "SQL", wasURLEscape("DELETE FROM \"" +
-   444 wasKeyValueGet("wiki table", configuration) +
-   445 "\" WHERE path=:path"),
-   446 "data", wasURLEscape(
440 "data", wasListToCSV( 447 wasListToCSV(
441 [ 448 [
442 "path", 449 "path",
443 wasURLEscape("path") 450 wasURLEscape("path")
-   451 ]
444 ] 452 )
445 ), 453 ),
446 "callback", wasURLEscape(URL) 454 "callback", wasURLEscape(URL)
447 ] 455 ]
448 ) 456 )
449 ); 457 );
450 llSetTimerEvent(60); 458 llSetTimerEvent(60);
451 return; 459 return;
452 } 460 }
453 // DEBUG 461 // DEBUG
454 llOwnerSay("[Wiki] Adding to database."); 462 llOwnerSay("[Wiki] Adding to database.");
455 llInstantMessage( 463 llInstantMessage(
456 wasKeyValueGet( 464 wasKeyValueGet(
457 "corrade", 465 "corrade",
458 configuration 466 configuration
459 ), 467 ),
460 wasKeyValueEncode( 468 wasKeyValueEncode(
461 [ 469 [
462 "command", "database", 470 "command", "database",
463 "group", wasURLEscape( 471 "group", wasURLEscape(
464 wasKeyValueGet( 472 wasKeyValueGet(
465 "group", 473 "group",
466 configuration 474 configuration
467 ) 475 )
468 ), 476 ),
469 "password", wasURLEscape( 477 "password", wasURLEscape(
470 wasKeyValueGet( 478 wasKeyValueGet(
471 "password", 479 "password",
472 configuration 480 configuration
473 ) 481 )
474 ), 482 ),
-   483 "SQL", wasURLEscape("REPLACE INTO \"" +
-   484 wasKeyValueGet("wiki table", configuration) +
475 "SQL", wasURLEscape("REPLACE INTO corradeeggdrop (path, data) VALUES (:path, :data)"), 485 "\" (path, data) VALUES (:path, :data)"),
-   486 "data", wasURLEscape(
476 "data", wasListToCSV( 487 wasListToCSV(
477 [ 488 [
478 "path", 489 "path",
479 wasURLEscape("path"), 490 wasURLEscape(path),
480 "data", 491 "data",
481 wasURLEscape("data") 492 wasURLEscape(data)
-   493 ]
482 ] 494 )
483 ), 495 ),
484 "callback", wasURLEscape(URL) 496 "callback", wasURLEscape(URL)
485 ] 497 ]
486 ) 498 )
487 ); 499 );
488 llSetTimerEvent(60); 500 llSetTimerEvent(60);
489 } 501 }
490 http_request(key id, string method, string body) { 502 http_request(key id, string method, string body) {
491 llHTTPResponse(id, 200, "OK"); 503 llHTTPResponse(id, 200, "OK");
492 llReleaseURL(URL); 504 llReleaseURL(URL);
493 if(wasKeyValueGet("command", body) != "database" || 505 if(wasKeyValueGet("command", body) != "database" ||
494 wasKeyValueGet("success", body) != "True") { 506 wasKeyValueGet("success", body) != "True") {
495 // DEBUG 507 // DEBUG
496 llOwnerSay("[Wiki] Unable modify database: " + 508 llOwnerSay("[Wiki] Unable modify database: " +
497 wasURLUnescape( 509 wasURLUnescape(
498 wasKeyValueGet("error", body) 510 wasKeyValueGet("error", body)
499 ) 511 )
500 ); 512 );
501 state listen_group; 513 state listen_group;
502 } 514 }
503 if(data == "") { 515 if(data == "") {
504 data = "Deleted from " + path; 516 data = "Deleted from " + path;
505 state tell; 517 state tell;
506 } 518 }
507 data = "Stored into " + path; 519 data = "Stored into " + path;
508 state tell; 520 state tell;
509 } 521 }
510 timer() { 522 timer() {
511 llReleaseURL(URL); 523 llReleaseURL(URL);
512 state listen_group; 524 state listen_group;
513 } 525 }
514 on_rez(integer num) { 526 on_rez(integer num) {
515 llResetScript(); 527 llResetScript();
516 } 528 }
517 changed(integer change) { 529 changed(integer change) {
518 if((change & CHANGED_INVENTORY) || 530 if((change & CHANGED_INVENTORY) ||
519 (change & CHANGED_REGION_START) || 531 (change & CHANGED_REGION_START) ||
520 (change & CHANGED_OWNER)) { 532 (change & CHANGED_OWNER)) {
521 llResetScript(); 533 llResetScript();
522 } 534 }
523 } 535 }
524 state_exit() { 536 state_exit() {
525 llSetTimerEvent(0); 537 llSetTimerEvent(0);
526 } 538 }
527 } 539 }
528   540  
529 state get { 541 state get {
530 state_entry() { 542 state_entry() {
531 // DEBUG 543 // DEBUG
532 llOwnerSay("[Wiki] Retrieving from database."); 544 llOwnerSay("[Wiki] Retrieving from database.");
533 llInstantMessage( 545 llInstantMessage(
534 wasKeyValueGet( 546 wasKeyValueGet(
535 "corrade", 547 "corrade",
536 configuration 548 configuration
537 ), 549 ),
538 wasKeyValueEncode( 550 wasKeyValueEncode(
539 [ 551 [
540 "command", "database", 552 "command", "database",
541 "group", wasURLEscape( 553 "group", wasURLEscape(
542 wasKeyValueGet( 554 wasKeyValueGet(
543 "group", 555 "group",
544 configuration 556 configuration
545 ) 557 )
546 ), 558 ),
547 "password", wasURLEscape( 559 "password", wasURLEscape(
548 wasKeyValueGet( 560 wasKeyValueGet(
549 "password", 561 "password",
550 configuration 562 configuration
551 ) 563 )
552 ), 564 ),
553 "SQL", wasURLEscape("SELECT data FROM corradeeggdrop WHERE path=:path"), 565 "SQL", wasURLEscape("SELECT data FROM \"" +
-   566 wasKeyValueGet("wiki table", configuration) +
-   567 "\" WHERE path=:path"),
-   568 "data", wasURLEscape(
554 "data", wasListToCSV( 569 wasListToCSV(
555 [ 570 [
556 "path", 571 "path",
557 wasURLEscape(path) 572 wasURLEscape(path)
-   573 ]
558 ] 574 )
559 ), 575 ),
560 "callback", wasURLEscape(URL) 576 "callback", wasURLEscape(URL)
561 ] 577 ]
562 ) 578 )
563 ); 579 );
564 llSetTimerEvent(60); 580 llSetTimerEvent(60);
565 } 581 }
566 http_request(key id, string method, string body) { 582 http_request(key id, string method, string body) {
567 llHTTPResponse(id, 200, "OK"); 583 llHTTPResponse(id, 200, "OK");
568 llReleaseURL(URL); 584 llReleaseURL(URL);
569 if(wasKeyValueGet("command", body) != "database" || 585 if(wasKeyValueGet("command", body) != "database" ||
570 wasKeyValueGet("success", body) != "True") { 586 wasKeyValueGet("success", body) != "True") {
571 // DEBUG 587 // DEBUG
572 llOwnerSay("[Wiki] Unable retrieve from database: " + 588 llOwnerSay("[Wiki] Unable retrieve from database: " +
573 wasURLUnescape( 589 wasURLUnescape(
574 wasKeyValueGet("error", body) 590 wasKeyValueGet("error", body)
575 ) 591 )
576 ); 592 );
577 state listen_group; 593 state listen_group;
578 } 594 }
579 595
580 data = llDumpList2String( 596 data = llDumpList2String(
581 llDeleteSubList( 597 llDeleteSubList(
582 wasCSVToList( 598 wasCSVToList(
583 wasURLUnescape( 599 wasURLUnescape(
584 wasKeyValueGet("data", body) 600 wasKeyValueGet("data", body)
585 ) 601 )
586 ), 602 ),
587 0, 603 0,
588 0 604 0
589 ), 605 ),
590 "" 606 ""
591 ); 607 );
592 608
593 if(data == "") { 609 if(data == "") {
594 data = "Sorry, that path contains no data."; 610 data = "Sorry, that path contains no data.";
595 state tell; 611 state tell;
596 } 612 }
597 613
598 data = path + ": " + data; 614 data = path + ": " + data;
599 state tell; 615 state tell;
600 } 616 }
601 timer() { 617 timer() {
602 llReleaseURL(URL); 618 llReleaseURL(URL);
603 state listen_group; 619 state listen_group;
604 } 620 }
605 on_rez(integer num) { 621 on_rez(integer num) {
606 llResetScript(); 622 llResetScript();
607 } 623 }
608 changed(integer change) { 624 changed(integer change) {
609 if((change & CHANGED_INVENTORY) || 625 if((change & CHANGED_INVENTORY) ||
610 (change & CHANGED_REGION_START) || 626 (change & CHANGED_REGION_START) ||
611 (change & CHANGED_OWNER)) { 627 (change & CHANGED_OWNER)) {
612 llResetScript(); 628 llResetScript();
613 } 629 }
614 } 630 }
615 state_exit() { 631 state_exit() {
616 llSetTimerEvent(0); 632 llSetTimerEvent(0);
617 } 633 }
618 } 634 }
619   635  
620 state dir { 636 state dir {
621 state_entry() { 637 state_entry() {
622 // DEBUG 638 // DEBUG
623 llOwnerSay("[Wiki] Listing paths from database."); 639 llOwnerSay("[Wiki] Listing paths from database.");
624 llInstantMessage( 640 llInstantMessage(
625 wasKeyValueGet( 641 wasKeyValueGet(
626 "corrade", 642 "corrade",
627 configuration 643 configuration
628 ), 644 ),
629 wasKeyValueEncode( 645 wasKeyValueEncode(
630 [ 646 [
631 "command", "database", 647 "command", "database",
632 "group", wasURLEscape( 648 "group", wasURLEscape(
633 wasKeyValueGet( 649 wasKeyValueGet(
634 "group", 650 "group",
635 configuration 651 configuration
636 ) 652 )
637 ), 653 ),
638 "password", wasURLEscape( 654 "password", wasURLEscape(
639 wasKeyValueGet( 655 wasKeyValueGet(
640 "password", 656 "password",
641 configuration 657 configuration
642 ) 658 )
643 ), 659 ),
644 "SQL", wasURLEscape("SELECT path FROM corradeeggdrop WHERE path like :path"), 660 "SQL", wasURLEscape("SELECT path FROM \"" +
-   661 wasKeyValueGet("wiki table", configuration) +
-   662 "\" WHERE path like :path"),
-   663 "data", wasURLEscape(
645 "data", wasListToCSV( 664 wasListToCSV(
646 [ 665 [
647 "path", 666 "path",
648 wasURLEscape(path + "%") 667 wasURLEscape(path + "%")
-   668 ]
649 ] 669 )
650 ), 670 ),
651 "callback", wasURLEscape(URL) 671 "callback", wasURLEscape(URL)
652 ] 672 ]
653 ) 673 )
654 ); 674 );
655 llSetTimerEvent(60); 675 llSetTimerEvent(60);
656 } 676 }
657 http_request(key id, string method, string body) { 677 http_request(key id, string method, string body) {
658 llHTTPResponse(id, 200, "OK"); 678 llHTTPResponse(id, 200, "OK");
659 llReleaseURL(URL); 679 llReleaseURL(URL);
660 if(wasKeyValueGet("command", body) != "database" || 680 if(wasKeyValueGet("command", body) != "database" ||
661 wasKeyValueGet("success", body) != "True") { 681 wasKeyValueGet("success", body) != "True") {
662 // DEBUG 682 // DEBUG
663 llOwnerSay("[Wiki] Unable retrieve from database: " + 683 llOwnerSay("[Wiki] Unable retrieve from database: " +
664 wasURLUnescape( 684 wasURLUnescape(
665 wasKeyValueGet("error", body) 685 wasKeyValueGet("error", body)
666 ) 686 )
667 ); 687 );
668 state listen_group; 688 state listen_group;
669 } 689 }
670 690
671 list paths = llList2ListStrided( 691 list paths = llList2ListStrided(
672 llDeleteSubList( 692 llDeleteSubList(
673 wasCSVToList( 693 wasCSVToList(
674 wasURLUnescape( 694 wasURLUnescape(
675 wasKeyValueGet("data", body) 695 wasKeyValueGet("data", body)
676 ) 696 )
677 ), 697 ),
678 0, 698 0,
679 0 699 0
680 ), 700 ),
681 0, 701 0,
682 -1, 702 -1,
683 2 703 2
684 ); 704 );
685 705
686 if(llGetListLength(paths) == 0) { 706 if(llGetListLength(paths) == 0) {
687 data = "Sorry, that path contains no sub-paths."; 707 data = "Sorry, that path contains no sub-paths.";
688 state tell; 708 state tell;
689 } 709 }
690 710
691 // Eliminate path component. 711 // Eliminate path component.
692 if(path == "/") 712 if(path == "/")
693 path = ""; 713 path = "";
694 714
695 list sibling = []; 715 list sibling = [];
696 do { 716 do {
697 // Get the path part. 717 // Get the path part.
698 string part = llList2String(paths, 0); 718 string part = llList2String(paths, 0);
699 719
700 // Remove the path component. 720 // Remove the path component.
701 string child = llStringTrim( 721 string child = llStringTrim(
702 llDumpList2String( 722 llDumpList2String(
703 llParseString2List( 723 llParseString2List(
704 part, 724 part,
705 [path, "/"], 725 [path, "/"],
706 [] 726 []
707 ), 727 ),
708 "/" 728 "/"
709 ), 729 ),
710 STRING_TRIM 730 STRING_TRIM
711 731
712 ); 732 );
713 733
714 integer i = llSubStringIndex(child, "/"); 734 integer i = llSubStringIndex(child, "/");
715 if(i == -1) { 735 if(i == -1) {
716 sibling += path + "/" + child; 736 sibling += path + "/" + child;
717 jump continue; 737 jump continue;
718 } 738 }
719 child = path + "/" + llDeleteSubString(child, i, -1) + "/"; 739 child = path + "/" + llDeleteSubString(child, i, -1) + "/";
720 if(llListFindList(sibling, (list)child) == -1) 740 if(llListFindList(sibling, (list)child) == -1)
721 sibling += child; 741 sibling += child;
722 @continue; 742 @continue;
723 paths = llDeleteSubList(paths, 0, 0); 743 paths = llDeleteSubList(paths, 0, 0);
724 } while(llGetListLength(paths) != 0); 744 } while(llGetListLength(paths) != 0);
725 745
726 data = llList2CSV(sibling); 746 data = llList2CSV(sibling);
727 // GC 747 // GC
728 sibling = []; 748 sibling = [];
729 749
730 state tell; 750 state tell;
731 } 751 }
732 timer() { 752 timer() {
733 llReleaseURL(URL); 753 llReleaseURL(URL);
734 state listen_group; 754 state listen_group;
735 } 755 }
736 on_rez(integer num) { 756 on_rez(integer num) {
737 llResetScript(); 757 llResetScript();
738 } 758 }
739 changed(integer change) { 759 changed(integer change) {
740 if((change & CHANGED_INVENTORY) || 760 if((change & CHANGED_INVENTORY) ||
741 (change & CHANGED_REGION_START) || 761 (change & CHANGED_REGION_START) ||
742 (change & CHANGED_OWNER)) { 762 (change & CHANGED_OWNER)) {
743 llResetScript(); 763 llResetScript();
744 } 764 }
745 } 765 }
746 state_exit() { 766 state_exit() {
747 llSetTimerEvent(0); 767 llSetTimerEvent(0);
748 } 768 }
749 } 769 }
750   770  
751 state tell { 771 state tell {
752 state_entry() { 772 state_entry() {
753 // DEBUG 773 // DEBUG
754 llOwnerSay("[Wiki] Sending to group."); 774 llOwnerSay("[Wiki] Sending to group.");
755 llInstantMessage( 775 llInstantMessage(
756 wasKeyValueGet( 776 wasKeyValueGet(
757 "corrade", 777 "corrade",
758 configuration 778 configuration
759 ), 779 ),
760 wasKeyValueEncode( 780 wasKeyValueEncode(
761 [ 781 [
762 "command", "tell", 782 "command", "tell",
763 "group", wasURLEscape( 783 "group", wasURLEscape(
764 wasKeyValueGet( 784 wasKeyValueGet(
765 "group", 785 "group",
766 configuration 786 configuration
767 ) 787 )
768 ), 788 ),
769 "password", wasURLEscape( 789 "password", wasURLEscape(
770 wasKeyValueGet( 790 wasKeyValueGet(
771 "password", 791 "password",
772 configuration 792 configuration
773 ) 793 )
774 ), 794 ),
775 "entity", "group", 795 "entity", "group",
776 "message", wasURLEscape(data) 796 "message", wasURLEscape(data)
777 ] 797 ]
778 ) 798 )
779 ); 799 );
780 state listen_group; 800 state listen_group;
781 } 801 }
782 } 802 }
783   803