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

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 5 Rev 29
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // 4 //
5 // This is a script that uses Corrade to change the texture on the 5 // This is a script that uses Corrade to change the texture on the
6 // available faces of the primitie. It requires that you have a Corrade bot 6 // available faces of the primitie. It requires that you have a Corrade bot
7 // with the following permissions enabled for the group specified in the 7 // with the following permissions enabled for the group specified in the
8 // configuration notecard inside this primitive: 8 // configuration notecard inside this primitive:
9 // 9 //
10 // config -> groups -> group [your group] -> permissions -> interact 10 // config -> groups -> group [your group] -> permissions -> interact
11 // config -> groups -> group [your group] -> permissions -> friendship 11 // config -> groups -> group [your group] -> permissions -> friendship
12 // 12 //
13 // Additionally, you should be a friend of your bot and have granted modify 13 // Additionally, you should be a friend of your bot and have granted modify
14 // permissions to the bot by using the viewer interface: 14 // permissions to the bot by using the viewer interface:
15 // 15 //
16 // Contact -> Friends -> [ Bot ] -> Friend can edit, delete, take objects. 16 // Contact -> Friends -> [ Bot ] -> Friend can edit, delete, take objects.
17 // 17 //
18 // The sit script works together with a "configuration" notecard that must 18 // The sit script works together with a "configuration" notecard that must
19 // be placed in the same primitive as this script. The purpose of this 19 // be placed in the same primitive as this script. The purpose of this
20 // script is to demonstrate changing textures with Corrade and you are free 20 // script is to demonstrate changing textures with Corrade and you are free
21 // to use, change, and commercialize it under the GNU/GPLv3 license at: 21 // to use, change, and commercialize it under the CC BY 2.0 license at:
22 // http://www.gnu.org/licenses/gpl.html 22 // https://creativecommons.org/licenses/by/2.0
23 // 23 //
24 /////////////////////////////////////////////////////////////////////////// 24 ///////////////////////////////////////////////////////////////////////////
25   25  
26 /////////////////////////////////////////////////////////////////////////// 26 ///////////////////////////////////////////////////////////////////////////
27 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 27 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
28 /////////////////////////////////////////////////////////////////////////// 28 ///////////////////////////////////////////////////////////////////////////
29 string wasKeyValueGet(string k, string data) { 29 string wasKeyValueGet(string k, string data) {
30 if(llStringLength(data) == 0) return ""; 30 if(llStringLength(data) == 0) return "";
31 if(llStringLength(k) == 0) return ""; 31 if(llStringLength(k) == 0) return "";
32 list a = llParseString2List(data, ["&", "="], []); 32 list a = llParseString2List(data, ["&", "="], []);
33 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); 33 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
34 if(i != -1) return llList2String(a, 2*i+1); 34 if(i != -1) return llList2String(a, 2*i+1);
35 return ""; 35 return "";
36 } 36 }
37 37
38 /////////////////////////////////////////////////////////////////////////// 38 ///////////////////////////////////////////////////////////////////////////
39 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // 39 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 //
40 /////////////////////////////////////////////////////////////////////////// 40 ///////////////////////////////////////////////////////////////////////////
41 string wasKeyValueEncode(list data) { 41 string wasKeyValueEncode(list data) {
42 list k = llList2ListStrided(data, 0, -1, 2); 42 list k = llList2ListStrided(data, 0, -1, 2);
43 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 43 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
44 data = []; 44 data = [];
45 do { 45 do {
46 data += llList2String(k, 0) + "=" + llList2String(v, 0); 46 data += llList2String(k, 0) + "=" + llList2String(v, 0);
47 k = llDeleteSubList(k, 0, 0); 47 k = llDeleteSubList(k, 0, 0);
48 v = llDeleteSubList(v, 0, 0); 48 v = llDeleteSubList(v, 0, 0);
49 } while(llGetListLength(k) != 0); 49 } while(llGetListLength(k) != 0);
50 return llDumpList2String(data, "&"); 50 return llDumpList2String(data, "&");
51 } 51 }
52   52  
53 /////////////////////////////////////////////////////////////////////////// 53 ///////////////////////////////////////////////////////////////////////////
54 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // 54 // Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 //
55 /////////////////////////////////////////////////////////////////////////// 55 ///////////////////////////////////////////////////////////////////////////
56 vector wasCirclePoint(float radius) { 56 vector wasCirclePoint(float radius) {
57 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 57 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
58 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 58 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
59 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) 59 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
60 return <x, y, 0>; 60 return <x, y, 0>;
61 return wasCirclePoint(radius); 61 return wasCirclePoint(radius);
62 } 62 }
63   63  
64 /////////////////////////////////////////////////////////////////////////// 64 ///////////////////////////////////////////////////////////////////////////
65 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 65 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
66 /////////////////////////////////////////////////////////////////////////// 66 ///////////////////////////////////////////////////////////////////////////
67 // escapes a string in conformance with RFC1738 67 // escapes a string in conformance with RFC1738
68 string wasURLEscape(string i) { 68 string wasURLEscape(string i) {
69 string o = ""; 69 string o = "";
70 do { 70 do {
71 string c = llGetSubString(i, 0, 0); 71 string c = llGetSubString(i, 0, 0);
72 i = llDeleteSubString(i, 0, 0); 72 i = llDeleteSubString(i, 0, 0);
73 if(c == "") jump continue; 73 if(c == "") jump continue;
74 if(c == " ") { 74 if(c == " ") {
75 o += "+"; 75 o += "+";
76 jump continue; 76 jump continue;
77 } 77 }
78 if(c == "\n") { 78 if(c == "\n") {
79 o += "%0D" + llEscapeURL(c); 79 o += "%0D" + llEscapeURL(c);
80 jump continue; 80 jump continue;
81 } 81 }
82 o += llEscapeURL(c); 82 o += llEscapeURL(c);
83 @continue; 83 @continue;
84 } while(i != ""); 84 } while(i != "");
85 return o; 85 return o;
86 } 86 }
87   87  
88 /////////////////////////////////////////////////////////////////////////// 88 ///////////////////////////////////////////////////////////////////////////
89 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 89 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
90 /////////////////////////////////////////////////////////////////////////// 90 ///////////////////////////////////////////////////////////////////////////
91 // unescapes a string in conformance with RFC1738 91 // unescapes a string in conformance with RFC1738
92 string wasURLUnescape(string i) { 92 string wasURLUnescape(string i) {
93 return llUnescapeURL( 93 return llUnescapeURL(
94 llDumpList2String( 94 llDumpList2String(
95 llParseString2List( 95 llParseString2List(
96 llDumpList2String( 96 llDumpList2String(
97 llParseString2List( 97 llParseString2List(
98 i, 98 i,
99 ["+"], 99 ["+"],
100 [] 100 []
101 ), 101 ),
102 " " 102 " "
103 ), 103 ),
104 ["%0D%0A"], 104 ["%0D%0A"],
105 [] 105 []
106 ), 106 ),
107 "\n" 107 "\n"
108 ) 108 )
109 ); 109 );
110 } 110 }
111   111  
112 /////////////////////////////////////////////////////////////////////////// 112 ///////////////////////////////////////////////////////////////////////////
113 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 113 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
114 /////////////////////////////////////////////////////////////////////////// 114 ///////////////////////////////////////////////////////////////////////////
115 list wasCSVToList(string csv) { 115 list wasCSVToList(string csv) {
116 list l = []; 116 list l = [];
117 list s = []; 117 list s = [];
118 string m = ""; 118 string m = "";
119 do { 119 do {
120 string a = llGetSubString(csv, 0, 0); 120 string a = llGetSubString(csv, 0, 0);
121 csv = llDeleteSubString(csv, 0, 0); 121 csv = llDeleteSubString(csv, 0, 0);
122 if(a == ",") { 122 if(a == ",") {
123 if(llList2String(s, -1) != "\"") { 123 if(llList2String(s, -1) != "\"") {
124 l += m; 124 l += m;
125 m = ""; 125 m = "";
126 jump continue; 126 jump continue;
127 } 127 }
128 m += a; 128 m += a;
129 jump continue; 129 jump continue;
130 } 130 }
131 if(a == "\"" && llGetSubString(csv, 0, 0) == a) { 131 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
132 m += a; 132 m += a;
133 csv = llDeleteSubString(csv, 0, 0); 133 csv = llDeleteSubString(csv, 0, 0);
134 jump continue; 134 jump continue;
135 } 135 }
136 if(a == "\"") { 136 if(a == "\"") {
137 if(llList2String(s, -1) != a) { 137 if(llList2String(s, -1) != a) {
138 s += a; 138 s += a;
139 jump continue; 139 jump continue;
140 } 140 }
141 s = llDeleteSubList(s, -1, -1); 141 s = llDeleteSubList(s, -1, -1);
142 jump continue; 142 jump continue;
143 } 143 }
144 m += a; 144 m += a;
145 @continue; 145 @continue;
146 } while(csv != ""); 146 } while(csv != "");
147 // postcondition: length(s) = 0 147 // postcondition: length(s) = 0
148 return l + m; 148 return l + m;
149 } 149 }
150   150  
151 /////////////////////////////////////////////////////////////////////////// 151 ///////////////////////////////////////////////////////////////////////////
152 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 152 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
153 /////////////////////////////////////////////////////////////////////////// 153 ///////////////////////////////////////////////////////////////////////////
154 string wasListToCSV(list l) { 154 string wasListToCSV(list l) {
155 list v = []; 155 list v = [];
156 do { 156 do {
157 string a = llDumpList2String( 157 string a = llDumpList2String(
158 llParseStringKeepNulls( 158 llParseStringKeepNulls(
159 llList2String( 159 llList2String(
160 l, 160 l,
161 0 161 0
162 ), 162 ),
163 ["\""], 163 ["\""],
164 [] 164 []
165 ), 165 ),
166 "\"\"" 166 "\"\""
167 ); 167 );
168 if(llParseStringKeepNulls( 168 if(llParseStringKeepNulls(
169 a, 169 a,
170 [" ", ",", "\n", "\""], [] 170 [" ", ",", "\n", "\""], []
171 ) != 171 ) !=
172 (list) a 172 (list) a
173 ) a = "\"" + a + "\""; 173 ) a = "\"" + a + "\"";
174 v += a; 174 v += a;
175 l = llDeleteSubList(l, 0, 0); 175 l = llDeleteSubList(l, 0, 0);
176 } while(l != []); 176 } while(l != []);
177 return llDumpList2String(v, ","); 177 return llDumpList2String(v, ",");
178 } 178 }
179   179  
180 // corrade data 180 // corrade data
181 string CORRADE = ""; 181 string CORRADE = "";
182 string GROUP = ""; 182 string GROUP = "";
183 string PASSWORD = ""; 183 string PASSWORD = "";
184   184  
185 // for holding the callback URL 185 // for holding the callback URL
186 string callback = ""; 186 string callback = "";
187   187  
188 // for holding the selected face number 188 // for holding the selected face number
189 string FACE = ""; 189 string FACE = "";
190 // for holding the selected texture 190 // for holding the selected texture
191 string TEXTURE = ""; 191 string TEXTURE = "";
192 // for holding the current user 192 // for holding the current user
193 key TOUCH = NULL_KEY; 193 key TOUCH = NULL_KEY;
194   194  
195 // for notecard reading 195 // for notecard reading
196 integer line = 0; 196 integer line = 0;
197   197  
198 // key-value data will be read into this list 198 // key-value data will be read into this list
199 list tuples = []; 199 list tuples = [];
200 200
201 default { 201 default {
202 state_entry() { 202 state_entry() {
203 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { 203 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
204 llOwnerSay("Sorry, could not find an inventory notecard."); 204 llOwnerSay("Sorry, could not find an inventory notecard.");
205 return; 205 return;
206 } 206 }
207 // DEBUG 207 // DEBUG
208 llOwnerSay("Reading configuration file..."); 208 llOwnerSay("Reading configuration file...");
209 llGetNotecardLine("configuration", line); 209 llGetNotecardLine("configuration", line);
210 } 210 }
211 dataserver(key id, string data) { 211 dataserver(key id, string data) {
212 if(data == EOF) { 212 if(data == EOF) {
213 // invariant, length(tuples) % 2 == 0 213 // invariant, length(tuples) % 2 == 0
214 if(llGetListLength(tuples) % 2 != 0) { 214 if(llGetListLength(tuples) % 2 != 0) {
215 llOwnerSay("Error in configuration notecard."); 215 llOwnerSay("Error in configuration notecard.");
216 return; 216 return;
217 } 217 }
218 CORRADE = llList2String( 218 CORRADE = llList2String(
219 tuples, 219 tuples,
220 llListFindList( 220 llListFindList(
221 tuples, 221 tuples,
222 [ 222 [
223 "corrade" 223 "corrade"
224 ] 224 ]
225 ) 225 )
226 +1); 226 +1);
227 if(CORRADE == "") { 227 if(CORRADE == "") {
228 llOwnerSay("Error in configuration notecard: corrade"); 228 llOwnerSay("Error in configuration notecard: corrade");
229 return; 229 return;
230 } 230 }
231 GROUP = llList2String( 231 GROUP = llList2String(
232 tuples, 232 tuples,
233 llListFindList( 233 llListFindList(
234 tuples, 234 tuples,
235 [ 235 [
236 "group" 236 "group"
237 ] 237 ]
238 ) 238 )
239 +1); 239 +1);
240 if(GROUP == "") { 240 if(GROUP == "") {
241 llOwnerSay("Error in configuration notecard: password"); 241 llOwnerSay("Error in configuration notecard: password");
242 return; 242 return;
243 } 243 }
244 PASSWORD = llList2String( 244 PASSWORD = llList2String(
245 tuples, 245 tuples,
246 llListFindList( 246 llListFindList(
247 tuples, 247 tuples,
248 [ 248 [
249 "password" 249 "password"
250 ] 250 ]
251 ) 251 )
252 +1); 252 +1);
253 if(GROUP == "") { 253 if(GROUP == "") {
254 llOwnerSay("Error in configuration notecard: group"); 254 llOwnerSay("Error in configuration notecard: group");
255 return; 255 return;
256 } 256 }
257 // DEBUG 257 // DEBUG
258 llOwnerSay("Read configuration file..."); 258 llOwnerSay("Read configuration file...");
259 state url; 259 state url;
260 } 260 }
261 if(data == "") jump continue; 261 if(data == "") jump continue;
262 integer i = llSubStringIndex(data, "#"); 262 integer i = llSubStringIndex(data, "#");
263 if(i != -1) data = llDeleteSubString(data, i, -1); 263 if(i != -1) data = llDeleteSubString(data, i, -1);
264 list o = llParseString2List(data, ["="], []); 264 list o = llParseString2List(data, ["="], []);
265 // get rid of starting and ending quotes 265 // get rid of starting and ending quotes
266 string k = llDumpList2String( 266 string k = llDumpList2String(
267 llParseString2List( 267 llParseString2List(
268 llStringTrim( 268 llStringTrim(
269 llList2String( 269 llList2String(
270 o, 270 o,
271 0 271 0
272 ), 272 ),
273 STRING_TRIM), 273 STRING_TRIM),
274 ["\""], [] 274 ["\""], []
275 ), "\""); 275 ), "\"");
276 string v = llDumpList2String( 276 string v = llDumpList2String(
277 llParseString2List( 277 llParseString2List(
278 llStringTrim( 278 llStringTrim(
279 llList2String( 279 llList2String(
280 o, 280 o,
281 1 281 1
282 ), 282 ),
283 STRING_TRIM), 283 STRING_TRIM),
284 ["\""], [] 284 ["\""], []
285 ), "\""); 285 ), "\"");
286 if(k == "" || v == "") jump continue; 286 if(k == "" || v == "") jump continue;
287 tuples += k; 287 tuples += k;
288 tuples += v; 288 tuples += v;
289 @continue; 289 @continue;
290 llGetNotecardLine("configuration", ++line); 290 llGetNotecardLine("configuration", ++line);
291 } 291 }
292 on_rez(integer num) { 292 on_rez(integer num) {
293 llResetScript(); 293 llResetScript();
294 } 294 }
295 changed(integer change) { 295 changed(integer change) {
296 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 296 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
297 llResetScript(); 297 llResetScript();
298 } 298 }
299 } 299 }
300 } 300 }
301 301
302 state url { 302 state url {
303 state_entry() { 303 state_entry() {
304 // DEBUG 304 // DEBUG
305 llOwnerSay("Requesting URL..."); 305 llOwnerSay("Requesting URL...");
306 llRequestURL(); 306 llRequestURL();
307 } 307 }
308 http_request(key id, string method, string body) { 308 http_request(key id, string method, string body) {
309 if(method != URL_REQUEST_GRANTED) return; 309 if(method != URL_REQUEST_GRANTED) return;
310 callback = body; 310 callback = body;
311 // DEBUG 311 // DEBUG
312 llOwnerSay("Got URL..."); 312 llOwnerSay("Got URL...");
313 state detect; 313 state detect;
314 } 314 }
315 on_rez(integer num) { 315 on_rez(integer num) {
316 llResetScript(); 316 llResetScript();
317 } 317 }
318 changed(integer change) { 318 changed(integer change) {
319 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 319 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
320 llResetScript(); 320 llResetScript();
321 } 321 }
322 } 322 }
323 } 323 }
324 324
325 state detect { 325 state detect {
326 state_entry() { 326 state_entry() {
327 // DEBUG 327 // DEBUG
328 llOwnerSay("Detecting if Corrade is online..."); 328 llOwnerSay("Detecting if Corrade is online...");
329 llSetTimerEvent(5); 329 llSetTimerEvent(5);
330 } 330 }
331 timer() { 331 timer() {
332 llRequestAgentData((key)CORRADE, DATA_ONLINE); 332 llRequestAgentData((key)CORRADE, DATA_ONLINE);
333 } 333 }
334 dataserver(key id, string data) { 334 dataserver(key id, string data) {
335 if(data != "1") { 335 if(data != "1") {
336 // DEBUG 336 // DEBUG
337 llOwnerSay("Corrade is not online, sleeping..."); 337 llOwnerSay("Corrade is not online, sleeping...");
338 llSetTimerEvent(30); 338 llSetTimerEvent(30);
339 return; 339 return;
340 } 340 }
341 llSensorRepeat("", (key)CORRADE, AGENT, 10, TWO_PI, 1); 341 llSensorRepeat("", (key)CORRADE, AGENT, 10, TWO_PI, 1);
342 } 342 }
343 no_sensor() { 343 no_sensor() {
344 // DEBUG 344 // DEBUG
345 llOwnerSay("Teleporting Corrade..."); 345 llOwnerSay("Teleporting Corrade...");
346 llInstantMessage((key)CORRADE, 346 llInstantMessage((key)CORRADE,
347 wasKeyValueEncode( 347 wasKeyValueEncode(
348 [ 348 [
349 "command", "teleport", 349 "command", "teleport",
350 "group", wasURLEscape(GROUP), 350 "group", wasURLEscape(GROUP),
351 "password", wasURLEscape(PASSWORD), 351 "password", wasURLEscape(PASSWORD),
352 "entity", "region", 352 "entity", "region",
353 "region", wasURLEscape(llGetRegionName()), 353 "region", wasURLEscape(llGetRegionName()),
354 "position", wasURLEscape( 354 "position", wasURLEscape(
355 (string)( 355 (string)(
356 llGetPos() + wasCirclePoint(1) 356 llGetPos() + wasCirclePoint(1)
357 ) 357 )
358 ), 358 ),
359 "callback", callback 359 "callback", callback
360 ] 360 ]
361 ) 361 )
362 ); 362 );
363 } 363 }
364 sensor(integer num) { 364 sensor(integer num) {
365 llSetTimerEvent(0); 365 llSetTimerEvent(0);
366 state check_rights; 366 state check_rights;
367 } 367 }
368 http_request(key id, string method, string body) { 368 http_request(key id, string method, string body) {
369 llHTTPResponse(id, 200, "OK"); 369 llHTTPResponse(id, 200, "OK");
370 if(wasKeyValueGet("command", body) != "teleport" || 370 if(wasKeyValueGet("command", body) != "teleport" ||
371 wasKeyValueGet("success", body) != "True") { 371 wasKeyValueGet("success", body) != "True") {
372 // DEBUG 372 // DEBUG
373 llOwnerSay("Teleport failed: " + 373 llOwnerSay("Teleport failed: " +
374 wasURLUnescape( 374 wasURLUnescape(
375 wasKeyValueGet( 375 wasKeyValueGet(
376 "error", 376 "error",
377 body 377 body
378 ) 378 )
379 ) 379 )
380 ); 380 );
381 state detect_trampoline; 381 state detect_trampoline;
382 } 382 }
383 llSetTimerEvent(0); 383 llSetTimerEvent(0);
384 state check_rights; 384 state check_rights;
385 } 385 }
386 on_rez(integer num) { 386 on_rez(integer num) {
387 llResetScript(); 387 llResetScript();
388 } 388 }
389 changed(integer change) { 389 changed(integer change) {
390 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 390 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
391 llResetScript(); 391 llResetScript();
392 } 392 }
393 } 393 }
394 } 394 }
395   395  
396 /* 396 /*
397 * Trampoline used for delaying teleport requests sent to Corrade. Once code 397 * Trampoline used for delaying teleport requests sent to Corrade. Once code
398 * switches into this state, the script waits for some seconds and then 398 * switches into this state, the script waits for some seconds and then
399 * switches to the detect state. 399 * switches to the detect state.
400 */ 400 */
401 state detect_trampoline { 401 state detect_trampoline {
402 state_entry() { 402 state_entry() {
403 // DEBUG 403 // DEBUG
404 llOwnerSay("Sleeping..."); 404 llOwnerSay("Sleeping...");
405 llSetTimerEvent(30); 405 llSetTimerEvent(30);
406 } 406 }
407 timer() { 407 timer() {
408 llSetTimerEvent(0); 408 llSetTimerEvent(0);
409 state detect; 409 state detect;
410 } 410 }
411 on_rez(integer num) { 411 on_rez(integer num) {
412 llResetScript(); 412 llResetScript();
413 } 413 }
414 changed(integer change) { 414 changed(integer change) {
415 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 415 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
416 llResetScript(); 416 llResetScript();
417 } 417 }
418 } 418 }
419 } 419 }
420   420  
421 /* 421 /*
422 * This state checks to see whether Corrade has the necessary rights to 422 * This state checks to see whether Corrade has the necessary rights to
423 * modify your objects. It checks by using the "getfrienddata" command 423 * modify your objects. It checks by using the "getfrienddata" command
424 * which requires "friendship" Corrade permissions and then tests whether 424 * which requires "friendship" Corrade permissions and then tests whether
425 * the "CanModifyTheirObjects" flag is set that indicates whether Corrade 425 * the "CanModifyTheirObjects" flag is set that indicates whether Corrade
426 * is able to alter your objects. In the end it proceeds to the main state. 426 * is able to alter your objects. In the end it proceeds to the main state.
427 */ 427 */
428 state check_rights { 428 state check_rights {
429 state_entry() { 429 state_entry() {
430 // DEBUG 430 // DEBUG
431 llOwnerSay("Checking whether Corrade has rights to modify your objects..."); 431 llOwnerSay("Checking whether Corrade has rights to modify your objects...");
432 llInstantMessage( 432 llInstantMessage(
433 (key)CORRADE, 433 (key)CORRADE,
434 wasKeyValueEncode( 434 wasKeyValueEncode(
435 [ 435 [
436 "command", "getfrienddata", 436 "command", "getfrienddata",
437 "group", wasURLEscape(GROUP), 437 "group", wasURLEscape(GROUP),
438 "password", wasURLEscape(PASSWORD), 438 "password", wasURLEscape(PASSWORD),
439 "agent", wasURLEscape(llGetOwner()), 439 "agent", wasURLEscape(llGetOwner()),
440 "data", "CanModifyTheirObjects", 440 "data", "CanModifyTheirObjects",
441 "callback", wasURLEscape(callback) 441 "callback", wasURLEscape(callback)
442 ] 442 ]
443 ) 443 )
444 ); 444 );
445 llSetTimerEvent(60); 445 llSetTimerEvent(60);
446 } 446 }
447 http_request(key id, string method, string body) { 447 http_request(key id, string method, string body) {
448 llHTTPResponse(id, 200, "OK"); 448 llHTTPResponse(id, 200, "OK");
449 if(wasKeyValueGet("command", body) != "getfrienddata" || 449 if(wasKeyValueGet("command", body) != "getfrienddata" ||
450 wasKeyValueGet("success", body) != "True") { 450 wasKeyValueGet("success", body) != "True") {
451 // DEBUG 451 // DEBUG
452 llOwnerSay("Failed to get friend rights: " + 452 llOwnerSay("Failed to get friend rights: " +
453 wasURLUnescape( 453 wasURLUnescape(
454 wasKeyValueGet( 454 wasKeyValueGet(
455 "error", 455 "error",
456 body 456 body
457 ) 457 )
458 ) 458 )
459 ); 459 );
460 state detect_trampoline; 460 state detect_trampoline;
461 } 461 }
462 // DEBUG 462 // DEBUG
463 llOwnerSay("Got friend rights, checking..."); 463 llOwnerSay("Got friend rights, checking...");
464 list data = wasCSVToList(wasURLUnescape(wasKeyValueGet("data", body))); 464 list data = wasCSVToList(wasURLUnescape(wasKeyValueGet("data", body)));
465 integer i = llListFindList(data, [ "CanModifyTheirObjects" ]); 465 integer i = llListFindList(data, [ "CanModifyTheirObjects" ]);
466 if(i == -1) { 466 if(i == -1) {
467 // DEBUG 467 // DEBUG
468 llOwnerSay("Friend data not returned by the \"getfrienddata\" command..."); 468 llOwnerSay("Friend data not returned by the \"getfrienddata\" command...");
469 state detect_trampoline; 469 state detect_trampoline;
470 } 470 }
471 if(llList2String(data, i+1) != "True") { 471 if(llList2String(data, i+1) != "True") {
472 // DEBUG 472 // DEBUG
473 llOwnerSay("Corrade cannot modify your objects, please grant Corrade permissions to modify your objects using your viewer..."); 473 llOwnerSay("Corrade cannot modify your objects, please grant Corrade permissions to modify your objects using your viewer...");
474 state detect_trampoline; 474 state detect_trampoline;
475 } 475 }
476 // DEBUG 476 // DEBUG
477 llOwnerSay("Corrade has permissions to modify your objects, proceeding..."); 477 llOwnerSay("Corrade has permissions to modify your objects, proceeding...");
478 llSetTimerEvent(0); 478 llSetTimerEvent(0);
479 state select_face; 479 state select_face;
480 } 480 }
481 timer() { 481 timer() {
482 llSetTimerEvent(0); 482 llSetTimerEvent(0);
483 // DEBUG 483 // DEBUG
484 llOwnerSay("Timeout checking for friend rights..."); 484 llOwnerSay("Timeout checking for friend rights...");
485 state detect_trampoline; 485 state detect_trampoline;
486 } 486 }
487 on_rez(integer num) { 487 on_rez(integer num) {
488 llResetScript(); 488 llResetScript();
489 } 489 }
490 changed(integer change) { 490 changed(integer change) {
491 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 491 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
492 llResetScript(); 492 llResetScript();
493 } 493 }
494 } 494 }
495 } 495 }
496   496  
497 /* 497 /*
498 * In this state we retrieve a face number from the user. 498 * In this state we retrieve a face number from the user.
499 */ 499 */
500 state select_face { 500 state select_face {
501 state_entry() { 501 state_entry() {
502 if(TOUCH == NULL_KEY) { 502 if(TOUCH == NULL_KEY) {
503 //DEBUG 503 //DEBUG
504 llOwnerSay("Please touch the primitive for a menu..."); 504 llOwnerSay("Please touch the primitive for a menu...");
505 return; 505 return;
506 } 506 }
507 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6)); 507 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
508 integer i = llGetNumberOfSides() - 1; 508 integer i = llGetNumberOfSides() - 1;
509 list buttons = []; 509 list buttons = [];
510 do { 510 do {
511 buttons += (string)i; 511 buttons += (string)i;
512 llListen(comChannel, "", "", (string)i); 512 llListen(comChannel, "", "", (string)i);
513 } while(--i > -1); 513 } while(--i > -1);
514 buttons += "default"; 514 buttons += "default";
515 llListen(comChannel, "", "", "default"); 515 llListen(comChannel, "", "", "default");
516 buttons += "all"; 516 buttons += "all";
517 llListen(comChannel, "", "", "all"); 517 llListen(comChannel, "", "", "all");
518 llDialog(TOUCH, "Please select a face to change...", buttons, comChannel); 518 llDialog(TOUCH, "Please select a face to change...", buttons, comChannel);
519 } 519 }
520 touch_start(integer num) { 520 touch_start(integer num) {
521 TOUCH = llDetectedKey(0); 521 TOUCH = llDetectedKey(0);
522 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6)); 522 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
523 integer i = llGetNumberOfSides() - 1; 523 integer i = llGetNumberOfSides() - 1;
524 list buttons = []; 524 list buttons = [];
525 do { 525 do {
526 buttons += (string)i; 526 buttons += (string)i;
527 llListen(comChannel, "", "", (string)i); 527 llListen(comChannel, "", "", (string)i);
528 } while(--i > -1); 528 } while(--i > -1);
529 buttons += "default"; 529 buttons += "default";
530 llListen(comChannel, "", "", "default"); 530 llListen(comChannel, "", "", "default");
531 buttons += "all"; 531 buttons += "all";
532 llListen(comChannel, "", "", "all"); 532 llListen(comChannel, "", "", "all");
533 llDialog(TOUCH, "Please select a face to change...", buttons, comChannel); 533 llDialog(TOUCH, "Please select a face to change...", buttons, comChannel);
534 } 534 }
535 listen(integer channel, string name, key id, string face) { 535 listen(integer channel, string name, key id, string face) {
536 llOwnerSay("Got face: " + face); 536 llOwnerSay("Got face: " + face);
537 FACE = face; 537 FACE = face;
538 state select_texture; 538 state select_texture;
539 } 539 }
540 on_rez(integer num) { 540 on_rez(integer num) {
541 llResetScript(); 541 llResetScript();
542 } 542 }
543 changed(integer change) { 543 changed(integer change) {
544 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 544 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
545 llResetScript(); 545 llResetScript();
546 } 546 }
547 } 547 }
548 } 548 }
549 /* 549 /*
550 * In this state we let the user select a texture from inventory. 550 * In this state we let the user select a texture from inventory.
551 */ 551 */
552 state select_texture { 552 state select_texture {
553 state_entry() { 553 state_entry() {
554 if(TOUCH == NULL_KEY) return; 554 if(TOUCH == NULL_KEY) return;
555 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6)); 555 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
556 integer i = llGetInventoryNumber(INVENTORY_TEXTURE) -1; 556 integer i = llGetInventoryNumber(INVENTORY_TEXTURE) -1;
557 list buttons = []; 557 list buttons = [];
558 do { 558 do {
559 string inventoryTexture = llGetInventoryName(INVENTORY_TEXTURE, i); 559 string inventoryTexture = llGetInventoryName(INVENTORY_TEXTURE, i);
560 buttons += inventoryTexture; 560 buttons += inventoryTexture;
561 llListen(comChannel, "", "", inventoryTexture); 561 llListen(comChannel, "", "", inventoryTexture);
562 } while(--i > -1); 562 } while(--i > -1);
563 llDialog(TOUCH, "Please select from the avilable textures...", buttons, comChannel); 563 llDialog(TOUCH, "Please select from the avilable textures...", buttons, comChannel);
564 } 564 }
565 touch_start(integer num) { 565 touch_start(integer num) {
566 TOUCH = llDetectedKey(0); 566 TOUCH = llDetectedKey(0);
567 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6)); 567 integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
568 integer i = llGetInventoryNumber(INVENTORY_TEXTURE) -1; 568 integer i = llGetInventoryNumber(INVENTORY_TEXTURE) -1;
569 list buttons = []; 569 list buttons = [];
570 do { 570 do {
571 string inventoryTexture = llGetInventoryName(INVENTORY_TEXTURE, i); 571 string inventoryTexture = llGetInventoryName(INVENTORY_TEXTURE, i);
572 buttons += inventoryTexture; 572 buttons += inventoryTexture;
573 llListen(comChannel, "", "", inventoryTexture); 573 llListen(comChannel, "", "", inventoryTexture);
574 } while(--i > -1); 574 } while(--i > -1);
575 llDialog(TOUCH, "Please select from the avilable textures...", buttons, comChannel); 575 llDialog(TOUCH, "Please select from the avilable textures...", buttons, comChannel);
576 } 576 }
577 listen(integer channel, string name, key id, string inventoryTexture) { 577 listen(integer channel, string name, key id, string inventoryTexture) {
578 llOwnerSay("Got texture: " + inventoryTexture); 578 llOwnerSay("Got texture: " + inventoryTexture);
579 TEXTURE = inventoryTexture; 579 TEXTURE = inventoryTexture;
580 state change_texture; 580 state change_texture;
581 } 581 }
582 on_rez(integer num) { 582 on_rez(integer num) {
583 llResetScript(); 583 llResetScript();
584 } 584 }
585 changed(integer change) { 585 changed(integer change) {
586 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 586 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
587 llResetScript(); 587 llResetScript();
588 } 588 }
589 } 589 }
590 } 590 }
591   591  
592 /* 592 /*
593 * This state is reponsible for setting the texture on the previously 593 * This state is reponsible for setting the texture on the previously
594 * selected face of this primitive. It makes a call to Corrade to set the 594 * selected face of this primitive. It makes a call to Corrade to set the
595 * texture on the selected face and then returns to the face selection. 595 * texture on the selected face and then returns to the face selection.
596 * This state relies on the "interact" Corrade permission being set 596 * This state relies on the "interact" Corrade permission being set
597 * for the group that you are using this script with. 597 * for the group that you are using this script with.
598 */ 598 */
599 state change_texture { 599 state change_texture {
600 state_entry() { 600 state_entry() {
601 // DEBUG 601 // DEBUG
602 llOwnerSay("Setting texture \"" + TEXTURE + "\" on face \"" + FACE + "\"."); 602 llOwnerSay("Setting texture \"" + TEXTURE + "\" on face \"" + FACE + "\".");
603 llInstantMessage(CORRADE, wasKeyValueEncode( 603 llInstantMessage(CORRADE, wasKeyValueEncode(
604 [ 604 [
605 // set the texture for the 4th face 605 // set the texture for the 4th face
606 // on a primitive in a 4m range 606 // on a primitive in a 4m range
607 // specified by UUID 607 // specified by UUID
608 "command", "setprimitivetexturedata", 608 "command", "setprimitivetexturedata",
609 "group", wasURLEscape(GROUP), 609 "group", wasURLEscape(GROUP),
610 "password", wasURLEscape(PASSWORD), 610 "password", wasURLEscape(PASSWORD),
611 // the UUID of the primitive 611 // the UUID of the primitive
612 "item", wasURLEscape(llGetKey()), 612 "item", wasURLEscape(llGetKey()),
613 "range", 5, 613 "range", 5,
614 // the face 614 // the face
615 "face", FACE, 615 "face", FACE,
616 // just set the texture to a texture UUID 616 // just set the texture to a texture UUID
617 "data", wasURLEscape( 617 "data", wasURLEscape(
618 wasListToCSV( 618 wasListToCSV(
619 [ 619 [
620 "TextureID", llGetInventoryKey(TEXTURE) 620 "TextureID", llGetInventoryKey(TEXTURE)
621 ] 621 ]
622 ) 622 )
623 ), 623 ),
624 "callback", wasURLEscape(callback) 624 "callback", wasURLEscape(callback)
625 ] 625 ]
626 ) 626 )
627 ); 627 );
628 llSetTimerEvent(60); 628 llSetTimerEvent(60);
629 } 629 }
630 http_request(key id, string method, string body) { 630 http_request(key id, string method, string body) {
631 llHTTPResponse(id, 200, "OK"); 631 llHTTPResponse(id, 200, "OK");
632 if(wasKeyValueGet("command", body) != "setprimitivetexturedata" || 632 if(wasKeyValueGet("command", body) != "setprimitivetexturedata" ||
633 wasKeyValueGet("success", body) != "True") { 633 wasKeyValueGet("success", body) != "True") {
634 // DEBUG 634 // DEBUG
635 llOwnerSay("Failed to set texture: " + 635 llOwnerSay("Failed to set texture: " +
636 wasURLUnescape( 636 wasURLUnescape(
637 wasKeyValueGet( 637 wasKeyValueGet(
638 "error", 638 "error",
639 body 639 body
640 ) 640 )
641 ) 641 )
642 ); 642 );
643 state detect_trampoline; 643 state detect_trampoline;
644 } 644 }
645 // DEBUG 645 // DEBUG
646 llOwnerSay("Texture set successfully..."); 646 llOwnerSay("Texture set successfully...");
647 state select_face; 647 state select_face;
648 } 648 }
649 timer() { 649 timer() {
650 llSetTimerEvent(0); 650 llSetTimerEvent(0);
651 // DEBUG 651 // DEBUG
652 llOwnerSay("Timeout setting texture..."); 652 llOwnerSay("Timeout setting texture...");
653 state detect_trampoline; 653 state detect_trampoline;
654 } 654 }
655 on_rez(integer num) { 655 on_rez(integer num) {
656 llResetScript(); 656 llResetScript();
657 } 657 }
658 changed(integer change) { 658 changed(integer change) {
659 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) { 659 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
660 llResetScript(); 660 llResetScript();
661 } 661 }
662 } 662 }
663 } 663 }
664   664  
665   665