corrade-lsl-templates – Diff between revs 29 and 38
?pathlinks?
Rev 29 | Rev 38 | |||
---|---|---|---|---|
Line -... | Line 1... | |||
- | 1 | |
||
- | 2 | |
||
1 | /////////////////////////////////////////////////////////////////////////// |
3 | /////////////////////////////////////////////////////////////////////////// |
|
2 | // Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 // |
4 | // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
|
3 | /////////////////////////////////////////////////////////////////////////// |
- | ||
4 | // |
- | ||
5 | // This is a device meant to scan regions and show metrics for the Corrade |
- | ||
6 | // Second Life / OpenSim bot. You can find more details about the bot |
- | ||
7 | // by following the URL: http://was.fm/secondlife/scripted_agents/corrade |
- | ||
8 | // |
- | ||
9 | // The script works in conjunction with a "configuration" notecard and a |
- | ||
10 | // "regions" notecard that must both be placed in the same primitive. |
- | ||
11 | // The purpose of this script is to demonstrate scanning with Corrade and |
- | ||
12 | // you are free to use, change, and commercialize it under the CC BY 2.0 |
- | ||
13 | // license at: https://creativecommons.org/licenses/by/2.0 |
- | ||
14 | // |
- | ||
15 | /////////////////////////////////////////////////////////////////////////// |
5 | /////////////////////////////////////////////////////////////////////////// |
|
16 | |
6 | |
|
17 | /////////////////////////////////////////////////////////////////////////// |
7 | /////////////////////////////////////////////////////////////////////////// |
|
18 | // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // |
8 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
|
19 | /////////////////////////////////////////////////////////////////////////// |
9 | /////////////////////////////////////////////////////////////////////////// |
|
20 | string wasKeyValueGet(string k, string data) { |
10 | string wasKeyValueGet(string k, string data) { |
|
21 | if(llStringLength(data) == 0) return ""; |
11 | if(llStringLength(data) == 0) return ""; |
|
22 | if(llStringLength(k) == 0) return ""; |
12 | if(llStringLength(k) == 0) return ""; |
|
23 | list a = llParseString2List(data, ["&", "="], []); |
13 | list a = llParseStringKeepNulls(data, ["&", "="], []); |
|
24 | integer i = llListFindList(a, [ k ]); |
14 | integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
|
25 | if(i != -1) return llList2String(a, i+1); |
15 | if(i != -1) return llList2String(a, 2*i+1); |
|
26 | return ""; |
16 | return ""; |
|
27 | } |
17 | } |
|
Line 28... | Line 18... | |||
28 | |
18 | |
|
29 | /////////////////////////////////////////////////////////////////////////// |
19 | /////////////////////////////////////////////////////////////////////////// |
|
30 | // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
20 | // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
|
31 | /////////////////////////////////////////////////////////////////////////// |
21 | /////////////////////////////////////////////////////////////////////////// |
|
32 | string wasKeyValueEncode(list data) { |
22 | string wasKeyValueEncode(list data) { |
|
33 | list k = llList2ListStrided(data, 0, -1, 2); |
23 | list k = llList2ListStrided(data, 0, -1, 2); |
|
34 | list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
24 | list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
|
Line 38... | Line 28... | |||
38 | k = llDeleteSubList(k, 0, 0); |
28 | k = llDeleteSubList(k, 0, 0); |
|
39 | v = llDeleteSubList(v, 0, 0); |
29 | v = llDeleteSubList(v, 0, 0); |
|
40 | } while(llGetListLength(k) != 0); |
30 | } while(llGetListLength(k) != 0); |
|
41 | return llDumpList2String(data, "&"); |
31 | return llDumpList2String(data, "&"); |
|
42 | } |
32 | } |
|
43 | |
33 | |
|
44 | /////////////////////////////////////////////////////////////////////////// |
34 | /////////////////////////////////////////////////////////////////////////// |
|
45 | // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
35 | // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
|
46 | /////////////////////////////////////////////////////////////////////////// |
36 | /////////////////////////////////////////////////////////////////////////// |
|
47 | integer wasListCountExclude(list input, list exclude) { |
37 | integer wasListCountExclude(list input, list exclude) { |
|
48 | if(llGetListLength(input) == 0) return 0; |
38 | if(llGetListLength(input) == 0) return 0; |
|
49 | if(llListFindList(exclude, (list)llList2String(input, 0)) == -1) |
39 | if(llListFindList(exclude, (list)llList2String(input, 0)) == -1) |
|
50 | return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); |
40 | return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); |
|
51 | return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); |
41 | return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); |
|
52 | } |
42 | } |
|
53 | |
43 | |
|
54 | /////////////////////////////////////////////////////////////////////////// |
44 | /////////////////////////////////////////////////////////////////////////// |
|
55 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
45 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
56 | /////////////////////////////////////////////////////////////////////////// |
46 | /////////////////////////////////////////////////////////////////////////// |
|
57 | string wasListToCSV(list l) { |
47 | string wasListToCSV(list l) { |
|
58 | list v = []; |
48 | list v = []; |
|
59 | do { |
49 | do { |
|
60 | string a = llDumpList2String( |
50 | string a = llDumpList2String( |
|
61 | llParseStringKeepNulls( |
51 | llParseStringKeepNulls( |
|
62 | llList2String( |
52 | llList2String( |
|
63 | l, |
53 | l, |
|
64 | 0 |
54 | 0 |
|
65 | ), |
55 | ), |
|
66 | ["\""], |
56 | ["\""], |
|
67 | [] |
57 | [] |
|
68 | ), |
58 | ), |
|
69 | "\"\"" |
59 | "\"\"" |
|
70 | ); |
60 | ); |
|
71 | if(llParseStringKeepNulls(a, [" ", ",", "\n"], []) != (list) a) |
61 | if(llParseStringKeepNulls(a, [" ", ",", "\n"], []) != (list) a) |
|
Line 73... | Line 63... | |||
73 | v += a; |
63 | v += a; |
|
74 | l = llDeleteSubList(l, 0, 0); |
64 | l = llDeleteSubList(l, 0, 0); |
|
75 | } while(l != []); |
65 | } while(l != []); |
|
76 | return llDumpList2String(v, ","); |
66 | return llDumpList2String(v, ","); |
|
77 | } |
67 | } |
|
78 | |
68 | |
|
79 | /////////////////////////////////////////////////////////////////////////// |
69 | /////////////////////////////////////////////////////////////////////////// |
|
80 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
70 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
81 | /////////////////////////////////////////////////////////////////////////// |
71 | /////////////////////////////////////////////////////////////////////////// |
|
82 | list wasCSVToList(string csv) { |
72 | list wasCSVToList(string csv) { |
|
83 | list l = []; |
73 | list l = []; |
|
84 | list s = []; |
74 | list s = []; |
|
85 | string m = ""; |
75 | string m = ""; |
|
Line 112... | Line 102... | |||
112 | @continue; |
102 | @continue; |
|
113 | } while(csv != ""); |
103 | } while(csv != ""); |
|
114 | // invariant: length(s) = 0 |
104 | // invariant: length(s) = 0 |
|
115 | return l + m; |
105 | return l + m; |
|
116 | } |
106 | } |
|
117 | |
107 | |
|
118 | /////////////////////////////////////////////////////////////////////////// |
108 | /////////////////////////////////////////////////////////////////////////// |
|
119 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
109 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
120 | /////////////////////////////////////////////////////////////////////////// |
110 | /////////////////////////////////////////////////////////////////////////// |
|
121 | // escapes a string in conformance with RFC1738 |
111 | // escapes a string in conformance with RFC1738 |
|
122 | string wasURLEscape(string i) { |
112 | string wasURLEscape(string i) { |
|
123 | string o = ""; |
113 | string o = ""; |
|
124 | do { |
114 | do { |
|
Line 136... | Line 126... | |||
136 | o += llEscapeURL(c); |
126 | o += llEscapeURL(c); |
|
137 | @continue; |
127 | @continue; |
|
138 | } while(i != ""); |
128 | } while(i != ""); |
|
139 | return o; |
129 | return o; |
|
140 | } |
130 | } |
|
141 | |
131 | |
|
142 | /////////////////////////////////////////////////////////////////////////// |
132 | /////////////////////////////////////////////////////////////////////////// |
|
143 | // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
133 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
144 | /////////////////////////////////////////////////////////////////////////// |
134 | /////////////////////////////////////////////////////////////////////////// |
|
145 | // unescapes a string in conformance with RFC1738 |
135 | // unescapes a string in conformance with RFC1738 |
|
146 | string wasURLUnescape(string i) { |
136 | string wasURLUnescape(string i) { |
|
147 | return llUnescapeURL( |
137 | return llUnescapeURL( |
|
148 | llDumpList2String( |
138 | llDumpList2String( |
|
149 | llParseString2List( |
139 | llParseString2List( |
|
150 | llDumpList2String( |
140 | llDumpList2String( |
|
151 | llParseString2List( |
141 | llParseString2List( |
|
152 | i, |
142 | i, |
|
153 | ["+"], |
143 | ["+"], |
|
154 | [] |
144 | [] |
|
155 | ), |
145 | ), |
|
156 | " " |
146 | " " |
|
157 | ), |
147 | ), |
|
158 | ["%0D%0A"], |
148 | ["%0D%0A"], |
|
159 | [] |
149 | [] |
|
160 | ), |
150 | ), |
|
161 | "\n" |
151 | "\n" |
|
162 | ) |
152 | ) |
|
163 | ); |
153 | ); |
|
164 | } |
154 | } |
|
165 | |
155 | |
|
166 | // corrade data |
156 | // corrade data |
|
167 | string CORRADE = ""; |
157 | string CORRADE = ""; |
|
168 | string GROUP = ""; |
158 | string GROUP = ""; |
|
169 | string PASSWORD = ""; |
159 | string PASSWORD = ""; |
|
- | 160 | float WAIT = 5; |
||
170 | |
161 | |
|
171 | // for holding the callback URL |
162 | // for holding the callback URL |
|
172 | string callback = ""; |
163 | string callback = ""; |
|
173 | |
164 | |
|
174 | // for notecard reading |
165 | // for notecard reading |
|
175 | integer line = 0; |
166 | integer line = 0; |
|
Line 176... | Line 167... | |||
176 | |
167 | |
|
177 | // key-value data will be read into this list |
168 | // key-value data will be read into this list |
|
178 | list tuples = []; |
169 | list tuples = []; |
|
179 | // regions will be stored here |
170 | // regions will be stored here |
|
180 | list regions = []; |
171 | list regions = []; |
|
181 | string region = ""; |
172 | string region = ""; |
|
182 | |
173 | |
|
183 | default { |
174 | default { |
|
184 | state_entry() { |
175 | state_entry() { |
|
185 | if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { |
176 | if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { |
|
186 | llOwnerSay("Sorry, could not find a configuration inventory notecard."); |
177 | llOwnerSay("Sorry, could not find a configuration inventory notecard."); |
|
Line 198... | Line 189... | |||
198 | return; |
189 | return; |
|
199 | } |
190 | } |
|
200 | CORRADE = llList2String( |
191 | CORRADE = llList2String( |
|
201 | tuples, |
192 | tuples, |
|
202 | llListFindList( |
193 | llListFindList( |
|
203 | tuples, |
194 | tuples, |
|
204 | [ |
195 | [ |
|
205 | "corrade" |
196 | "corrade" |
|
206 | ] |
197 | ] |
|
207 | ) |
198 | ) |
|
- | 199 | +1 |
||
208 | +1); |
200 | ); |
|
209 | if(CORRADE == "") { |
201 | if(CORRADE == "") { |
|
210 | llOwnerSay("Error in configuration notecard: corrade"); |
202 | llOwnerSay("Error in configuration notecard: corrade"); |
|
211 | return; |
203 | return; |
|
212 | } |
204 | } |
|
213 | GROUP = llList2String( |
205 | GROUP = llList2String( |
|
214 | tuples, |
206 | tuples, |
|
215 | llListFindList( |
207 | llListFindList( |
|
216 | tuples, |
208 | tuples, |
|
217 | [ |
209 | [ |
|
218 | "group" |
210 | "group" |
|
219 | ] |
211 | ] |
|
220 | ) |
212 | ) |
|
- | 213 | +1 |
||
221 | +1); |
214 | ); |
|
222 | if(GROUP == "") { |
215 | if(GROUP == "") { |
|
223 | llOwnerSay("Error in configuration notecard: group"); |
216 | llOwnerSay("Error in configuration notecard: group"); |
|
224 | return; |
217 | return; |
|
225 | } |
218 | } |
|
226 | PASSWORD = llList2String( |
219 | PASSWORD = llList2String( |
|
227 | tuples, |
220 | tuples, |
|
228 | llListFindList( |
221 | llListFindList( |
|
229 | tuples, |
222 | tuples, |
|
230 | [ |
223 | [ |
|
231 | "password" |
224 | "password" |
|
232 | ] |
225 | ] |
|
233 | ) |
226 | ) |
|
- | 227 | +1 |
||
234 | +1); |
228 | ); |
|
235 | if(PASSWORD == "") { |
229 | if(PASSWORD == "") { |
|
236 | llOwnerSay("Error in configuration notecard: password"); |
230 | llOwnerSay("Error in configuration notecard: password"); |
|
237 | return; |
231 | return; |
|
238 | } |
232 | } |
|
- | 233 | WAIT = (float)llList2String( |
||
- | 234 | tuples, |
||
- | 235 | llListFindList( |
||
- | 236 | tuples, |
||
- | 237 | [ |
||
- | 238 | "wait" |
||
- | 239 | ] |
||
- | 240 | ) |
||
- | 241 | +1 |
||
- | 242 | ); |
||
- | 243 | if(WAIT == 0) { |
||
- | 244 | llOwnerSay("Error in configuration notecard: wait"); |
||
- | 245 | return; |
||
- | 246 | } |
||
239 | // DEBUG |
247 | // DEBUG |
|
240 | llOwnerSay("Read configuration notecard..."); |
248 | llOwnerSay("Read configuration notecard..."); |
|
241 | state read; |
249 | state read; |
|
242 | } |
250 | } |
|
243 | if(data == "") jump continue; |
251 | if(data == "") jump continue; |
|
Line 247... | Line 255... | |||
247 | // get rid of starting and ending quotes |
255 | // get rid of starting and ending quotes |
|
248 | string k = llDumpList2String( |
256 | string k = llDumpList2String( |
|
249 | llParseString2List( |
257 | llParseString2List( |
|
250 | llStringTrim( |
258 | llStringTrim( |
|
251 | llList2String( |
259 | llList2String( |
|
252 | o, |
260 | o, |
|
253 | 0 |
261 | 0 |
|
254 | ), |
262 | ), |
|
255 | STRING_TRIM), |
263 | STRING_TRIM), |
|
256 | ["\""], [] |
264 | ["\""], [] |
|
257 | ), "\""); |
265 | ), "\""); |
|
258 | string v = llDumpList2String( |
266 | string v = llDumpList2String( |
|
259 | llParseString2List( |
267 | llParseString2List( |
|
260 | llStringTrim( |
268 | llStringTrim( |
|
261 | llList2String( |
269 | llList2String( |
|
262 | o, |
270 | o, |
|
263 | 1 |
271 | 1 |
|
264 | ), |
272 | ), |
|
265 | STRING_TRIM), |
273 | STRING_TRIM), |
|
266 | ["\""], [] |
274 | ["\""], [] |
|
267 | ), "\""); |
275 | ), "\""); |
|
268 | if(k == "" || v == "") jump continue; |
276 | if(k == "" || v == "") jump continue; |
|
269 | tuples += k; |
277 | tuples += k; |
|
270 | tuples += v; |
278 | tuples += v; |
|
Line 278... | Line 286... | |||
278 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
286 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
|
279 | llResetScript(); |
287 | llResetScript(); |
|
280 | } |
288 | } |
|
281 | } |
289 | } |
|
282 | } |
290 | } |
|
283 | |
291 | |
|
284 | state read { |
292 | state read { |
|
285 | state_entry() { |
293 | state_entry() { |
|
286 | if(llGetInventoryType("regions") != INVENTORY_NOTECARD) { |
294 | if(llGetInventoryType("regions") != INVENTORY_NOTECARD) { |
|
287 | llOwnerSay("Sorry, could not find a regions inventory notecard."); |
295 | llOwnerSay("Sorry, could not find a regions inventory notecard."); |
|
288 | return; |
296 | return; |
|
Line 350... | Line 358... | |||
350 | // DEBUG |
358 | // DEBUG |
|
351 | llOwnerSay("Corrade is not online, sleeping..."); |
359 | llOwnerSay("Corrade is not online, sleeping..."); |
|
352 | llSetTimerEvent(30); |
360 | llSetTimerEvent(30); |
|
353 | return; |
361 | return; |
|
354 | } |
362 | } |
|
- | 363 | state notify; |
||
- | 364 | } |
||
- | 365 | on_rez(integer num) { |
||
- | 366 | llResetScript(); |
||
- | 367 | } |
||
- | 368 | changed(integer change) { |
||
- | 369 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
||
- | 370 | llResetScript(); |
||
- | 371 | } |
||
- | 372 | } |
||
- | 373 | } |
||
- | 374 | |
||
- | 375 | state notify { |
||
- | 376 | state_entry() { |
||
- | 377 | // Timeout in 60s. |
||
- | 378 | llSetTimerEvent(60); |
||
- | 379 | |
||
- | 380 | // DEBUG |
||
- | 381 | llOwnerSay("Binding to the CAPS notification..."); |
||
- | 382 | llInstantMessage( |
||
- | 383 | (key)CORRADE, |
||
- | 384 | wasKeyValueEncode( |
||
- | 385 | [ |
||
- | 386 | "command", "notify", |
||
- | 387 | "group", wasURLEscape(GROUP), |
||
- | 388 | "password", wasURLEscape(PASSWORD), |
||
- | 389 | "action", "set", |
||
- | 390 | "type", "CAPS", |
||
- | 391 | "URL", wasURLEscape(callback), |
||
- | 392 | "callback", wasURLEscape(callback) |
||
- | 393 | ] |
||
- | 394 | ) |
||
- | 395 | ); |
||
- | 396 | } |
||
- | 397 | http_request(key id, string method, string body) { |
||
- | 398 | llHTTPResponse(id, 200, "OK"); |
||
- | 399 | if(wasKeyValueGet("command", body) != "notify") return; |
||
- | 400 | if(wasKeyValueGet("success", body) != "True") { |
||
- | 401 | // DEBUG |
||
- | 402 | llOwnerSay("Failed to bind to the CAPS notification..."); |
||
- | 403 | llResetScript(); |
||
- | 404 | } |
||
- | 405 | // DEBUG |
||
- | 406 | llOwnerSay("CAPS notification installed..."); |
||
355 | state teleport; |
407 | state teleport; |
|
356 | } |
408 | } |
|
- | 409 | timer() { |
||
- | 410 | // DEBUG |
||
- | 411 | llOwnerSay("Timeout binding to the CAPS notifications..."); |
||
- | 412 | |
||
- | 413 | llResetScript(); |
||
- | 414 | } |
||
357 | on_rez(integer num) { |
415 | on_rez(integer num) { |
|
358 | llResetScript(); |
416 | llResetScript(); |
|
359 | } |
417 | } |
|
360 | changed(integer change) { |
418 | changed(integer change) { |
|
361 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
419 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
|
362 | llResetScript(); |
420 | llResetScript(); |
|
363 | } |
421 | } |
|
364 | } |
422 | } |
|
365 | } |
423 | } |
|
366 | |
424 | |
|
367 | state teleport { |
425 | state teleport { |
|
368 | state_entry() { |
426 | state_entry() { |
|
369 | // Timeout in one minute. |
427 | // Emergency timeout |
|
370 | llSetTimerEvent(60); |
428 | llSetTimerEvent(60); |
|
- | 429 | |
||
371 | // Check that Corrade is online. |
430 | // Check that Corrade is online. |
|
372 | llSensorRepeat("", NULL_KEY, AGENT, 0.1, 0.1, 5); |
431 | llSensorRepeat("", NULL_KEY, AGENT, 0.1, 0.1, 5); |
|
- | 432 | |
||
373 | // Shuffle the regions and grab the next region. |
433 | // Shuffle the regions and grab the next region. |
|
374 | region = llList2String(regions, 0); |
434 | region = llList2String(regions, 0); |
|
375 | regions = llDeleteSubList(regions, 0, 0); |
435 | regions = llDeleteSubList(regions, 0, 0); |
|
376 | regions += region; |
436 | regions += region; |
|
- | 437 | |
||
- | 438 | // The selected region is the current region so reshufle. |
||
- | 439 | if(region == llGetRegionName()) { |
||
- | 440 | // DEBUG |
||
- | 441 | llOwnerSay("Already on current region " + region + ", trying the next region."); |
||
- | 442 | region = llList2String(regions, 0); |
||
- | 443 | regions = llDeleteSubList(regions, 0, 0); |
||
- | 444 | regions += region; |
||
- | 445 | } |
||
- | 446 | |
||
377 | // DEBUG |
447 | // DEBUG |
|
378 | llOwnerSay("Teleporting to: " + region); |
448 | llOwnerSay("Teleporting to: " + region); |
|
- | 449 | |
||
379 | llInstantMessage( |
450 | llInstantMessage( |
|
380 | (key)CORRADE, |
451 | (key)CORRADE, |
|
381 | wasKeyValueEncode( |
452 | wasKeyValueEncode( |
|
382 | [ |
453 | [ |
|
383 | "command", "teleport", |
454 | "command", "teleport", |
|
384 | "group", wasURLEscape(GROUP), |
455 | "group", wasURLEscape(GROUP), |
|
385 | "password", wasURLEscape(PASSWORD), |
456 | "password", wasURLEscape(PASSWORD), |
|
386 | "entity", "region", |
457 | "entity", "region", |
|
387 | "region", wasURLEscape(region), |
458 | "region", wasURLEscape(region), |
|
- | 459 | "position", wasURLEscape((string)<128, 128, 50>), |
||
388 | "callback", wasURLEscape(callback) |
460 | "callback", wasURLEscape(callback) |
|
389 | ] |
461 | ] |
|
390 | ) |
462 | ) |
|
391 | ); |
463 | ); |
|
392 | } |
464 | } |
|
393 | http_request(key id, string method, string body) { |
465 | http_request(key id, string method, string body) { |
|
394 | llHTTPResponse(id, 200, "OK"); |
466 | llHTTPResponse(id, 200, "OK"); |
|
395 | if(wasKeyValueGet("command", body) != "teleport" || |
467 | if(wasKeyValueGet("command", body) == "teleport") { |
|
396 | wasKeyValueGet("success", body) != "True") { |
468 | if(wasKeyValueGet("success", body) == "True") { |
|
- | 469 | // DEBUG |
||
- | 470 | llOwnerSay("Teleported successfully to: " + region + " and waiting for capabiltiies..."); |
||
- | 471 | return; |
||
- | 472 | } |
||
397 | // DEBUG |
473 | // DEBUG |
|
398 | llOwnerSay("Failed to teleport to " + region + " due to: " + |
474 | llOwnerSay("Failed to teleport to " + region + " due to: " + |
|
399 | wasURLUnescape( |
475 | wasURLUnescape( |
|
400 | wasKeyValueGet( |
476 | wasKeyValueGet( |
|
401 | "error", |
477 | "error", |
|
402 | body |
478 | body |
|
403 | ) |
479 | ) |
|
404 | ) |
480 | ) |
|
405 | ); |
481 | ); |
|
406 | // Jump to trampoline for re-entry. |
482 | // Jump to trampoline for re-entry. |
|
407 | state teleport_trampoline; |
483 | state teleport_trampoline; |
|
408 | } |
484 | } |
|
- | 485 | if(wasKeyValueGet("notification", body) == "CAPS") { |
||
- | 486 | string capsRegion = wasURLUnescape( |
||
- | 487 | wasKeyValueGet( |
||
- | 488 | "region", |
||
- | 489 | body |
||
- | 490 | ) |
||
- | 491 | ); |
||
- | 492 | string capsAction = wasURLUnescape( |
||
- | 493 | wasKeyValueGet( |
||
- | 494 | "action", |
||
- | 495 | body |
||
- | 496 | ) |
||
- | 497 | ); |
||
- | 498 | |
||
- | 499 | if(capsRegion == region && capsAction == "start") { |
||
- | 500 | llOwnerSay("Capabiltiies for region " + region + " successfully connected."); |
||
- | 501 | state stats_trampoline; |
||
- | 502 | } |
||
- | 503 | } |
||
- | 504 | } |
||
- | 505 | timer() { |
||
409 | // DEBUG |
506 | // DEBUG |
|
410 | llOwnerSay("Teleported successfully to: " + region); |
507 | llOwnerSay("Timeout receiving capabilities, attempting emergency teleport..."); |
|
411 | state stats_trampoline; |
508 | state teleport_trampoline; |
|
412 | } |
509 | } |
|
413 | no_sensor() { |
510 | no_sensor() { |
|
414 | llRequestAgentData((key)CORRADE, DATA_ONLINE); |
511 | llRequestAgentData((key)CORRADE, DATA_ONLINE); |
|
415 | } |
512 | } |
|
416 | dataserver(key id, string data) { |
513 | dataserver(key id, string data) { |
|
Line 418... | Line 515... | |||
418 | // DEBUG |
515 | // DEBUG |
|
419 | llOwnerSay("Corrade is not online, sleeping..."); |
516 | llOwnerSay("Corrade is not online, sleeping..."); |
|
420 | state detect; |
517 | state detect; |
|
421 | } |
518 | } |
|
422 | } |
519 | } |
|
423 | timer() { |
- | ||
424 | state teleport_trampoline; |
- | ||
425 | } |
- | ||
426 | on_rez(integer num) { |
520 | on_rez(integer num) { |
|
427 | llResetScript(); |
521 | llResetScript(); |
|
428 | } |
522 | } |
|
429 | changed(integer change) { |
523 | changed(integer change) { |
|
430 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
524 | if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { |
|
Line 433... | Line 527... | |||
433 | } |
527 | } |
|
434 | state_exit() { |
528 | state_exit() { |
|
435 | llSetTimerEvent(0); |
529 | llSetTimerEvent(0); |
|
436 | } |
530 | } |
|
437 | } |
531 | } |
|
438 | |
532 | |
|
439 | state teleport_trampoline { |
533 | state teleport_trampoline { |
|
440 | state_entry() { |
534 | state_entry() { |
|
441 | // DEBUG |
535 | // DEBUG |
|
442 | llOwnerSay("Sleeping..."); |
536 | llOwnerSay("Sleeping..."); |
|
443 | llSetTimerEvent(30); |
537 | llSetTimerEvent(WAIT); |
|
444 | } |
538 | } |
|
445 | timer() { |
539 | timer() { |
|
446 | state teleport; |
540 | state teleport; |
|
447 | } |
541 | } |
|
448 | on_rez(integer num) { |
542 | on_rez(integer num) { |
|
Line 455... | Line 549... | |||
455 | } |
549 | } |
|
456 | state_exit() { |
550 | state_exit() { |
|
457 | llSetTimerEvent(0); |
551 | llSetTimerEvent(0); |
|
458 | } |
552 | } |
|
459 | } |
553 | } |
|
460 | |
554 | |
|
461 | state stats_trampoline { |
555 | state stats_trampoline { |
|
462 | state_entry() { |
556 | state_entry() { |
|
463 | // DEBUG |
557 | // DEBUG |
|
464 | llOwnerSay("Sleeping..."); |
558 | llOwnerSay("Sleeping..."); |
|
465 | llSetTimerEvent(10); |
559 | llSetTimerEvent(1); |
|
466 | } |
560 | } |
|
467 | timer() { |
561 | timer() { |
|
468 | state stats; |
562 | state stats; |
|
469 | } |
563 | } |
|
470 | on_rez(integer num) { |
564 | on_rez(integer num) { |
|
Line 477... | Line 571... | |||
477 | } |
571 | } |
|
478 | state_exit() { |
572 | state_exit() { |
|
479 | llSetTimerEvent(0); |
573 | llSetTimerEvent(0); |
|
480 | } |
574 | } |
|
481 | } |
575 | } |
|
482 | |
576 | |
|
483 | state stats { |
577 | state stats { |
|
484 | state_entry() { |
578 | state_entry() { |
|
485 | // Timeout in one minute. |
579 | // Timeout in one minute. |
|
486 | llSetTimerEvent(60); |
580 | llSetTimerEvent(60); |
|
- | 581 | |
||
487 | // Check that Corrade is online. |
582 | // Check that Corrade is online. |
|
488 | llSensorRepeat("", NULL_KEY, AGENT, 0.1, 0.1, 5); |
583 | llSensorRepeat("", NULL_KEY, AGENT, 0.1, 0.1, 5); |
|
- | 584 | |
||
489 | // DEBUG |
585 | // DEBUG |
|
490 | llOwnerSay("Fetching region statistics..."); |
586 | llOwnerSay("Fetching region statistics..."); |
|
491 | llInstantMessage( |
587 | llInstantMessage( |
|
492 | (key)CORRADE, |
588 | (key)CORRADE, |
|
493 | wasKeyValueEncode( |
589 | wasKeyValueEncode( |
|
494 | [ |
590 | [ |
|
495 | "command", "getregiondata", |
591 | "command", "getregiondata", |
|
496 | "group", wasURLEscape(GROUP), |
592 | "group", wasURLEscape(GROUP), |
|
497 | "password", wasURLEscape(PASSWORD), |
593 | "password", wasURLEscape(PASSWORD), |
|
498 | "data", wasListToCSV([ |
594 | "data", wasListToCSV([ |
|
499 | // For a full list see: http://was.fm/secondlife/scripted_agents/corrade/application_programming_interface#get_region_data |
595 | // For a full list see: https://grimore.org/secondlife/scripted_agents/corrade/api/commands/getregiondata |
|
500 | "Stats.LastLag", |
596 | "Stats.LastLag", |
|
501 | "Stats.Agents", |
597 | "Stats.Agents", |
|
502 | "Stats.Dilation", |
598 | "Stats.Dilation", |
|
503 | "Stats.FPS", |
599 | "Stats.FPS", |
|
504 | "Stats.ActiveScripts", |
600 | "Stats.ActiveScripts", |
|
505 | "Stats.ScriptTime", |
601 | "Stats.ScriptTime", |
|
506 | "Stats.Objects", |
602 | "Stats.Objects", |
|
507 | "Stats.PhysicsFPS", |
603 | "Stats.PhysicsFPS", |
|
508 | "Stats.ScriptTime" |
604 | "Stats.ScriptTime" |
|
509 | ]), |
605 | ]), |
|
510 | "callback", wasURLEscape(callback) |
606 | "callback", wasURLEscape(callback) |
|
511 | ] |
607 | ] |
|
512 | ) |
608 | ) |
|
513 | ); |
609 | ); |
|
514 | } |
610 | } |
|
515 | http_request(key id, string method, string body) { |
611 | http_request(key id, string method, string body) { |
|
516 | llHTTPResponse(id, 200, "OK"); |
612 | llHTTPResponse(id, 200, "OK"); |
|
- | 613 | // Ignore CAPS notification here. |
||
- | 614 | if(wasKeyValueGet("notification", body) == "CAPS") { |
||
- | 615 | return; |
||
- | 616 | } |
||
517 | if(wasKeyValueGet("command", body) != "getregiondata" || |
617 | if(wasKeyValueGet("command", body) != "getregiondata" || |
|
518 | wasKeyValueGet("success", body) != "True") { |
618 | wasKeyValueGet("success", body) != "True") { |
|
519 | // DEBUG |
619 | // DEBUG |
|
520 | llOwnerSay("Failed to get stats for " + region + " due to: " + |
620 | llOwnerSay("Failed to get stats for " + region + " due to: " + |
|
521 | wasURLUnescape( |
621 | wasURLUnescape( |
|
522 | wasKeyValueGet( |
622 | wasKeyValueGet( |
|
523 | "error", |
623 | "error", |
|
524 | body |
624 | body |
|
525 | ) |
625 | ) |
|
526 | ) |
626 | ) |
|
527 | ); |
627 | ); |
|
528 | // Jump to trampoline for teleport. |
628 | // Jump to trampoline for teleport. |
|
Line 532... | Line 632... | |||
532 | llOwnerSay("Got stats for region: " + region); |
632 | llOwnerSay("Got stats for region: " + region); |
|
533 | // Get the stats and unescape. |
633 | // Get the stats and unescape. |
|
534 | list stat = wasCSVToList( |
634 | list stat = wasCSVToList( |
|
535 | wasURLUnescape( |
635 | wasURLUnescape( |
|
536 | wasKeyValueGet( |
636 | wasKeyValueGet( |
|
537 | "data", |
637 | "data", |
|
538 | body |
638 | body |
|
539 | ) |
639 | ) |
|
540 | ) |
640 | ) |
|
541 | ); |
641 | ); |
|
542 | llSetText("-:[ " + region + " ]:- \n" + |
642 | llSetText("-:[ " + region + " ]:- \n" + |
|
543 | // Show the stats in the overhead text. |
643 | // Show the stats in the overhead text. |
|
544 | "Agents: " + llList2String( |
644 | "Agents: " + llList2String( |
|
545 | stat, |
645 | stat, |
|
546 | llListFindList( |
646 | llListFindList( |
|
547 | stat, |
647 | stat, |
|
548 | (list)"Stats.Agents" |
648 | (list)"Stats.Agents" |
|
549 | )+1 |
649 | )+1 |
|
550 | ) + "\n" + |
650 | ) + "\n" + |
|
551 | "LastLag: " + llList2String( |
651 | "LastLag: " + llList2String( |
|
552 | stat, |
652 | stat, |
|
553 | llListFindList( |
653 | llListFindList( |
|
554 | stat, |
654 | stat, |
|
555 | (list)"Stats.LastLag" |
655 | (list)"Stats.LastLag" |
|
556 | )+1 |
656 | )+1 |
|
557 | ) + "\n" + |
657 | ) + "\n" + |
|
558 | "Time Dilation: " + llList2String( |
658 | "Time Dilation: " + llList2String( |
|
559 | stat, |
659 | stat, |
|
560 | llListFindList( |
660 | llListFindList( |
|
561 | stat, |
661 | stat, |
|
562 | (list)"Stats.Dilation" |
662 | (list)"Stats.Dilation" |
|
563 | )+1 |
663 | )+1 |
|
564 | ) + "\n" + |
664 | ) + "\n" + |
|
565 | "FPS: " + llList2String( |
665 | "FPS: " + llList2String( |
|
566 | stat, |
666 | stat, |
|
567 | llListFindList( |
667 | llListFindList( |
|
568 | stat, |
668 | stat, |
|
569 | (list)"Stats.FPS" |
669 | (list)"Stats.FPS" |
|
570 | )+1 |
670 | )+1 |
|
571 | ) + "\n" + |
671 | ) + "\n" + |
|
572 | "Physics FPS: " + llList2String( |
672 | "Physics FPS: " + llList2String( |
|
573 | stat, |
673 | stat, |
|
574 | llListFindList( |
674 | llListFindList( |
|
575 | stat, |
675 | stat, |
|
576 | (list)"Stats.PhysicsFPS" |
676 | (list)"Stats.PhysicsFPS" |
|
577 | )+1 |
677 | )+1 |
|
578 | ) + "\n" + |
678 | ) + "\n" + |
|
579 | "Scripts: " + llList2String( |
679 | "Scripts: " + llList2String( |
|
580 | stat, |
680 | stat, |
|
581 | llListFindList( |
681 | llListFindList( |
|
582 | stat, |
682 | stat, |
|
583 | (list)"Stats.ActiveScripts" |
683 | (list)"Stats.ActiveScripts" |
|
584 | )+1 |
684 | )+1 |
|
585 | ) + "\n" + |
685 | ) + "\n" + |
|
586 | "Script Time: " + llList2String( |
686 | "Script Time: " + llList2String( |
|
587 | stat, |
687 | stat, |
|
588 | llListFindList( |
688 | llListFindList( |
|
589 | stat, |
689 | stat, |
|
590 | (list)"Stats.ScriptTime" |
690 | (list)"Stats.ScriptTime" |
|
591 | )+1 |
691 | )+1 |
|
592 | ) + "\n" + |
692 | ) + "\n" + |
|
593 | "Objects: " + llList2String( |
693 | "Objects: " + llList2String( |
|
594 | stat, |
694 | stat, |
|
595 | llListFindList( |
695 | llListFindList( |
|
596 | stat, (list)"Stats.Objects" |
696 | stat, (list)"Stats.Objects" |
|
597 | )+1 |
697 | )+1 |
|
598 | ), |
698 | ), |
|
599 | <1, 0, 0>, |
699 | <1, 0, 0>, |
|
600 | 1.0 |
700 | 1.0 |
|
601 | ); |
701 | ); |
|
602 | stat = []; |
702 | stat = []; |
|
603 | state teleport_trampoline; |
703 | state teleport_trampoline; |
|
604 | } |
704 | } |
|
Line 625... | Line 725... | |||
625 | } |
725 | } |
|
626 | state_exit() { |
726 | state_exit() { |
|
627 | llSetTimerEvent(0); |
727 | llSetTimerEvent(0); |
|
628 | } |
728 | } |
|
629 | } |
729 | } |
|
630 | |
- |