corrade-lsl-templates – Blame information for rev 37

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