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

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 41 Rev 42
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // 2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // 4 //
5 // An eggdrop-like group bot using Corrade. 5 // An eggdrop-like group bot using Corrade.
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 "";
14 if(llStringLength(k) == 0) return ""; 14 if(llStringLength(k) == 0) return "";
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 ///////////////////////////////////////////////////////////////////////////
-   22 // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 //
-   23 ///////////////////////////////////////////////////////////////////////////
-   24 string wasKeyValueDelete(string k, string data) {
-   25 if(llStringLength(data) == 0) return "";
-   26 if(llStringLength(k) == 0) return "";
-   27 integer i = llListFindList(
-   28 llList2ListStrided(
-   29 llParseString2List(data, ["&", "="], []),
-   30 0, -1, 2
-   31 ),
-   32 [ k ]);
-   33 if(i != -1) return llDumpList2String(
-   34 llDeleteSubList(
-   35 llParseString2List(data, ["&"], []),
-   36 i, i),
-   37 "&");
-   38 return data;
-   39 }
-   40  
21 /////////////////////////////////////////////////////////////////////////// 41 ///////////////////////////////////////////////////////////////////////////
22 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // 42 // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 //
-   43 ///////////////////////////////////////////////////////////////////////////
-   44 string wasKeyValueSet(string k, string v, string data) {
-   45 if(llStringLength(k) == 0) return "";
-   46 if(llStringLength(v) == 0) return "";
-   47 if(llStringLength(data) == 0) return k + "=" + v;
-   48 integer i = llListFindList(
-   49 llList2ListStrided(
-   50 llParseString2List(data, ["&", "="], []),
-   51 0, -1, 2
-   52 ),
-   53 [ k ]);
-   54 if(i != -1) return llDumpList2String(
-   55 llListReplaceList(
-   56 llParseString2List(data, ["&"], []),
-   57 [ k + "=" + v ],
-   58 i, i),
-   59 "&");
-   60 return data + "&" + k + "=" + v;
-   61 }
-   62  
-   63 ///////////////////////////////////////////////////////////////////////////
-   64 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
23 /////////////////////////////////////////////////////////////////////////// 65 ///////////////////////////////////////////////////////////////////////////
24 string wasKeyValueEncode(list data) { 66 string wasKeyValueEncode(list data) {
25 list k = llList2ListStrided(data, 0, -1, 2); 67 list k = llList2ListStrided(data, 0, -1, 2);
26 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 68 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
27 data = []; 69 data = [];
28 do { 70 do {
29 data += llList2String(k, 0) + "=" + llList2String(v, 0); 71 data += llList2String(k, 0) + "=" + llList2String(v, 0);
30 k = llDeleteSubList(k, 0, 0); 72 k = llDeleteSubList(k, 0, 0);
31 v = llDeleteSubList(v, 0, 0); 73 v = llDeleteSubList(v, 0, 0);
32 } while(llGetListLength(k) != 0); 74 } while(llGetListLength(k) != 0);
33 return llDumpList2String(data, "&"); 75 return llDumpList2String(data, "&");
34 } 76 }
35   77  
36 /////////////////////////////////////////////////////////////////////////// 78 ///////////////////////////////////////////////////////////////////////////
37 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 79 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
38 /////////////////////////////////////////////////////////////////////////// 80 ///////////////////////////////////////////////////////////////////////////
39 // escapes a string in conformance with RFC1738 81 // escapes a string in conformance with RFC1738
40 string wasURLEscape(string i) { 82 string wasURLEscape(string i) {
41 string o = ""; 83 string o = "";
42 do { 84 do {
43 string c = llGetSubString(i, 0, 0); 85 string c = llGetSubString(i, 0, 0);
44 i = llDeleteSubString(i, 0, 0); 86 i = llDeleteSubString(i, 0, 0);
45 if(c == "") jump continue; 87 if(c == "") jump continue;
46 if(c == " ") { 88 if(c == " ") {
47 o += "+"; 89 o += "+";
48 jump continue; 90 jump continue;
49 } 91 }
50 if(c == "\n") { 92 if(c == "\n") {
51 o += "%0D" + llEscapeURL(c); 93 o += "%0D" + llEscapeURL(c);
52 jump continue; 94 jump continue;
53 } 95 }
54 o += llEscapeURL(c); 96 o += llEscapeURL(c);
55 @continue; 97 @continue;
56 } while(i != ""); 98 } while(i != "");
57 return o; 99 return o;
58 } 100 }
59   101  
60 /////////////////////////////////////////////////////////////////////////// 102 ///////////////////////////////////////////////////////////////////////////
61 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 103 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
62 /////////////////////////////////////////////////////////////////////////// 104 ///////////////////////////////////////////////////////////////////////////
63 // unescapes a string in conformance with RFC1738 105 // unescapes a string in conformance with RFC1738
64 string wasURLUnescape(string i) { 106 string wasURLUnescape(string i) {
65 return llUnescapeURL( 107 return llUnescapeURL(
66 llDumpList2String( 108 llDumpList2String(
67 llParseString2List( 109 llParseString2List(
68 llDumpList2String( 110 llDumpList2String(
69 llParseString2List( 111 llParseString2List(
70 i, 112 i,
71 ["+"], 113 ["+"],
72 [] 114 []
73 ), 115 ),
74 " " 116 " "
75 ), 117 ),
76 ["%0D%0A"], 118 ["%0D%0A"],
77 [] 119 []
78 ), 120 ),
79 "\n" 121 "\n"
80 ) 122 )
81 ); 123 );
82 } 124 }
83   125  
84 /////////////////////////////////////////////////////////////////////////// 126 ///////////////////////////////////////////////////////////////////////////
85 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 127 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
86 /////////////////////////////////////////////////////////////////////////// 128 ///////////////////////////////////////////////////////////////////////////
87 string wasListToCSV(list l) { 129 string wasListToCSV(list l) {
88 list v = []; 130 list v = [];
89 do { 131 do {
90 string a = llDumpList2String( 132 string a = llDumpList2String(
91 llParseStringKeepNulls( 133 llParseStringKeepNulls(
92 llList2String( 134 llList2String(
93 l, 135 l,
94 0 136 0
95 ), 137 ),
96 ["\""], 138 ["\""],
97 [] 139 []
98 ), 140 ),
99 "\"\"" 141 "\"\""
100 ); 142 );
101 if(llParseStringKeepNulls( 143 if(llParseStringKeepNulls(
102 a, 144 a,
103 [" ", ",", "\n", "\""], [] 145 [" ", ",", "\n", "\""], []
104 ) != 146 ) !=
105 (list) a 147 (list) a
106 ) a = "\"" + a + "\""; 148 ) a = "\"" + a + "\"";
107 v += a; 149 v += a;
108 l = llDeleteSubList(l, 0, 0); 150 l = llDeleteSubList(l, 0, 0);
109 } while(l != []); 151 } while(l != []);
110 return llDumpList2String(v, ","); 152 return llDumpList2String(v, ",");
111 } 153 }
-   154  
-   155 ///////////////////////////////////////////////////////////////////////////
-   156 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
-   157 ///////////////////////////////////////////////////////////////////////////
-   158 list wasCSVToList(string csv) {
-   159 list l = [];
-   160 list s = [];
-   161 string m = "";
-   162 do {
-   163 string a = llGetSubString(csv, 0, 0);
-   164 csv = llDeleteSubString(csv, 0, 0);
-   165 if(a == ",") {
-   166 if(llList2String(s, -1) != "\"") {
-   167 l += m;
-   168 m = "";
-   169 jump continue;
-   170 }
-   171 m += a;
-   172 jump continue;
-   173 }
-   174 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
-   175 m += a;
-   176 csv = llDeleteSubString(csv, 0, 0);
-   177 jump continue;
-   178 }
-   179 if(a == "\"") {
-   180 if(llList2String(s, -1) != a) {
-   181 s += a;
-   182 jump continue;
-   183 }
-   184 s = llDeleteSubList(s, -1, -1);
-   185 jump continue;
-   186 }
-   187 m += a;
-   188 @continue;
-   189 } while(csv != "");
-   190 // postcondition: length(s) = 0
-   191 return l + m;
-   192 }
112   193  
113 // for notecard reading 194 // for notecard reading
114 integer line = 0; 195 integer line = 0;
115 196  
116 // key-value data will be read into this list 197 // key-value data will be read into this list
117 list tuples = []; 198 list tuples = [];
118 string configuration = ""; 199 string configuration = "";
119 // Corrade's online status. 200 // Corrade's online status.
120 integer online = FALSE; 201 integer online = FALSE;
121 integer compatible = FALSE; 202 integer compatible = FALSE;
122 string URL = ""; 203 string URL = "";
123   204  
124 // The notifications to bind to. 205 // The notifications to bind to.
125 list notifications = [ "group", "membership", "login", "MQTT" ]; 206 list notifications = [ "group", "membership", "login", "MQTT" ];
126   207  
127 default { 208 default {
128 state_entry() { 209 state_entry() {
129 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { 210 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
130 llOwnerSay("[Control] Sorry, could not find a configuration inventory notecard."); 211 llOwnerSay("[Control] Sorry, could not find a configuration inventory notecard.");
131 return; 212 return;
132 } 213 }
133 // DEBUG 214 // DEBUG
134 llOwnerSay("[Control] Reading configuration file..."); 215 llOwnerSay("[Control] Reading configuration file...");
135 llGetNotecardLine("configuration", line); 216 llGetNotecardLine("configuration", line);
136 } 217 }
137 dataserver(key id, string data) { 218 dataserver(key id, string data) {
138 if(data == EOF) { 219 if(data == EOF) {
139 // invariant, length(tuples) % 2 == 0 220 // invariant, length(tuples) % 2 == 0
140 if(llGetListLength(tuples) % 2 != 0) { 221 if(llGetListLength(tuples) % 2 != 0) {
141 llOwnerSay("[Control] Error in configuration notecard."); 222 llOwnerSay("[Control] Error in configuration notecard.");
142 return; 223 return;
143 } 224 }
144 key CORRADE = llList2Key( 225 key CORRADE = llList2Key(
145 tuples, 226 tuples,
146 llListFindList( 227 llListFindList(
147 tuples, 228 tuples,
148 [ 229 [
149 "corrade" 230 "corrade"
150 ] 231 ]
151 ) 232 )
152 +1); 233 +1);
153 if(CORRADE == NULL_KEY) { 234 if(CORRADE == NULL_KEY) {
154 llOwnerSay("[Control] Error in configuration notecard: corrade"); 235 llOwnerSay("[Control] Error in configuration notecard: corrade");
155 return; 236 return;
156 } 237 }
157 string GROUP = llList2String( 238 string GROUP = llList2String(
158 tuples, 239 tuples,
159 llListFindList( 240 llListFindList(
160 tuples, 241 tuples,
161 [ 242 [
162 "group" 243 "group"
163 ] 244 ]
164 ) 245 )
165 +1); 246 +1);
166 if(GROUP == "") { 247 if(GROUP == "") {
167 llOwnerSay("[Control] Error in configuration notecard: group"); 248 llOwnerSay("[Control] Error in configuration notecard: group");
168 return; 249 return;
169 } 250 }
170 string PASSWORD = llList2String( 251 string PASSWORD = llList2String(
171 tuples, 252 tuples,
172 llListFindList( 253 llListFindList(
173 tuples, 254 tuples,
174 [ 255 [
175 "password" 256 "password"
176 ] 257 ]
177 ) 258 )
178 +1); 259 +1);
179 if(PASSWORD == "") { 260 if(PASSWORD == "") {
180 llOwnerSay("[Control] Error in configuration notecard: password"); 261 llOwnerSay("[Control] Error in configuration notecard: password");
181 return; 262 return;
182 } 263 }
183 string VERSION = llList2String( 264 string VERSION = llList2String(
184 tuples, 265 tuples,
185 llListFindList( 266 llListFindList(
186 tuples, 267 tuples,
187 [ 268 [
188 "version" 269 "version"
189 ] 270 ]
190 ) 271 )
191 +1); 272 +1);
192 if(VERSION == "") { 273 if(VERSION == "") {
193 llOwnerSay("[Control] Error in configuration notecard: version"); 274 llOwnerSay("[Control] Error in configuration notecard: version");
194 return; 275 return;
195 } 276 }
196 // DEBUG 277 // DEBUG
197 llOwnerSay("[Control] Read configuration notecard..."); 278 llOwnerSay("[Control] Read configuration notecard...");
198 configuration = wasKeyValueEncode(tuples); 279 configuration = wasKeyValueEncode(tuples);
199 // GC 280 // GC
200 tuples = []; 281 tuples = [];
201 state request_url_notifications; 282 state request_url_notifications;
202 } 283 }
203 if(data == "") jump continue; 284 if(data == "") jump continue;
-   285 // No support for inline comments for this one! Needs parsing!
204 integer i = llSubStringIndex(data, "#"); 286 integer i = llSubStringIndex(data, "#");
205 if(i != -1) data = llDeleteSubString(data, i, -1); 287 if(i == 0) data = llDeleteSubString(data, i, -1);
206 list o = llParseString2List(data, ["="], []); 288 list o = llParseString2List(data, ["="], []);
207 // get rid of starting and ending quotes 289 // get rid of starting and ending quotes
208 string k = llDumpList2String( 290 string k = llDumpList2String(
209 llParseString2List( 291 llParseString2List(
210 llStringTrim( 292 llStringTrim(
211 llList2String( 293 llList2String(
212 o, 294 o,
213 0 295 0
214 ), 296 ),
215 STRING_TRIM), 297 STRING_TRIM),
216 ["\""], [] 298 ["\""], []
217 ), "\""); 299 ), "\"");
218 string v = llDumpList2String( 300 string v = llDumpList2String(
219 llParseString2List( 301 llParseString2List(
220 llStringTrim( 302 llStringTrim(
221 llList2String( 303 llList2String(
222 o, 304 o,
223 1 305 1
224 ), 306 ),
225 STRING_TRIM), 307 STRING_TRIM),
226 ["\""], [] 308 ["\""], []
227 ), "\""); 309 ), "\"");
228 if(k == "" || v == "") jump continue; 310 if(k == "" || v == "") jump continue;
229 tuples += k; 311 tuples += k;
230 tuples += v; 312 tuples += v;
231 @continue; 313 @continue;
232 llGetNotecardLine("configuration", ++line); 314 llGetNotecardLine("configuration", ++line);
233 } 315 }
234 attach(key id) { 316 attach(key id) {
235 llResetScript(); 317 llResetScript();
236 } 318 }
237 on_rez(integer num) { 319 on_rez(integer num) {
238 llResetScript(); 320 llResetScript();
239 } 321 }
240 changed(integer change) { 322 changed(integer change) {
241 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 323 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
242 llResetScript(); 324 llResetScript();
243 } 325 }
244 } 326 }
245 } 327 }
246   328  
247 state request_url_notifications { 329 state request_url_notifications {
248 state_entry() { 330 state_entry() {
249 // DEBUG 331 // DEBUG
250 llOwnerSay("[Control] Requesting URL..."); 332 llOwnerSay("[Control] Requesting URL...");
251 llRequestURL(); 333 llRequestURL();
252 } 334 }
253 http_request(key id, string method, string body) { 335 http_request(key id, string method, string body) {
254 if(method != URL_REQUEST_GRANTED) return; 336 if(method != URL_REQUEST_GRANTED) return;
255 URL = body; 337 URL = body;
256 // DEBUG 338 // DEBUG
257 llOwnerSay("[Control] Got URL..."); 339 llOwnerSay("[Control] Got URL...");
258 state unbind_notifications; 340 state unbind_notifications;
259 } 341 }
260 on_rez(integer num) { 342 on_rez(integer num) {
261 llResetScript(); 343 llResetScript();
262 } 344 }
263 changed(integer change) { 345 changed(integer change) {
264 if((change & CHANGED_INVENTORY) || 346 if((change & CHANGED_INVENTORY) ||
265 (change & CHANGED_REGION_START) || 347 (change & CHANGED_REGION_START) ||
266 (change & CHANGED_OWNER)) { 348 (change & CHANGED_OWNER)) {
267 llResetScript(); 349 llResetScript();
268 } 350 }
269 } 351 }
270 } 352 }
271   353  
272 state unbind_notifications { 354 state unbind_notifications {
273 state_entry() { 355 state_entry() {
274 // DEBUG 356 // DEBUG
275 llOwnerSay("[Control] Releasing notifications..."); 357 llOwnerSay("[Control] Releasing notifications...");
276 llInstantMessage( 358 llInstantMessage(
277 (key)wasKeyValueGet( 359 (key)wasKeyValueGet(
278 "corrade", 360 "corrade",
279 configuration 361 configuration
280 ), 362 ),
281 wasKeyValueEncode( 363 wasKeyValueEncode(
282 [ 364 [
283 "command", "notify", 365 "command", "notify",
284 "group", wasURLEscape( 366 "group", wasURLEscape(
285 wasKeyValueGet( 367 wasKeyValueGet(
286 "group", 368 "group",
287 configuration 369 configuration
288 ) 370 )
289 ), 371 ),
290 "password", wasURLEscape( 372 "password", wasURLEscape(
291 wasKeyValueGet( 373 wasKeyValueGet(
292 "password", 374 "password",
293 configuration 375 configuration
294 ) 376 )
295 ), 377 ),
296 "action", "remove", 378 "action", "remove",
297 "tag", wasURLEscape( 379 "tag", wasURLEscape(
298 wasKeyValueGet( 380 wasKeyValueGet(
299 "notification tag", 381 "notification tag",
300 configuration 382 configuration
301 ) 383 )
302 ), 384 ),
303 "callback", wasURLEscape(URL) 385 "callback", wasURLEscape(URL)
304 ] 386 ]
305 ) 387 )
306 ); 388 );
307 llSetTimerEvent(60); 389 llSetTimerEvent(60);
308 } 390 }
309 http_request(key id, string method, string body) { 391 http_request(key id, string method, string body) {
310 llHTTPResponse(id, 200, "OK"); 392 llHTTPResponse(id, 200, "OK");
311 if(wasKeyValueGet("command", body) != "notify" || 393 if(wasKeyValueGet("command", body) != "notify" ||
312 wasKeyValueGet("success", body) != "True") { 394 wasKeyValueGet("success", body) != "True") {
313 // DEBUG 395 // DEBUG
314 llOwnerSay("[Control] Unable to release tag: " + 396 llOwnerSay("[Control] Unable to release tag: " +
315 wasURLUnescape( 397 wasURLUnescape(
316 wasKeyValueGet("error", body) 398 wasKeyValueGet("error", body)
317 ) 399 )
318 ); 400 );
319 llResetScript(); 401 llResetScript();
320 } 402 }
321 state bind_notifications; 403 state bind_notifications;
322 } 404 }
323 timer() { 405 timer() {
324 llOwnerSay("[Control] Timeout releasing notifications"); 406 llOwnerSay("[Control] Timeout releasing notifications");
325 llResetScript(); 407 llResetScript();
326 } 408 }
327 on_rez(integer num) { 409 on_rez(integer num) {
328 llResetScript(); 410 llResetScript();
329 } 411 }
330 changed(integer change) { 412 changed(integer change) {
331 if((change & CHANGED_INVENTORY) || 413 if((change & CHANGED_INVENTORY) ||
332 (change & CHANGED_REGION_START) || 414 (change & CHANGED_REGION_START) ||
333 (change & CHANGED_OWNER)) { 415 (change & CHANGED_OWNER)) {
334 llResetScript(); 416 llResetScript();
335 } 417 }
336 } 418 }
337 state_exit() { 419 state_exit() {
338 llSetTimerEvent(0); 420 llSetTimerEvent(0);
339 } 421 }
340 } 422 }
341   423  
342 state bind_notifications { 424 state bind_notifications {
343 state_entry() { 425 state_entry() {
344 // DEBUG 426 // DEBUG
345 llOwnerSay("[Control] Binding to notifications..."); 427 llOwnerSay("[Control] Binding to notifications...");
346 llInstantMessage( 428 llInstantMessage(
347 wasKeyValueGet( 429 wasKeyValueGet(
348 "corrade", 430 "corrade",
349 configuration 431 configuration
350 ), 432 ),
351 wasKeyValueEncode( 433 wasKeyValueEncode(
352 [ 434 [
353 "command", "notify", 435 "command", "notify",
354 "group", wasURLEscape( 436 "group", wasURLEscape(
355 wasKeyValueGet( 437 wasKeyValueGet(
356 "group", 438 "group",
357 configuration 439 configuration
358 ) 440 )
359 ), 441 ),
360 "password", wasURLEscape( 442 "password", wasURLEscape(
361 wasKeyValueGet( 443 wasKeyValueGet(
362 "password", 444 "password",
363 configuration 445 configuration
364 ) 446 )
365 ), 447 ),
366 "action", "add", 448 "action", "add",
367 "type", wasURLEscape( 449 "type", wasURLEscape(
368 wasListToCSV( 450 wasListToCSV(
369 notifications 451 notifications
370 ) 452 )
371 ), 453 ),
372 "URL", wasURLEscape(URL), 454 "URL", wasURLEscape(URL),
373 "tag", wasURLEscape( 455 "tag", wasURLEscape(
374 wasKeyValueGet( 456 wasKeyValueGet(
375 "notification tag", 457 "notification tag",
376 configuration 458 configuration
377 ) 459 )
378 ), 460 ),
379 "callback", wasURLEscape(URL) 461 "callback", wasURLEscape(URL)
380 ] 462 ]
381 ) 463 )
382 ); 464 );
383 llSetTimerEvent(60); 465 llSetTimerEvent(60);
384 } 466 }
385 http_request(key id, string method, string body) { 467 http_request(key id, string method, string body) {
386 llHTTPResponse(id, 200, "OK"); 468 llHTTPResponse(id, 200, "OK");
387 if(wasKeyValueGet("command", body) != "notify" || 469 if(wasKeyValueGet("command", body) != "notify" ||
388 wasKeyValueGet("success", body) != "True") { 470 wasKeyValueGet("success", body) != "True") {
389 // DEBUG 471 // DEBUG
390 llOwnerSay("[Control] Unable to bind notifications: " + 472 llOwnerSay("[Control] Unable to bind notifications: " +
391 wasURLUnescape( 473 wasURLUnescape(
392 wasKeyValueGet("error", body) 474 wasKeyValueGet("error", body)
393 ) 475 )
394 ); 476 );
395 llResetScript(); 477 llResetScript();
396 } 478 }
397 state serve_configuration; 479 state version_check;
398 } 480 }
399 timer() { 481 timer() {
400 llOwnerSay("[Control] Timeout binding notifications"); 482 llOwnerSay("[Control] Timeout binding notifications");
401 llResetScript(); 483 llResetScript();
402 } 484 }
403 on_rez(integer num) { 485 on_rez(integer num) {
404 llResetScript(); 486 llResetScript();
405 } 487 }
406 changed(integer change) { 488 changed(integer change) {
407 if((change & CHANGED_INVENTORY) || 489 if((change & CHANGED_INVENTORY) ||
408 (change & CHANGED_REGION_START) || 490 (change & CHANGED_REGION_START) ||
409 (change & CHANGED_OWNER)) { 491 (change & CHANGED_OWNER)) {
410 llResetScript(); 492 llResetScript();
411 } 493 }
412 } 494 }
413 state_exit() { 495 state_exit() {
414 llSetTimerEvent(0); 496 llSetTimerEvent(0);
415 } 497 }
416 } 498 }
417   499  
418 state serve_configuration { 500 state version_check {
419 state_entry() { 501 state_entry() {
420 // DEBUG 502 // DEBUG
421 llOwnerSay("[Control] Checking version..."); 503 llOwnerSay("[Control] Checking version...");
422 llInstantMessage( 504 llInstantMessage(
423 wasKeyValueGet( 505 wasKeyValueGet(
424 "corrade", 506 "corrade",
425 configuration 507 configuration
426 ), 508 ),
427 wasKeyValueEncode( 509 wasKeyValueEncode(
428 [ 510 [
429 "command", "version", 511 "command", "version",
430 "group", wasURLEscape( 512 "group", wasURLEscape(
431 wasKeyValueGet( 513 wasKeyValueGet(
432 "group", 514 "group",
433 configuration 515 configuration
434 ) 516 )
435 ), 517 ),
436 "password", wasURLEscape( 518 "password", wasURLEscape(
437 wasKeyValueGet( 519 wasKeyValueGet(
438 "password", 520 "password",
439 configuration 521 configuration
440 ) 522 )
441 ), 523 ),
442 "callback", wasURLEscape(URL) 524 "callback", wasURLEscape(URL)
443 ] 525 ]
444 ) 526 )
445 ); 527 );
446 llSetTimerEvent(60); 528 llSetTimerEvent(60);
447 } 529 }
448 http_request(key id, string method, string body) { 530 http_request(key id, string method, string body) {
449 llHTTPResponse(id, 200, "OK"); 531 llHTTPResponse(id, 200, "OK");
450 llSetTimerEvent(0); 532 llSetTimerEvent(0);
451 if(wasKeyValueGet("command", body) != "version") { -  
452 llMessageLinked(LINK_THIS, 0, body, "notification"); -  
453 return; -  
454 } -  
455 533  
456 if(wasKeyValueGet("success", body) != "True") { 534 if(wasKeyValueGet("success", body) != "True") {
457 llOwnerSay("[Control] Version check failed..."); 535 llOwnerSay("[Control] Version check failed...");
458 return; 536 return;
459 } 537 }
460 538  
461 list v = llParseString2List( 539 list v = llParseString2List(
462 wasKeyValueGet( 540 wasKeyValueGet(
463 "data", 541 "data",
464 body 542 body
465 ), 543 ),
466 ["."], 544 ["."],
467 [] 545 []
468 ); 546 );
469 integer receivedVersion = (integer)(llList2String(v, 0) + llList2String(v, 1)); 547 integer receivedVersion = (integer)(llList2String(v, 0) + llList2String(v, 1));
470 v = llParseString2List( 548 v = llParseString2List(
471 wasKeyValueGet( 549 wasKeyValueGet(
472 "version", 550 "version",
473 configuration 551 configuration
474 ), 552 ),
475 ["."], 553 ["."],
476 [] 554 []
477 ); 555 );
478 integer notecardVersion = (integer)(llList2String(v, 0) + llList2String(v, 1)); 556 integer notecardVersion = (integer)(llList2String(v, 0) + llList2String(v, 1));
479 if(receivedVersion < notecardVersion) { 557 if(receivedVersion < notecardVersion) {
480 llOwnerSay("[Control] Version is incompatible! You need a Corrade of at least version: " + 558 llOwnerSay("[Control] Version is incompatible! You need a Corrade of at least version: " +
481 wasKeyValueGet( 559 wasKeyValueGet(
482 "version", 560 "version",
483 configuration 561 configuration
484 ) + 562 ) +
485 " for this template." 563 " for this template."
486 ); 564 );
487 compatible = FALSE; 565 compatible = FALSE;
488 //llReleaseURL(URL); -  
489 return; 566 return;
490 } 567 }
-   568  
-   569 // Add the URL to the configuration so it can be used for all components.
-   570 configuration = wasKeyValueSet("URL", URL, configuration);
-   571  
491 // DEBUG 572 // DEBUG
492 llOwnerSay("[Control] Version is compatible!"); 573 llOwnerSay("[Control] Version is compatible!");
493 compatible = TRUE; 574 compatible = TRUE;
494 //llReleaseURL(URL); -  
495 return; -  
496 } 575  
497 link_message(integer sender, integer num, string message, key id) { -  
498 if(message != "configuration") return; 576 state serve_configuration;
499 llMessageLinked(LINK_THIS, 0, configuration, "configuration"); -  
500 } 577 }
501 timer() { 578 timer() {
502 llOwnerSay("[Control] Timeout checking version..."); 579 llOwnerSay("[Control] Timeout checking version...");
503 llResetScript(); 580 llResetScript();
504 } 581 }
505 on_rez(integer num) { 582 on_rez(integer num) {
506 llResetScript(); 583 llResetScript();
507 } 584 }
508 changed(integer change) { 585 changed(integer change) {
-   586 if((change & CHANGED_INVENTORY) ||
-   587 (change & CHANGED_REGION_START) ||
-   588 (change & CHANGED_OWNER)) {
-   589 llResetScript();
-   590 }
-   591 }
-   592 state_exit() {
-   593 llSetTimerEvent(0);
-   594 }
-   595 }
-   596  
-   597 state serve_configuration {
-   598 state_entry() {
-   599 // DEBUG
-   600 llOwnerSay("[Control] Serving configuration and passing callbacks...");
-   601 }
-   602 http_request(key id, string method, string body) {
-   603 llHTTPResponse(id, 200, "OK");
-   604  
-   605 if(wasKeyValueGet("command", body) != "") {
-   606 llMessageLinked(LINK_THIS, 0, body, "callback");
-   607 return;
-   608 }
-   609  
-   610 // Check if this group message is from Corrade and passed through Discord.
-   611 if(wasKeyValueGet("type", body) == "group" &&
-   612 llToUpper(wasKeyValueGet("agent", body)) == llToUpper(wasKeyValueGet("corrade", configuration)) &&
-   613 llSubStringIndex(wasURLUnescape(wasKeyValueGet("message", body)), "[Discord]:") != -1) {
-   614  
-   615 // Split message in Discord discriminator and message body.
-   616 list messageSplit = llParseString2List(
-   617 wasURLUnescape(
-   618 wasKeyValueGet("message", body)
-   619 ),
-   620 ["[Discord]:"],
-   621 []
-   622 );
-   623  
-   624 // Retrive the Discord discriminator.
-   625 string did = llStringTrim(
-   626 llList2String(
-   627 messageSplit,
-   628 0
-   629 ),
-   630 STRING_TRIM
-   631 );
-   632  
-   633  
-   634 // Retrieve a list of Discord discriminator that are allowed to send administrative commands.
-   635 list admins = wasCSVToList(wasKeyValueGet("discord admin", configuration));
-   636  
-   637 // If the sender is not amongst the administrative Discord discriminators, then strip the agent details.
-   638 if(llListFindList(admins, [ did ]) == -1) {
-   639 // DEBUG
-   640 llOwnerSay("[Control] Non admin, issuing command, strip the agent details from the command.");
-   641  
-   642 body = wasKeyValueDelete("firstname", body);
-   643 body = wasKeyValueDelete("lastname", body);
-   644 body = wasKeyValueDelete("agent", body);
-   645 }
-   646  
-   647 // Pack the message back without the Discord discriminator identifier.
-   648 body = wasKeyValueSet(
-   649 "message",
-   650 wasURLEscape(
-   651 llStringTrim(
-   652 llList2String(
-   653 messageSplit,
-   654 1
-   655 ),
-   656 STRING_TRIM
-   657 )
-   658 ),
-   659 body
-   660 );
-   661 }
-   662  
-   663 llMessageLinked(LINK_THIS, 0, body, "notification");
-   664 }
-   665 link_message(integer sender, integer num, string message, key id) {
-   666 if(message != "configuration") return;
-   667  
-   668 llMessageLinked(LINK_THIS, 0, configuration, "configuration");
-   669 }
-   670 on_rez(integer num) {
-   671 llResetScript();
-   672 }
-   673 changed(integer change) {
509 if((change & CHANGED_INVENTORY) || 674 if((change & CHANGED_INVENTORY) ||
510 (change & CHANGED_REGION_START) || 675 (change & CHANGED_REGION_START) ||
511 (change & CHANGED_OWNER)) { 676 (change & CHANGED_OWNER)) {
512 llResetScript(); 677 llResetScript();
513 } 678 }
514 } 679 }
515 state_exit() { 680 state_exit() {
516 llSetTimerEvent(0); 681 llSetTimerEvent(0);
517 } 682 }
518 } 683 }
519   684