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

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 41 Rev 42
Line 3... Line 3...
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // 4 //
5 // A database-based joke module for Corrade Eggdrop. 5 // A database-based joke module for Corrade Eggdrop.
6 // 6 //
7 /////////////////////////////////////////////////////////////////////////// 7 ///////////////////////////////////////////////////////////////////////////
8 8  
9 /////////////////////////////////////////////////////////////////////////// 9 ///////////////////////////////////////////////////////////////////////////
10 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 10 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
11 /////////////////////////////////////////////////////////////////////////// 11 ///////////////////////////////////////////////////////////////////////////
12 string wasKeyValueGet(string k, string data) { 12 string wasKeyValueGet(string k, string data) {
13 if(llStringLength(data) == 0) return ""; 13 if(llStringLength(data) == 0) return "";
Line 15... Line 15...
15 list a = llParseStringKeepNulls(data, ["&", "="], []); 15 list a = llParseStringKeepNulls(data, ["&", "="], []);
16 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); 16 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
17 if(i != -1) return llList2String(a, 2*i+1); 17 if(i != -1) return llList2String(a, 2*i+1);
18 return ""; 18 return "";
19 } 19 }
20 20  
21 /////////////////////////////////////////////////////////////////////////// 21 ///////////////////////////////////////////////////////////////////////////
22 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // 22 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
23 /////////////////////////////////////////////////////////////////////////// 23 ///////////////////////////////////////////////////////////////////////////
24 string wasKeyValueEncode(list data) { 24 string wasKeyValueEncode(list data) {
25 list k = llList2ListStrided(data, 0, -1, 2); 25 list k = llList2ListStrided(data, 0, -1, 2);
Line 30... Line 30...
30 k = llDeleteSubList(k, 0, 0); 30 k = llDeleteSubList(k, 0, 0);
31 v = llDeleteSubList(v, 0, 0); 31 v = llDeleteSubList(v, 0, 0);
32 } while(llGetListLength(k) != 0); 32 } while(llGetListLength(k) != 0);
33 return llDumpList2String(data, "&"); 33 return llDumpList2String(data, "&");
34 } 34 }
35 35  
36 /////////////////////////////////////////////////////////////////////////// 36 ///////////////////////////////////////////////////////////////////////////
37 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // 37 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
38 /////////////////////////////////////////////////////////////////////////// 38 ///////////////////////////////////////////////////////////////////////////
39 // http://was.fm/secondlife/wanderer 39 // http://was.fm/secondlife/wanderer
40 vector wasCirclePoint(float radius) { 40 vector wasCirclePoint(float radius) {
Line 42... Line 42...
42 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 42 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
43 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) 43 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
44 return <x, y, 0>; 44 return <x, y, 0>;
45 return wasCirclePoint(radius); 45 return wasCirclePoint(radius);
46 } 46 }
47 47  
48 /////////////////////////////////////////////////////////////////////////// 48 ///////////////////////////////////////////////////////////////////////////
49 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 49 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
50 /////////////////////////////////////////////////////////////////////////// 50 ///////////////////////////////////////////////////////////////////////////
51 // escapes a string in conformance with RFC1738 51 // escapes a string in conformance with RFC1738
52 string wasURLEscape(string i) { 52 string wasURLEscape(string i) {
Line 66... Line 66...
66 o += llEscapeURL(c); 66 o += llEscapeURL(c);
67 @continue; 67 @continue;
68 } while(i != ""); 68 } while(i != "");
69 return o; 69 return o;
70 } 70 }
71 71  
72 /////////////////////////////////////////////////////////////////////////// 72 ///////////////////////////////////////////////////////////////////////////
73 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 73 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
74 /////////////////////////////////////////////////////////////////////////// 74 ///////////////////////////////////////////////////////////////////////////
75 list wasCSVToList(string csv) { 75 list wasCSVToList(string csv) {
76 list l = []; 76 list l = [];
Line 105... Line 105...
105 @continue; 105 @continue;
106 } while(csv != ""); 106 } while(csv != "");
107 // postcondition: length(s) = 0 107 // postcondition: length(s) = 0
108 return l + m; 108 return l + m;
109 } 109 }
110 110  
111 /////////////////////////////////////////////////////////////////////////// 111 ///////////////////////////////////////////////////////////////////////////
112 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 112 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
113 /////////////////////////////////////////////////////////////////////////// 113 ///////////////////////////////////////////////////////////////////////////
114 string wasListToCSV(list l) { 114 string wasListToCSV(list l) {
115 list v = []; 115 list v = [];
116 do { 116 do {
117 string a = llDumpList2String( 117 string a = llDumpList2String(
118 llParseStringKeepNulls( 118 llParseStringKeepNulls(
119 llList2String( 119 llList2String(
120 l, 120 l,
121 0 121 0
122 ), 122 ),
123 ["\""], 123 ["\""],
124 [] 124 []
125 ), 125 ),
126 "\"\"" 126 "\"\""
127 ); 127 );
128 if(llParseStringKeepNulls( 128 if(llParseStringKeepNulls(
129 a, 129 a,
130 [" ", ",", "\n", "\""], [] 130 [" ", ",", "\n", "\""], []
131 ) != 131 ) !=
132 (list) a 132 (list) a
133 ) a = "\"" + a + "\""; 133 ) a = "\"" + a + "\"";
134 v += a; 134 v += a;
135 l = llDeleteSubList(l, 0, 0); 135 l = llDeleteSubList(l, 0, 0);
136 } while(l != []); 136 } while(l != []);
137 return llDumpList2String(v, ","); 137 return llDumpList2String(v, ",");
138 } 138 }
139 139  
140 /////////////////////////////////////////////////////////////////////////// 140 ///////////////////////////////////////////////////////////////////////////
141 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 141 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
142 /////////////////////////////////////////////////////////////////////////// 142 ///////////////////////////////////////////////////////////////////////////
143 // unescapes a string in conformance with RFC1738 143 // unescapes a string in conformance with RFC1738
144 string wasURLUnescape(string i) { 144 string wasURLUnescape(string i) {
145 return llUnescapeURL( 145 return llUnescapeURL(
146 llDumpList2String( 146 llDumpList2String(
147 llParseString2List( 147 llParseString2List(
148 llDumpList2String( 148 llDumpList2String(
149 llParseString2List( 149 llParseString2List(
150 i, 150 i,
151 ["+"], 151 ["+"],
152 [] 152 []
153 ), 153 ),
154 " " 154 " "
155 ), 155 ),
156 ["%0D%0A"], 156 ["%0D%0A"],
157 [] 157 []
158 ), 158 ),
159 "\n" 159 "\n"
160 ) 160 )
161 ); 161 );
162 } 162 }
163 163  
164 // configuration data 164 // configuration data
165 string configuration = ""; 165 string configuration = "";
166 // callback URL -  
167 string URL = ""; -  
168 // store message over state. 166 // store message over state.
169 string firstname = ""; 167 string firstname = "";
170 string lastname = ""; 168 string lastname = "";
171 string group = ""; 169 string group = "";
172 string data = ""; 170 string data = "";
-   171 string action = "";
-   172  
173 string jump_state = ""; 173 string statement = "";
174 integer joke_counter = 0; 174 string parameters = "";
175 175  
176 default { 176 default {
177 state_entry() { 177 state_entry() {
178 llOwnerSay("[Joke] Starting module..."); 178 llOwnerSay("[Joke] Starting module...");
179 llSetTimerEvent(10); 179 llSetTimerEvent(10);
180 } 180 }
181 link_message(integer sender, integer num, string message, key id) { 181 link_message(integer sender, integer num, string message, key id) {
182 if(id != "configuration") return; 182 if(id != "configuration") return;
183 llOwnerSay("[Joke] Got configuration..."); 183 llOwnerSay("[Joke] Got configuration...");
184 configuration = message; 184 configuration = message;
185 jump_state = "create_database"; 185 action = "create_database";
186 state url; 186 state trampoline;
187 } 187 }
188 timer() { 188 timer() {
189 llOwnerSay("[Joke] Requesting configuration..."); 189 llOwnerSay("[Joke] Requesting configuration...");
190 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); 190 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
191 } 191 }
192 on_rez(integer num) { 192 on_rez(integer num) {
193 llResetScript(); 193 llResetScript();
194 } 194 }
195 changed(integer change) { 195 changed(integer change) {
196 if((change & CHANGED_INVENTORY) || 196 if((change & CHANGED_INVENTORY) ||
197 (change & CHANGED_REGION_START) || 197 (change & CHANGED_REGION_START) ||
198 (change & CHANGED_OWNER)) { 198 (change & CHANGED_OWNER)) {
199 llResetScript(); 199 llResetScript();
200 } 200 }
201 } 201 }
202 state_exit() { 202 state_exit() {
203 llSetTimerEvent(0); 203 llSetTimerEvent(0);
204 } 204 }
205 } 205 }
206 206  
207 state url { 207 state trampoline {
208 state_entry() { 208 state_entry() {
-   209 if(action == "create_database") {
-   210 statement = wasURLEscape("CREATE TABLE IF NOT EXISTS \"" +
-   211 wasKeyValueGet("joke table", configuration) +
-   212 "\" (data text(1023), name text(35), firstname text(31), lastname text(31), id integer NOT NULL PRIMARY KEY)");
-   213 state query;
209 // DEBUG 214 }
-   215  
-   216 if(action == "random") {
-   217 statement = wasURLEscape("SELECT * FROM \"" +
-   218 wasKeyValueGet("joke table", configuration) +
-   219 "\" WHERE name=:group ORDER BY RANDOM() LIMIT 1");
210 llOwnerSay("[Joke] Requesting URL..."); 220 parameters = wasURLEscape(
-   221 wasListToCSV(
-   222 [
-   223 "group",
-   224 wasURLEscape(
-   225 wasKeyValueGet(
-   226 "group",
-   227 configuration
-   228 )
-   229 )
-   230 ]
-   231 )
-   232 );
-   233  
211 llRequestURL(); 234 state query;
212 } 235 }
-   236  
-   237 if(action == "id") {
-   238 statement = wasURLEscape("SELECT * FROM \"" +
213 http_request(key id, string method, string body) { 239 wasKeyValueGet("joke table", configuration) +
-   240 "\" WHERE name=:group AND id=:id");
-   241 parameters = wasURLEscape(
-   242 wasListToCSV(
-   243 [
-   244 "group",
-   245 wasURLEscape(
-   246 wasKeyValueGet(
-   247 "group",
214 if(method != URL_REQUEST_GRANTED) return; 248 configuration
-   249 )
-   250 ),
-   251 "id",
-   252 data
-   253 ]
215 URL = body; 254 )
216 // DEBUG 255 );
-   256 state query;
-   257 }
-   258  
-   259 if(action == "search") {
-   260 statement = wasURLEscape("SELECT * FROM \"" +
-   261 wasKeyValueGet("joke table", configuration) +
-   262 "\" WHERE name=:group AND data LIKE :data COLLATE NOCASE ORDER BY RANDOM() LIMIT 1");
217 llOwnerSay("[Joke] Got URL..."); 263 parameters = wasURLEscape(
-   264 wasListToCSV(
-   265 [
-   266 "group",
-   267 wasURLEscape(
218 if(jump_state == "create_database") 268 wasKeyValueGet(
-   269 "group",
-   270 configuration
-   271 )
-   272 ),
-   273 "data",
-   274 wasURLEscape("%" + llDumpList2String(llParseString2List(data, [" "], []), "%") + "%")
-   275 ]
-   276 )
-   277 );
219 state create_database; 278 state query;
-   279 }
-   280  
220 if(jump_state == "get") 281 if(action == "remove") {
-   282 statement = wasURLEscape("DELETE FROM \"" +
-   283 wasKeyValueGet("joke table", configuration) +
-   284 "\" WHERE name=:name AND id=:id");
-   285 parameters = wasURLEscape(
-   286 wasListToCSV(
-   287 [
-   288 "name",
-   289 wasURLEscape(
-   290 wasKeyValueGet(
-   291 "group",
-   292 configuration
-   293 )
-   294 ),
-   295 "id",
-   296 data
-   297 ]
-   298 )
-   299 );
221 state get; 300 state query;
-   301 }
-   302  
222 if(jump_state == "add") 303 if(action == "add") {
-   304 statement = wasURLEscape("INSERT INTO \"" +
-   305 wasKeyValueGet("joke table", configuration) +
-   306 "\" (name, data, firstname, lastname) VALUES (:name, :data, :firstname, :lastname)");
-   307 parameters = wasURLEscape(
-   308 wasListToCSV(
223 state add; 309 [
224 if(jump_state == "remove") 310 "name",
-   311 wasURLEscape(
-   312 wasKeyValueGet(
-   313 "group",
-   314 configuration
-   315 )
-   316 ),
-   317 "data",
-   318 wasURLEscape(data),
-   319 "firstname",
-   320 wasURLEscape(firstname),
-   321 "lastname",
-   322 wasURLEscape(lastname)
-   323 ]
-   324 )
-   325 );
225 state remove; 326 state query;
-   327 }
-   328  
226 if(jump_state == "count_jokes") 329 if(action == "get_joke_id") {
-   330 statement = wasURLEscape("SELECT MAX(id) AS LAST FROM \"" +
-   331 wasKeyValueGet("joke table", configuration) + "\"");
227 state count_jokes; 332 state query;
-   333 }
-   334  
-   335 if(action == "by") {
-   336 statement = wasURLEscape("SELECT * FROM \"" +
-   337 wasKeyValueGet("joke table", configuration) +
-   338 "\" WHERE name=:group AND firstname=:firstname AND lastname=:lastname ORDER BY RANDOM() LIMIT 1");
-   339 parameters = wasURLEscape(
-   340 wasListToCSV(
-   341 [
-   342 "group",
-   343 wasURLEscape(
-   344 wasKeyValueGet(
228 if(jump_state == "listen_group") 345 "group",
-   346 configuration
-   347 )
-   348 ),
-   349 "firstname",
-   350 wasURLEscape(firstname),
-   351 "lastname",
-   352 wasURLEscape(lastname)
-   353 ]
-   354 )
-   355 );
-   356  
229 state listen_group; 357 state query;
-   358 }
230 359  
231 // DEBUG 360 // DEBUG
232 llOwnerSay("[Joke] Jump table corrupted, please contact creator..."); 361 llOwnerSay("[Joke] Jump table corrupted, please contact creator...");
233 llResetScript(); 362 llResetScript();
234 } 363 }
235 on_rez(integer num) { 364 on_rez(integer num) {
236 llResetScript(); 365 llResetScript();
237 } 366 }
238 changed(integer change) { 367 changed(integer change) {
239 if((change & CHANGED_INVENTORY) || 368 if((change & CHANGED_INVENTORY) ||
240 (change & CHANGED_REGION_START) || 369 (change & CHANGED_REGION_START) ||
241 (change & CHANGED_OWNER)) { 370 (change & CHANGED_OWNER)) {
242 llResetScript(); 371 llResetScript();
243 } 372 }
244 } 373 }
245 } 374 }
246 375  
247 state create_database { 376 state query {
248 state_entry() { 377 state_entry() {
-   378 // Check messge length.
-   379 string message = wasKeyValueEncode(
-   380 [
-   381 "command", "database",
-   382 "group", wasURLEscape(
-   383 wasKeyValueGet(
-   384 "group",
-   385 configuration
-   386 )
-   387 ),
-   388 "password", wasURLEscape(
-   389 wasKeyValueGet(
-   390 "password",
-   391 configuration
-   392 )
-   393 ),
-   394 "SQL", statement,
-   395 "data", parameters,
-   396 "callback", wasURLEscape(
-   397 wasKeyValueGet(
-   398 "URL",
-   399 configuration
-   400 )
-   401 )
-   402 ]
-   403 );
-   404  
-   405 // GC - none of these are needed anymore.
-   406 statement = "";
-   407 parameters = "";
-   408  
-   409 // Message length check.
-   410 if(llStringLength(message) > 1023) {
-   411 data = "Message length exceeded 1023 characters.";
-   412 state tell;
-   413 }
-   414  
249 // DEBUG 415 // DEBUG
250 llOwnerSay("[Joke] Creating database: " + wasKeyValueGet("joke table", configuration)); 416 llOwnerSay("[Joke] Executing action: " + action);
251 llInstantMessage( 417 llInstantMessage(
252 wasKeyValueGet( 418 wasKeyValueGet(
253 "corrade", 419 "corrade",
254 configuration 420 configuration
255 ), 421 ),
256 wasKeyValueEncode( -  
257 [ -  
258 "command", "database", -  
259 "group", wasURLEscape( -  
260 wasKeyValueGet( -  
261 "group", -  
262 configuration -  
263 ) -  
264 ), -  
265 "password", wasURLEscape( -  
266 wasKeyValueGet( -  
267 "password", -  
268 configuration -  
269 ) -  
270 ), -  
271 "SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + -  
272 wasKeyValueGet("joke table", configuration) + -  
273 "\" (data text(1023), name text(35), firstname text(31), lastname text(31), id integer NOT NULL PRIMARY KEY)"), -  
274 "callback", wasURLEscape(URL) -  
275 ] 422 message
276 ) -  
277 ); 423 );
-   424 // GC
-   425 message = "";
278 llSetTimerEvent(60); 426 llSetTimerEvent(60);
279 } 427 }
280 http_request(key id, string method, string body) { 428 link_message(integer sender, integer num, string body, key id) {
281 llHTTPResponse(id, 200, "OK"); 429 // Only process callbacks for the database command.
282 llReleaseURL(URL); -  
283 if(wasKeyValueGet("command", body) != "database" || 430 if(id != "callback" || wasKeyValueGet("command", body) != "database")
-   431 return;
-   432  
284 wasKeyValueGet("success", body) != "True") { 433 if(wasKeyValueGet("success", body) != "True") {
285 // DEBUG 434 // DEBUG
286 llOwnerSay("[Joke] Unable modify database: " + 435 llOwnerSay("[Joke] Unable query database: " +
287 wasURLUnescape( 436 wasURLUnescape(
288 wasKeyValueGet("error", body) 437 wasKeyValueGet("error", body)
289 ) + 438 )
290 " " + 439 );
-   440 state listen_group;
-   441 }
-   442  
-   443 if(action == "create_database") {
-   444 llOwnerSay("[Joke] Database created!");
-   445 state listen_group;
-   446 }
-   447  
-   448 if(action == "random" || action == "id" || action == "search" || action == "by") {
-   449 list result = wasCSVToList(
291 wasURLUnescape( 450 wasURLUnescape(
292 wasKeyValueGet("data", body) 451 wasKeyValueGet("data", body)
293 ) 452 )
294 -  
295 ); 453 );
-   454  
-   455 if(llGetListLength(result) != 10) {
-   456 data = "No joke found. . .";
296 llResetScript(); 457 state tell;
-   458 }
-   459  
-   460 data = llList2String(
-   461 result,
-   462 llListFindList(result, ["data"]) + 1
-   463 );
-   464  
-   465 firstname = llList2String(
-   466 result,
-   467 llListFindList(result, ["firstname"]) + 1
-   468 );
-   469  
-   470 lastname = llList2String(
-   471 result,
-   472 llListFindList(result, ["lastname"]) + 1
-   473 );
-   474  
-   475 string id = llList2String(
-   476 result,
-   477 llListFindList(result, ["id"]) + 1
-   478 );
-   479  
-   480 // Build data to be sent.
-   481 data += " " + "[" + firstname + " " + lastname + "/" + id + "]";
-   482  
-   483 state tell;
297 } 484 }
298 llOwnerSay("[Joke] Database created!"); -  
299 jump_state = "count_jokes"; -  
300 state url; -  
301 } -  
302 timer() { -  
303 llResetScript(); -  
304 } 485  
305 on_rez(integer num) { -  
306 llResetScript(); -  
307 } -  
308 changed(integer change) { 486 if(action == "remove") {
309 if((change & CHANGED_INVENTORY) || -  
310 (change & CHANGED_REGION_START) || 487 data = "Joke " + data + " has been removed.";
311 (change & CHANGED_OWNER)) { -  
312 llResetScript(); 488 state tell;
313 } 489 }
314 } -  
315 state_exit() { -  
316 llSetTimerEvent(0); -  
317 } -  
318 } -  
Line 319... Line -...
319   -  
320 state count_jokes { -  
321 state_entry() { -  
322 // DEBUG -  
323 llOwnerSay("[Joke] Counting jokes in database: " + wasKeyValueGet("joke table", configuration)); -  
324 llInstantMessage( -  
325 wasKeyValueGet( 490  
326 "corrade", -  
327 configuration -  
328 ), -  
329 wasKeyValueEncode( -  
330 [ -  
331 "command", "database", -  
332 "group", wasURLEscape( -  
333 wasKeyValueGet( 491 if(action == "add") {
334 "group", -  
335 configuration -  
336 ) 492 action = "get_joke_id";
337 ), -  
338 "password", wasURLEscape( -  
339 wasKeyValueGet( -  
340 "password", -  
341 configuration 493 data = body;
342 ) -  
343 ), -  
344 "SQL", wasURLEscape("SELECT COUNT(*) AS count FROM \"" + -  
345 wasKeyValueGet("joke table", configuration) + "\""), -  
346 "callback", wasURLEscape(URL) -  
347 ] -  
348 ) 494 state trampoline;
349 ); -  
350 llSetTimerEvent(60); 495 }
351 } -  
352 http_request(key id, string method, string body) { 496  
353 llHTTPResponse(id, 200, "OK"); -  
354 llReleaseURL(URL); -  
355 if(wasKeyValueGet("command", body) != "database" || -  
356 wasKeyValueGet("success", body) != "True") { -  
357 // DEBUG -  
358 llOwnerSay("[Joke] Unable modify database: " + 497 if(action == "get_joke_id") {
359 wasURLUnescape( -  
360 wasKeyValueGet("error", body) -  
361 ) + -  
362 " " + 498 list result = wasCSVToList(
363 wasURLUnescape( 499 wasURLUnescape(
364 wasKeyValueGet("data", body) 500 wasKeyValueGet("data", body)
365 ) -  
366 501 )
-   502 );
-   503  
-   504 data = llList2String(
-   505 result,
-   506 llListFindList(result, ["LAST"]) + 1
-   507 );
-   508  
367 ); 509 data = "Joke " + data + " has been stored.";
368 llResetScript(); 510 state tell;
369 } 511 }
370 -  
371 list result = wasCSVToList( -  
372 wasURLUnescape( -  
373 wasKeyValueGet("data", body) -  
374 ) -  
375 ); -  
376 -  
377 joke_counter = llList2Integer( -  
378 result, -  
379 llListFindList(result, ["count"]) + 1 512  
380 ) + 1; -  
381 513 // DEBUG
382 llOwnerSay("[Joke] There are " + (string)joke_counter + " jokes in the database."); 514 llOwnerSay("[Joke] Jump table corrupted, please contact creator...");
383 state listen_group; 515 state listen_group;
384 } 516 }
385 timer() { 517 timer() {
386 llResetScript(); 518 state listen_group;
387 } 519 }
388 on_rez(integer num) { 520 on_rez(integer num) {
389 llResetScript(); 521 llResetScript();
390 } 522 }
391 changed(integer change) { 523 changed(integer change) {
392 if((change & CHANGED_INVENTORY) || 524 if((change & CHANGED_INVENTORY) ||
393 (change & CHANGED_REGION_START) || 525 (change & CHANGED_REGION_START) ||
394 (change & CHANGED_OWNER)) { 526 (change & CHANGED_OWNER)) {
395 llResetScript(); 527 llResetScript();
396 } 528 }
397 } 529 }
398 state_exit() { 530 state_exit() {
399 llSetTimerEvent(0); 531 llSetTimerEvent(0);
400 } 532 }
401 } 533 }
402 534  
403 state listen_group { 535 state listen_group {
404 state_entry() { 536 state_entry() {
405 // DEBUG 537 // DEBUG
406 llOwnerSay("[Joke] Waiting for group messages."); 538 llOwnerSay("[Joke] Waiting for group messages.");
407 } 539 }
408 link_message(integer sender, integer num, string message, key id) { 540 link_message(integer sender, integer num, string message, key id) {
409 // We only care about notifications now. 541 // We only care about notifications now.
410 if(id != "notification") 542 if(id != "notification")
411 return; 543 return;
412 544  
413 // This script only processes group notifications. 545 // This script only processes group notifications.
414 if(wasKeyValueGet("type", message) != "group" || 546 if(wasKeyValueGet("type", message) != "group" ||
415 (wasKeyValueGet("type", message) == "group" && 547 (wasKeyValueGet("type", message) == "group" &&
416 wasURLUnescape(wasKeyValueGet("group", message)) != 548 wasURLUnescape(wasKeyValueGet("group", message)) !=
417 wasKeyValueGet("group", configuration))) 549 wasKeyValueGet("group", configuration)))
418 return; 550 return;
419 551  
420 // Get the message sender. 552 // Get the message sender.
421 firstname = wasURLUnescape( 553 firstname = wasURLUnescape(
422 wasKeyValueGet( 554 wasKeyValueGet(
423 "firstname", 555 "firstname",
424 message 556 message
425 ) 557 )
426 ); 558 );
427 559  
428 lastname = wasURLUnescape( 560 lastname = wasURLUnescape(
429 wasKeyValueGet( 561 wasKeyValueGet(
430 "lastname", 562 "lastname",
431 message 563 message
432 ) 564 )
433 ); 565 );
434 566  
435 // Get the sent message. 567 // Get the sent message.
436 data = wasURLUnescape( 568 data = wasURLUnescape(
437 wasKeyValueGet( 569 wasKeyValueGet(
438 "message", 570 "message",
439 message 571 message
440 ) 572 )
441 ); 573 );
442 574  
443 // Check if this is an eggdrop command. 575 // Check if this is an eggdrop command.
444 if(llGetSubString(data, 0, 0) != 576 if(llGetSubString(data, 0, 0) !=
445 wasKeyValueGet("command", configuration)) 577 wasKeyValueGet("command", configuration))
446 return; 578 return;
447 579  
448 // Check if the command matches the current module. 580 // Check if the command matches the current module.
449 list command = llParseString2List(data, [" "], []); 581 list command = llParseString2List(data, [" "], []);
450 if(llList2String(command, 0) != 582 if(llList2String(command, 0) !=
451 wasKeyValueGet("command", configuration) + "joke") 583 wasKeyValueGet("command", configuration) + "joke")
452 return; 584 return;
453 585  
454 // Remove command. 586 // Remove command.
455 command = llDeleteSubList(command, 0, 0); 587 command = llDeleteSubList(command, 0, 0);
456 588  
457 // Remove action. 589 // Remove action.
458 string action = llList2String(command, 0); 590 action = llList2String(command, 0);
459 // Jump to the "add" state for adding 591 // Jump to the "add" state for adding
460 if(action == "add") { 592 if(action == "add") {
461 command = llDeleteSubList(command, 0, 0); 593 command = llDeleteSubList(command, 0, 0);
462 data = llDumpList2String(command, " "); 594 data = llDumpList2String(command, " ");
463 if(data == "") { 595 if(data == "") {
464 data = "The joke's too short to be funny."; 596 data = "The joke's too short to be funny.";
465 state tell; 597 state tell;
466 } 598 }
467 jump_state = "add"; 599 action = "add";
468 state url; 600 state trampoline;
469 } 601 }
470 602  
471 // Jump to the "remove" state for removing 603 // Jump to the "remove" state for removing
472 if(action == "remove") { 604 if(action == "remove") {
473 command = llDeleteSubList(command, 0, 0); 605 command = llDeleteSubList(command, 0, 0);
474 data = llDumpList2String(command, " "); 606 data = llDumpList2String(command, " ");
475 if((integer)data == 0) { 607 if((integer)data == 0) {
476 data = "Which one though? Please provide a joke id."; 608 data = "Which one though? Please provide a joke id.";
477 state tell; 609 state tell;
478 } 610 }
479 jump_state = "remove"; -  
480 state url; -  
481 } -  
482 -  
483 data = llDumpList2String(command, " "); -  
484 if((integer)data <= 0) -  
485 data = ""; -  
486 jump_state = "get"; -  
487 state url; -  
488 } -  
489 on_rez(integer num) { -  
490 llResetScript(); -  
491 } -  
492 changed(integer change) { -  
493 if((change & CHANGED_INVENTORY) || -  
494 (change & CHANGED_REGION_START) || -  
495 (change & CHANGED_OWNER)) { -  
496 llResetScript(); -  
497 } -  
498 } -  
499 } -  
500 -  
501 state get { -  
502 state_entry() { -  
503 // DEBUG -  
504 llOwnerSay("[Joke] Retrieving from database."); -  
505 if(data == "") { -  
506 llInstantMessage( -  
507 wasKeyValueGet( -  
508 "corrade", -  
509 configuration -  
510 ), -  
511 wasKeyValueEncode( -  
512 [ -  
513 "command", "database", -  
514 "group", wasURLEscape( -  
515 wasKeyValueGet( -  
516 "group", -  
517 configuration -  
518 ) -  
519 ), -  
520 "password", wasURLEscape( -  
521 wasKeyValueGet( -  
522 "password", -  
523 configuration -  
524 ) -  
525 ), -  
526 "SQL", wasURLEscape("SELECT * FROM \"" + -  
527 wasKeyValueGet("joke table", configuration) + -  
528 "\" WHERE name=:group LIMIT 1 OFFSET :id"), -  
529 "data", wasURLEscape( -  
530 wasListToCSV( -  
531 [ -  
532 "group", -  
533 wasURLEscape( -  
534 wasKeyValueGet( -  
535 "group", -  
536 configuration -  
537 ) -  
538 ), -  
539 "id", -  
540 (string)( -  
541 (integer)llFrand( -  
542 joke_counter -  
543 ) + 1 -  
544 ) -  
545 ] -  
546 ) -  
547 ), -  
548 "callback", wasURLEscape(URL) -  
549 ] -  
550 ) -  
551 ); -  
552 llSetTimerEvent(60); -  
553 return; -  
554 } -  
555 llInstantMessage( -  
556 wasKeyValueGet( -  
557 "corrade", -  
558 configuration -  
559 ), -  
560 wasKeyValueEncode( -  
561 [ -  
562 "command", "database", -  
563 "group", wasURLEscape( -  
564 wasKeyValueGet( -  
565 "group", -  
566 configuration -  
567 ) -  
568 ), -  
569 "password", wasURLEscape( -  
570 wasKeyValueGet( -  
571 "password", -  
572 configuration -  
573 ) -  
574 ), -  
575 "SQL", wasURLEscape("SELECT * FROM \"" + -  
576 wasKeyValueGet("joke table", configuration) + -  
577 "\" WHERE name=:group AND id=:id"), -  
578 "data", wasURLEscape( -  
579 wasListToCSV( -  
580 [ -  
581 "group", -  
582 wasURLEscape( -  
583 wasKeyValueGet( -  
584 "group", -  
585 configuration -  
586 ) -  
587 ), -  
588 "id", -  
589 data -  
590 ] -  
591 ) -  
592 ), -  
593 "callback", wasURLEscape(URL) -  
594 ] -  
595 ) -  
596 ); -  
597 llSetTimerEvent(60); -  
598 } -  
599 http_request(key id, string method, string body) { -  
600 llHTTPResponse(id, 200, "OK"); -  
601 llReleaseURL(URL); -  
602 if(wasKeyValueGet("command", body) != "database" || -  
603 wasKeyValueGet("success", body) != "True") { -  
604 // DEBUG -  
605 llOwnerSay("[Joke] Unable retrieve from database: " + -  
606 wasURLUnescape( -  
607 wasKeyValueGet("error", body) -  
608 ) -  
609 ); -  
610 state listen_group; -  
611 } -  
612 -  
613 list result = wasCSVToList( -  
614 wasURLUnescape( -  
615 wasKeyValueGet("data", body) -  
616 ) -  
617 ); -  
618 -  
619 if(llGetListLength(result) != 10) { -  
620 data = "No joke found. . ."; 611 action = "remove";
621 state tell; -  
622 } -  
623 -  
624 data = llList2String( -  
625 result, -  
626 llListFindList(result, ["data"]) + 1 -  
627 ); -  
628 -  
629 string firstname = llList2String( -  
630 result, -  
631 llListFindList(result, ["firstname"]) + 1 -  
632 ); -  
633 -  
634 string lastname = llList2String( -  
635 result, -  
636 llListFindList(result, ["lastname"]) + 1 -  
637 ); -  
638 -  
639 string id = llList2String( -  
640 result, -  
641 llListFindList(result, ["id"]) + 1 -  
642 ); -  
643 -  
644 // Build data to be sent. -  
645 data += " " + "[" + firstname + " " + lastname + "/" + id + "]"; -  
646 -  
647 state tell; -  
648 } -  
649 timer() { -  
650 llReleaseURL(URL); -  
651 state listen_group; -  
652 } -  
653 on_rez(integer num) { -  
654 llResetScript(); -  
655 } -  
656 changed(integer change) { -  
657 if((change & CHANGED_INVENTORY) || -  
658 (change & CHANGED_REGION_START) || -  
659 (change & CHANGED_OWNER)) { -  
660 llResetScript(); 612 state trampoline;
661 } -  
662 } -  
663 state_exit() { -  
664 llSetTimerEvent(0); -  
665 } -  
666 } 613 }
667 -  
668 state add { -  
669 state_entry() { -  
670 // DEBUG -  
671 llOwnerSay("[Joke] Adding to database: " + (string)(joke_counter + 1)); -  
672 llInstantMessage( -  
673 wasKeyValueGet( -  
674 "corrade", -  
675 configuration -  
676 ), -  
677 wasKeyValueEncode( -  
678 [ -  
679 "command", "database", -  
680 "group", wasURLEscape( -  
681 wasKeyValueGet( -  
682 "group", -  
683 configuration 614  
684 ) -  
685 ), -  
686 "password", wasURLEscape( -  
687 wasKeyValueGet( 615 if(action == "by") {
688 "password", 616 command = llDeleteSubList(command, 0, 0);
689 configuration -  
690 ) -  
691 ), -  
692 "SQL", wasURLEscape("INSERT INTO \"" + -  
693 wasKeyValueGet("joke table", configuration) + -  
694 "\" (name, data, firstname, lastname, id) VALUES (:name, :data, :firstname, :lastname, :id)"), -  
695 "data", wasURLEscape( -  
696 wasListToCSV( -  
697 [ -  
698 "name", -  
699 wasURLEscape( 617 firstname = llList2String(command, 0);
700 wasKeyValueGet( 618 command = llDeleteSubList(command, 0, 0);
701 "group", 619 lastname = llList2String(command, 0);
702 configuration -  
703 ) -  
704 ), -  
705 "data", 620 command = llDeleteSubList(command, 0, 0);
-   621 data = llDumpList2String(command, " ");
706 wasURLEscape(data), 622  
707 "firstname", -  
708 wasURLEscape(firstname), 623 if(llStringLength(firstname) == 0 ||
709 "lastname", -  
710 wasURLEscape(lastname), -  
711 "id", 624 llStringLength(lastname) == 0) {
712 (string)(joke_counter + 1) -  
713 ] 625 data = "First and Last name is required.";
714 ) -  
715 ), -  
716 "callback", wasURLEscape(URL) -  
717 ] 626 state tell;
718 ) -  
719 ); -  
720 llSetTimerEvent(60); 627 }
721 } -  
722 http_request(key id, string method, string body) { -  
723 llHTTPResponse(id, 200, "OK"); -  
724 llReleaseURL(URL); -  
725 if(wasKeyValueGet("command", body) != "database" || -  
726 wasKeyValueGet("success", body) != "True") { -  
727 // DEBUG -  
728 llOwnerSay("[Joke] Unable modify database: " + -  
729 wasURLUnescape( -  
730 wasKeyValueGet("data", body) 628  
731 ) -  
732 ); 629 action = "by";
733 state listen_group; 630 state trampoline;
734 } -  
735 ++joke_counter; -  
736 data = "Joke " + (string)joke_counter + " has been stored."; -  
737 state tell; 631 }
738 } -  
739 timer() { 632  
740 llReleaseURL(URL); 633 string index = llList2String(command, 0);
741 state listen_group; 634 command = llDeleteSubList(command, 0, 0);
742 } -  
743 on_rez(integer num) { 635  
744 llResetScript(); 636 data = llDumpList2String(command, " ");
745 } 637  
746 changed(integer change) { -  
747 if((change & CHANGED_INVENTORY) || -  
748 (change & CHANGED_REGION_START) || 638 if(index == "search") {
749 (change & CHANGED_OWNER)) { 639 action = "search";
750 llResetScript(); 640 state trampoline;
751 } -  
752 } -  
753 state_exit() { -  
754 llSetTimerEvent(0); -  
755 } -  
Line 756... Line -...
756 } -  
757   -  
758 state remove { -  
759 state_entry() { -  
760 // DEBUG -  
761 llOwnerSay("[Joke] Removing from database."); -  
762 llInstantMessage( -  
763 wasKeyValueGet( -  
764 "corrade", -  
765 configuration -  
766 ), -  
767 wasKeyValueEncode( -  
768 [ -  
769 "command", "database", -  
770 "group", wasURLEscape( -  
771 wasKeyValueGet( -  
772 "group", -  
773 configuration -  
774 ) -  
775 ), -  
776 "password", wasURLEscape( -  
777 wasKeyValueGet( -  
778 "password", -  
779 configuration -  
780 ) -  
781 ), -  
782 "SQL", wasURLEscape("DELETE FROM \"" + -  
783 wasKeyValueGet("joke table", configuration) + -  
784 "\" WHERE name=:name AND id=:id"), -  
785 "data", wasURLEscape( -  
786 wasListToCSV( -  
787 [ -  
788 "name", -  
789 wasURLEscape( -  
790 wasKeyValueGet( -  
791 "group", -  
792 configuration 641 }
793 ) -  
794 ), -  
795 "id", 642  
796 data -  
797 ] -  
798 ) -  
799 ), -  
800 "callback", wasURLEscape(URL) -  
801 ] -  
802 ) -  
803 ); -  
804 llSetTimerEvent(60); -  
805 } -  
806 http_request(key id, string method, string body) { -  
807 llHTTPResponse(id, 200, "OK"); -  
808 llReleaseURL(URL); -  
809 if(wasKeyValueGet("command", body) != "database" || -  
810 wasKeyValueGet("success", body) != "True") { -  
811 // DEBUG -  
812 llOwnerSay("[Joke] Unable modify database: " + -  
813 wasURLUnescape( -  
814 wasKeyValueGet("error", body) -  
815 ) 643 if((integer)index <= 0) {
816 ); 644 action = "random";
-   645 state trampoline;
817 state listen_group; 646 }
818 } -  
819 --joke_counter; 647  
820 data = "Joke " + data + " has been removed."; -  
821 state tell; -  
822 } -  
823 timer() { 648 data = index;
824 llReleaseURL(URL); 649 action = "id";
825 state listen_group; 650 state trampoline;
826 } 651 }
827 on_rez(integer num) { 652 on_rez(integer num) {
828 llResetScript(); 653 llResetScript();
829 } 654 }
830 changed(integer change) { 655 changed(integer change) {
831 if((change & CHANGED_INVENTORY) || 656 if((change & CHANGED_INVENTORY) ||
832 (change & CHANGED_REGION_START) || 657 (change & CHANGED_REGION_START) ||
833 (change & CHANGED_OWNER)) { 658 (change & CHANGED_OWNER)) {
834 llResetScript(); 659 llResetScript();
835 } -  
836 } -  
837 state_exit() { -  
838 llSetTimerEvent(0); 660 }
839 } 661 }
840 } 662 }
841 663  
842 state tell { 664 state tell {
843 state_entry() { 665 state_entry() {
844 // DEBUG 666 // DEBUG
845 llOwnerSay("[Joke] Sending to group."); 667 llOwnerSay("[Joke] Sending to group.");
846 llInstantMessage( 668 llInstantMessage(
847 wasKeyValueGet( 669 wasKeyValueGet(
848 "corrade", 670 "corrade",
849 configuration 671 configuration
850 ), 672 ),
851 wasKeyValueEncode( 673 wasKeyValueEncode(
852 [ 674 [
853 "command", "tell", 675 "command", "tell",
854 "group", wasURLEscape( 676 "group", wasURLEscape(
855 wasKeyValueGet( 677 wasKeyValueGet(
856 "group", 678 "group",
857 configuration 679 configuration
858 ) 680 )
859 ), 681 ),
860 "password", wasURLEscape( 682 "password", wasURLEscape(
861 wasKeyValueGet( 683 wasKeyValueGet(
862 "password", 684 "password",
863 configuration 685 configuration
864 ) 686 )
865 ), 687 ),