corrade-lsl-templates – Diff between revs 29 and 37

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 29 Rev 37
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 // 2 // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // 4 //
5 // This is an automatic teleporter, and patrol script for the Corrade 5 // This is an automatic teleporter, and patrol script for the Corrade
6 // Second Life / OpenSim bot. You can find more details about the bot 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 7 // by following the URL: http://was.fm/secondlife/scripted_agents/corrade
8 // 8 //
9 // The purpose of this script is to demonstrate patroling with Corrade and 9 // The purpose of this script is to demonstrate patroling with Corrade and
10 // you are free to use, change, and commercialize it under the CC BY 2.0 10 // you are free to use, change, and commercialize it under the GNU/GPLv3
11 // license which can be found at: https://creativecommons.org/licenses/by/2.0 11 // license which can be found at: http://www.gnu.org/licenses/gpl.html
12 // 12 //
13 /////////////////////////////////////////////////////////////////////////// 13 ///////////////////////////////////////////////////////////////////////////
14   14  
15 /////////////////////////////////////////////////////////////////////////// 15 ///////////////////////////////////////////////////////////////////////////
16 // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // 16 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
17 /////////////////////////////////////////////////////////////////////////// 17 ///////////////////////////////////////////////////////////////////////////
18 string wasKeyValueGet(string k, string data) { 18 string wasKeyValueGet(string k, string data) {
19 if(llStringLength(data) == 0) return ""; 19 if(llStringLength(data) == 0) return "";
20 if(llStringLength(k) == 0) return ""; 20 if(llStringLength(k) == 0) return "";
21 list a = llParseString2List(data, ["&", "="], []); 21 list a = llParseString2List(data, ["&", "="], []);
22 integer i = llListFindList(a, [ k ]); 22 integer i = llListFindList(a, [ k ]);
23 if(i != -1) return llList2String(a, i+1); 23 if(i != -1) return llList2String(a, i+1);
24 return ""; 24 return "";
25 } 25 }
26 26
27 /////////////////////////////////////////////////////////////////////////// 27 ///////////////////////////////////////////////////////////////////////////
28 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // 28 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
29 /////////////////////////////////////////////////////////////////////////// 29 ///////////////////////////////////////////////////////////////////////////
30 string wasKeyValueEncode(list data) { 30 string wasKeyValueEncode(list data) {
31 list k = llList2ListStrided(data, 0, -1, 2); 31 list k = llList2ListStrided(data, 0, -1, 2);
32 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 32 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
33 data = []; 33 data = [];
34 do { 34 do {
35 data += llList2String(k, 0) + "=" + llList2String(v, 0); 35 data += llList2String(k, 0) + "=" + llList2String(v, 0);
36 k = llDeleteSubList(k, 0, 0); 36 k = llDeleteSubList(k, 0, 0);
37 v = llDeleteSubList(v, 0, 0); 37 v = llDeleteSubList(v, 0, 0);
38 } while(llGetListLength(k) != 0); 38 } while(llGetListLength(k) != 0);
39 return llDumpList2String(data, "&"); 39 return llDumpList2String(data, "&");
40 } 40 }
41   41  
42 /////////////////////////////////////////////////////////////////////////// 42 ///////////////////////////////////////////////////////////////////////////
43 // Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // 43 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
44 /////////////////////////////////////////////////////////////////////////// 44 ///////////////////////////////////////////////////////////////////////////
45 // http://was.fm/secondlife/wanderer 45 // http://was.fm/secondlife/wanderer
46 vector wasCirclePoint(float radius) { 46 vector wasCirclePoint(float radius) {
47 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 47 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
48 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 48 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
49 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) 49 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
50 return <x, y, 0>; 50 return <x, y, 0>;
51 return wasCirclePoint(radius); 51 return wasCirclePoint(radius);
52 } 52 }
53   53  
54 /////////////////////////////////////////////////////////////////////////// 54 ///////////////////////////////////////////////////////////////////////////
55 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // 55 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
56 /////////////////////////////////////////////////////////////////////////// 56 ///////////////////////////////////////////////////////////////////////////
57 // escapes a string in conformance with RFC1738 57 // escapes a string in conformance with RFC1738
58 string wasURLEscape(string i) { 58 string wasURLEscape(string i) {
59 string o = ""; 59 string o = "";
60 do { 60 do {
61 string c = llGetSubString(i, 0, 0); 61 string c = llGetSubString(i, 0, 0);
62 i = llDeleteSubString(i, 0, 0); 62 i = llDeleteSubString(i, 0, 0);
63 if(c == "") jump continue; 63 if(c == "") jump continue;
64 if(c == " ") { 64 if(c == " ") {
65 o += "+"; 65 o += "+";
66 jump continue; 66 jump continue;
67 } 67 }
68 if(c == "\n") { 68 if(c == "\n") {
69 o += "%0D" + llEscapeURL(c); 69 o += "%0D" + llEscapeURL(c);
70 jump continue; 70 jump continue;
71 } 71 }
72 o += llEscapeURL(c); 72 o += llEscapeURL(c);
73 @continue; 73 @continue;
74 } while(i != ""); 74 } while(i != "");
75 return o; 75 return o;
76 } 76 }
77   77  
78 // corrade data 78 // corrade data
79 string CORRADE = ""; 79 string CORRADE = "";
80 string GROUP = ""; 80 string GROUP = "";
81 string PASSWORD = ""; 81 string PASSWORD = "";
82 float RADIUS = 0; 82 float RADIUS = 0;
83 float WAIT = 0; 83 float WAIT = 0;
84   84  
85 // for holding the callback URL 85 // for holding the callback URL
86 string callback = ""; 86 string callback = "";
87   87  
88 // for notecard reading 88 // for notecard reading
89 integer line = 0; 89 integer line = 0;
90   90  
91 // key-value data will be read into this list 91 // key-value data will be read into this list
92 list tuples = []; 92 list tuples = [];
93 93
94 default { 94 default {
95 state_entry() { 95 state_entry() {
96 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { 96 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
97 llOwnerSay("Sorry, could not find an inventory notecard."); 97 llOwnerSay("Sorry, could not find an inventory notecard.");
98 return; 98 return;
99 } 99 }
100 // DEBUG 100 // DEBUG
101 llOwnerSay("Reading configuration file..."); 101 llOwnerSay("Reading configuration file...");
102 llGetNotecardLine("configuration", line); 102 llGetNotecardLine("configuration", line);
103 } 103 }
104 dataserver(key id, string data) { 104 dataserver(key id, string data) {
105 if(data == EOF) { 105 if(data == EOF) {
106 // invariant, length(tuples) % 2 == 0 106 // invariant, length(tuples) % 2 == 0
107 if(llGetListLength(tuples) % 2 != 0) { 107 if(llGetListLength(tuples) % 2 != 0) {
108 llOwnerSay("Error in configuration notecard."); 108 llOwnerSay("Error in configuration notecard.");
109 return; 109 return;
110 } 110 }
111 CORRADE = llList2String( 111 CORRADE = llList2String(
112 tuples, 112 tuples,
113 llListFindList( 113 llListFindList(
114 tuples, 114 tuples,
115 [ 115 [
116 "corrade" 116 "corrade"
117 ] 117 ]
118 ) 118 )
119 +1); 119 +1);
120 if(CORRADE == "") { 120 if(CORRADE == "") {
121 llOwnerSay("Error in configuration notecard: corrade"); 121 llOwnerSay("Error in configuration notecard: corrade");
122 return; 122 return;
123 } 123 }
124 GROUP = llList2String( 124 GROUP = llList2String(
125 tuples, 125 tuples,
126 llListFindList( 126 llListFindList(
127 tuples, 127 tuples,
128 [ 128 [
129 "group" 129 "group"
130 ] 130 ]
131 ) 131 )
132 +1); 132 +1);
133 if(GROUP == "") { 133 if(GROUP == "") {
134 llOwnerSay("Error in configuration notecard: group"); 134 llOwnerSay("Error in configuration notecard: group");
135 return; 135 return;
136 } 136 }
137 PASSWORD = llList2String( 137 PASSWORD = llList2String(
138 tuples, 138 tuples,
139 llListFindList( 139 llListFindList(
140 tuples, 140 tuples,
141 [ 141 [
142 "password" 142 "password"
143 ] 143 ]
144 ) 144 )
145 +1); 145 +1);
146 if(PASSWORD == "") { 146 if(PASSWORD == "") {
147 llOwnerSay("Error in configuration notecard: password"); 147 llOwnerSay("Error in configuration notecard: password");
148 return; 148 return;
149 } 149 }
150 RADIUS = llList2Float( 150 RADIUS = llList2Float(
151 tuples, 151 tuples,
152 llListFindList( 152 llListFindList(
153 tuples, 153 tuples,
154 [ 154 [
155 "radius" 155 "radius"
156 ] 156 ]
157 ) 157 )
158 +1); 158 +1);
159 if(RADIUS == 0) { 159 if(RADIUS == 0) {
160 llOwnerSay("Error in configuration notecard: radius"); 160 llOwnerSay("Error in configuration notecard: radius");
161 return; 161 return;
162 } 162 }
163 WAIT = llList2Float( 163 WAIT = llList2Float(
164 tuples, 164 tuples,
165 llListFindList( 165 llListFindList(
166 tuples, 166 tuples,
167 [ 167 [
168 "wait" 168 "wait"
169 ] 169 ]
170 ) 170 )
171 +1); 171 +1);
172 if(WAIT == 0) { 172 if(WAIT == 0) {
173 llOwnerSay("Error in configuration notecard: wait"); 173 llOwnerSay("Error in configuration notecard: wait");
174 return; 174 return;
175 } 175 }
176 // DEBUG 176 // DEBUG
177 llOwnerSay("Read configuration file..."); 177 llOwnerSay("Read configuration file...");
178 state url; 178 state url;
179 } 179 }
180 if(data == "") jump continue; 180 if(data == "") jump continue;
181 integer i = llSubStringIndex(data, "#"); 181 integer i = llSubStringIndex(data, "#");
182 if(i != -1) data = llDeleteSubString(data, i, -1); 182 if(i != -1) data = llDeleteSubString(data, i, -1);
183 list o = llParseString2List(data, ["="], []); 183 list o = llParseString2List(data, ["="], []);
184 // get rid of starting and ending quotes 184 // get rid of starting and ending quotes
185 string k = llDumpList2String( 185 string k = llDumpList2String(
186 llParseString2List( 186 llParseString2List(
187 llStringTrim( 187 llStringTrim(
188 llList2String( 188 llList2String(
189 o, 189 o,
190 0 190 0
191 ), 191 ),
192 STRING_TRIM), 192 STRING_TRIM),
193 ["\""], [] 193 ["\""], []
194 ), "\""); 194 ), "\"");
195 string v = llDumpList2String( 195 string v = llDumpList2String(
196 llParseString2List( 196 llParseString2List(
197 llStringTrim( 197 llStringTrim(
198 llList2String( 198 llList2String(
199 o, 199 o,
200 1 200 1
201 ), 201 ),
202 STRING_TRIM), 202 STRING_TRIM),
203 ["\""], [] 203 ["\""], []
204 ), "\""); 204 ), "\"");
205 if(k == "" || v == "") jump continue; 205 if(k == "" || v == "") jump continue;
206 tuples += k; 206 tuples += k;
207 tuples += v; 207 tuples += v;
208 @continue; 208 @continue;
209 llGetNotecardLine("configuration", ++line); 209 llGetNotecardLine("configuration", ++line);
210 } 210 }
211 on_rez(integer num) { 211 on_rez(integer num) {
212 llResetScript(); 212 llResetScript();
213 } 213 }
214 changed(integer change) { 214 changed(integer change) {
215 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 215 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
216 llResetScript(); 216 llResetScript();
217 } 217 }
218 } 218 }
219 } 219 }
220 220
221 state url { 221 state url {
222 state_entry() { 222 state_entry() {
223 // DEBUG 223 // DEBUG
224 llOwnerSay("Requesting URL..."); 224 llOwnerSay("Requesting URL...");
225 llRequestURL(); 225 llRequestURL();
226 } 226 }
227 http_request(key id, string method, string body) { 227 http_request(key id, string method, string body) {
228 if(method != URL_REQUEST_GRANTED) return; 228 if(method != URL_REQUEST_GRANTED) return;
229 callback = body; 229 callback = body;
230 // DEBUG 230 // DEBUG
231 llOwnerSay("Got URL..."); 231 llOwnerSay("Got URL...");
232 state detect; 232 state detect;
233 } 233 }
234 on_rez(integer num) { 234 on_rez(integer num) {
235 llResetScript(); 235 llResetScript();
236 } 236 }
237 changed(integer change) { 237 changed(integer change) {
238 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 238 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
239 llResetScript(); 239 llResetScript();
240 } 240 }
241 } 241 }
242 } 242 }
243 243
244 state detect { 244 state detect {
245 state_entry() { 245 state_entry() {
246 // DEBUG 246 // DEBUG
247 llOwnerSay("Detecting if Corrade is online..."); 247 llOwnerSay("Detecting if Corrade is online...");
248 llSetTimerEvent(5); 248 llSetTimerEvent(5);
249 } 249 }
250 timer() { 250 timer() {
251 llRequestAgentData((key)CORRADE, DATA_ONLINE); 251 llRequestAgentData((key)CORRADE, DATA_ONLINE);
252 } 252 }
253 dataserver(key id, string data) { 253 dataserver(key id, string data) {
254 if(data != "1") { 254 if(data != "1") {
255 // DEBUG 255 // DEBUG
256 llOwnerSay("Corrade is not online, sleeping..."); 256 llOwnerSay("Corrade is not online, sleeping...");
257 llSetTimerEvent(30); 257 llSetTimerEvent(30);
258 return; 258 return;
259 } 259 }
260 llSensor("", (key)CORRADE, AGENT, 10, TWO_PI); 260 llSensor("", (key)CORRADE, AGENT, 10, TWO_PI);
261 } 261 }
262 no_sensor() { 262 no_sensor() {
263 // DEBUG 263 // DEBUG
264 llOwnerSay("Teleporting Corrade..."); 264 llOwnerSay("Teleporting Corrade...");
265 llInstantMessage((key)CORRADE, 265 llInstantMessage((key)CORRADE,
266 wasKeyValueEncode( 266 wasKeyValueEncode(
267 [ 267 [
268 "command", "teleport", 268 "command", "teleport",
269 "group", wasURLEscape(GROUP), 269 "group", wasURLEscape(GROUP),
270 "password", wasURLEscape(PASSWORD), 270 "password", wasURLEscape(PASSWORD),
271 "entity", "region", 271 "entity", "region",
272 "region", wasURLEscape(llGetRegionName()), 272 "region", wasURLEscape(llGetRegionName()),
273 "position", wasURLEscape( 273 "position", wasURLEscape(
274 (string)( 274 (string)(
275 llGetPos() + wasCirclePoint(RADIUS) 275 llGetPos() + wasCirclePoint(RADIUS)
276 ) 276 )
277 ), 277 ),
278 "callback", callback 278 "callback", callback
279 ] 279 ]
280 ) 280 )
281 ); 281 );
282 llSensorRepeat("", (key)CORRADE, AGENT, 10, TWO_PI, 60); 282 llSensorRepeat("", (key)CORRADE, AGENT, 10, TWO_PI, 60);
283 } 283 }
284 sensor(integer num) { 284 sensor(integer num) {
285 llSetTimerEvent(0); 285 llSetTimerEvent(0);
286 state wander; 286 state wander;
287 } 287 }
288 http_request(key id, string method, string body) { 288 http_request(key id, string method, string body) {
289 llHTTPResponse(id, 200, "OK"); 289 llHTTPResponse(id, 200, "OK");
290 if(wasKeyValueGet("command", body) != "teleport" || 290 if(wasKeyValueGet("command", body) != "teleport" ||
291 wasKeyValueGet("success", body) != "True") { 291 wasKeyValueGet("success", body) != "True") {
292 // DEBUG 292 // DEBUG
293 llOwnerSay("Teleport failed..."); 293 llOwnerSay("Teleport failed...");
294 return; 294 return;
295 } 295 }
296 llSetTimerEvent(0); 296 llSetTimerEvent(0);
297 state wander; 297 state wander;
298 } 298 }
299 on_rez(integer num) { 299 on_rez(integer num) {
300 llResetScript(); 300 llResetScript();
301 } 301 }
302 changed(integer change) { 302 changed(integer change) {
303 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 303 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
304 llResetScript(); 304 llResetScript();
305 } 305 }
306 } 306 }
307 } 307 }
308   308  
309 state wander { 309 state wander {
310 state_entry() { 310 state_entry() {
311 // DEBUG 311 // DEBUG
312 llOwnerSay("Wandering ready..."); 312 llOwnerSay("Wandering ready...");
313 llSetTimerEvent(1 + llFrand(WAIT)); 313 llSetTimerEvent(1 + llFrand(WAIT));
314 } 314 }
315 timer() { 315 timer() {
316 llRequestAgentData((key)CORRADE, DATA_ONLINE); 316 llRequestAgentData((key)CORRADE, DATA_ONLINE);
317 } 317 }
318 dataserver(key id, string data) { 318 dataserver(key id, string data) {
319 if(data != "1") { 319 if(data != "1") {
320 // DEBUG 320 // DEBUG
321 llOwnerSay("Corrade is not online, sleeping..."); 321 llOwnerSay("Corrade is not online, sleeping...");
322 llResetScript(); 322 llResetScript();
323 return; 323 return;
324 } 324 }
325 // DEBUG 325 // DEBUG
326 //llOwnerSay("Sending stop..."); -  
327 llInstantMessage(CORRADE, -  
328 wasKeyValueEncode( -  
329 [ -  
330 "command", "autopilot", -  
331 "group", wasURLEscape(GROUP), -  
332 "password", wasURLEscape(PASSWORD), -  
333 "action", "stop", -  
334 "callback", wasURLEscape(callback) -  
335 ] -  
336 ) -  
337 ); -  
338 } -  
339 http_request(key id, string method, string body) { -  
340 llHTTPResponse(id, 200, "OK"); -  
341 if(wasKeyValueGet("command", body) != "autopilot" || -  
342 wasKeyValueGet("success", body) != "True") { -  
343 // DEBUG -  
344 llOwnerSay("Could not get Corrade to stop, restarting script..."); -  
345 llResetScript(); -  
346 } -  
347 // DEBUG -  
348 //llOwnerSay("Sending next move..."); 326 //llOwnerSay("Sending next move...");
-   327 float timeout = 1 + llFrand(WAIT);
349 llInstantMessage(CORRADE, 328 llInstantMessage(CORRADE,
350 wasKeyValueEncode( 329 wasKeyValueEncode(
351 [ 330 [
352 "command", "autopilot", 331 "command", "walkto",
353 "group", wasURLEscape(GROUP), 332 "group", wasURLEscape(GROUP),
354 "password", wasURLEscape(PASSWORD), 333 "password", wasURLEscape(PASSWORD),
355 "position", wasURLEscape( 334 "position", wasURLEscape(
356 (string)( 335 (string)(
357 llGetPos() + wasCirclePoint(RADIUS) 336 llGetPos() + wasCirclePoint(RADIUS)
358 ) 337 )
359 ), 338 ),
360 "action", "start" 339 "vicinity", "1",
-   340 "timeout", timeout
361 ] 341 ]
362 ) 342 )
363 ); 343 );
364 llSetTimerEvent(1 + llFrand(WAIT)); 344 llSetTimerEvent(timeout);
365 } 345 }
366 on_rez(integer num) { 346 on_rez(integer num) {
367 llResetScript(); 347 llResetScript();
368 } 348 }
369 changed(integer change) { 349 changed(integer change) {
370 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 350 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
371 llResetScript(); 351 llResetScript();
372 } 352 }
373 } 353 }
374 } 354 }
375   355