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 2015 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2015 - License: CC BY 2.0 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 3 // Please see: https://creativecommons.org/licenses/by/2.0 for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. // 4 // rights of fair usage, the disclaimer and warranty conditions. //
5 /////////////////////////////////////////////////////////////////////////// 5 ///////////////////////////////////////////////////////////////////////////
6   6  
7 /////////////////////////////////////////////////////////////////////////// 7 ///////////////////////////////////////////////////////////////////////////
8 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 8 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
9 /////////////////////////////////////////////////////////////////////////// 9 ///////////////////////////////////////////////////////////////////////////
10 // escapes a string in conformance with RFC1738 10 // escapes a string in conformance with RFC1738
11 string wasURLEscape(string i) { 11 string wasURLEscape(string i) {
12 string o = ""; 12 string o = "";
13 do { 13 do {
14 string c = llGetSubString(i, 0, 0); 14 string c = llGetSubString(i, 0, 0);
15 i = llDeleteSubString(i, 0, 0); 15 i = llDeleteSubString(i, 0, 0);
16 if(c == "") jump continue; 16 if(c == "") jump continue;
17 if(c == " ") { 17 if(c == " ") {
18 o += "+"; 18 o += "+";
19 jump continue; 19 jump continue;
20 } 20 }
21 if(c == "\n") { 21 if(c == "\n") {
22 o += "%0D" + llEscapeURL(c); 22 o += "%0D" + llEscapeURL(c);
23 jump continue; 23 jump continue;
24 } 24 }
25 o += llEscapeURL(c); 25 o += llEscapeURL(c);
26 @continue; 26 @continue;
27 } while(i != ""); 27 } while(i != "");
28 return o; 28 return o;
29 } 29 }
30   30  
31 /////////////////////////////////////////////////////////////////////////// 31 ///////////////////////////////////////////////////////////////////////////
32 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 32 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
33 /////////////////////////////////////////////////////////////////////////// 33 ///////////////////////////////////////////////////////////////////////////
34 // unescapes a string in conformance with RFC1738 34 // unescapes a string in conformance with RFC1738
35 string wasURLUnescape(string i) { 35 string wasURLUnescape(string i) {
36 return llUnescapeURL( 36 return llUnescapeURL(
37 llDumpList2String( 37 llDumpList2String(
38 llParseString2List( 38 llParseString2List(
39 llDumpList2String( 39 llDumpList2String(
40 llParseString2List( 40 llParseString2List(
41 i, 41 i,
42 ["+"], 42 ["+"],
43 [] 43 []
44 ), 44 ),
45 " " 45 " "
46 ), 46 ),
47 ["%0D%0A"], 47 ["%0D%0A"],
48 [] 48 []
49 ), 49 ),
50 "\n" 50 "\n"
51 ) 51 )
52 ); 52 );
53 } 53 }
54   54  
55 /////////////////////////////////////////////////////////////////////////// 55 ///////////////////////////////////////////////////////////////////////////
56 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // 56 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 //
57 /////////////////////////////////////////////////////////////////////////// 57 ///////////////////////////////////////////////////////////////////////////
58 string wasKeyValueEncode(list data) { 58 string wasKeyValueEncode(list data) {
59 list k = llList2ListStrided(data, 0, -1, 2); 59 list k = llList2ListStrided(data, 0, -1, 2);
60 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 60 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
61 data = []; 61 data = [];
62 do { 62 do {
63 data += llList2String(k, 0) + "=" + llList2String(v, 0); 63 data += llList2String(k, 0) + "=" + llList2String(v, 0);
64 k = llDeleteSubList(k, 0, 0); 64 k = llDeleteSubList(k, 0, 0);
65 v = llDeleteSubList(v, 0, 0); 65 v = llDeleteSubList(v, 0, 0);
66 } while(llGetListLength(k) != 0); 66 } while(llGetListLength(k) != 0);
67 return llDumpList2String(data, "&"); 67 return llDumpList2String(data, "&");
68 } 68 }
69   69  
70 /////////////////////////////////////////////////////////////////////////// 70 ///////////////////////////////////////////////////////////////////////////
71 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 71 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
72 /////////////////////////////////////////////////////////////////////////// 72 ///////////////////////////////////////////////////////////////////////////
73 string wasKeyValueGet(string k, string data) { 73 string wasKeyValueGet(string k, string data) {
74 if(llStringLength(data) == 0) return ""; 74 if(llStringLength(data) == 0) return "";
75 if(llStringLength(k) == 0) return ""; 75 if(llStringLength(k) == 0) return "";
76 list a = llParseString2List(data, ["&", "="], []); 76 list a = llParseString2List(data, ["&", "="], []);
77 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); 77 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
78 if(i != -1) return llList2String(a, 2*i+1); 78 if(i != -1) return llList2String(a, 2*i+1);
79 return ""; 79 return "";
80 } 80 }
81   81  
82 /////////////////////////////////////////////////////////////////////////// 82 ///////////////////////////////////////////////////////////////////////////
83 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 83 // Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 //
84 /////////////////////////////////////////////////////////////////////////// 84 ///////////////////////////////////////////////////////////////////////////
85 list wasCSVToList(string csv) { 85 list wasCSVToList(string csv) {
86 list l = []; 86 list l = [];
87 list s = []; 87 list s = [];
88 string m = ""; 88 string m = "";
89 do { 89 do {
90 string a = llGetSubString(csv, 0, 0); 90 string a = llGetSubString(csv, 0, 0);
91 csv = llDeleteSubString(csv, 0, 0); 91 csv = llDeleteSubString(csv, 0, 0);
92 if(a == ",") { 92 if(a == ",") {
93 if(llList2String(s, -1) != "\"") { 93 if(llList2String(s, -1) != "\"") {
94 l += m; 94 l += m;
95 m = ""; 95 m = "";
96 jump continue; 96 jump continue;
97 } 97 }
98 m += a; 98 m += a;
99 jump continue; 99 jump continue;
100 } 100 }
101 if(a == "\"" && llGetSubString(csv, 0, 0) == a) { 101 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
102 m += a; 102 m += a;
103 csv = llDeleteSubString(csv, 0, 0); 103 csv = llDeleteSubString(csv, 0, 0);
104 jump continue; 104 jump continue;
105 } 105 }
106 if(a == "\"") { 106 if(a == "\"") {
107 if(llList2String(s, -1) != a) { 107 if(llList2String(s, -1) != a) {
108 s += a; 108 s += a;
109 jump continue; 109 jump continue;
110 } 110 }
111 s = llDeleteSubList(s, -1, -1); 111 s = llDeleteSubList(s, -1, -1);
112 jump continue; 112 jump continue;
113 } 113 }
114 m += a; 114 m += a;
115 @continue; 115 @continue;
116 } while(csv != ""); 116 } while(csv != "");
117 // postcondition: length(s) = 0 117 // postcondition: length(s) = 0
118 return l + m; 118 return l + m;
119 } 119 }
120   120  
121 /////////////////////////////////////////////////////////////////////////// 121 ///////////////////////////////////////////////////////////////////////////
122 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // 122 // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 //
123 /////////////////////////////////////////////////////////////////////////// 123 ///////////////////////////////////////////////////////////////////////////
124 integer wasDateTimeToStamp( 124 integer wasDateTimeToStamp(
125 integer year, 125 integer year,
126 integer month, 126 integer month,
127 integer day, 127 integer day,
128 integer hour, 128 integer hour,
129 integer minute, 129 integer minute,
130 integer second 130 integer second
131 ) { 131 ) {
132 month -= 2; 132 month -= 2;
133 if (month <= 0) { 133 if (month <= 0) {
134 month += 12; 134 month += 12;
135 --year; 135 --year;
136 } 136 }
137 return 137 return
138 ( 138 (
139 (((year / 4 - year / 100 + year / 400 + (367 * month) / 12 + day) + 139 (((year / 4 - year / 100 + year / 400 + (367 * month) / 12 + day) +
140 year * 365 - 719499 140 year * 365 - 719499
141 ) * 24 + hour 141 ) * 24 + hour
142 ) * 60 + minute 142 ) * 60 + minute
143 ) * 60 + second; 143 ) * 60 + second;
144 } 144 }
145   145  
146 /////////////////////////////////////////////////////////////////////////// 146 ///////////////////////////////////////////////////////////////////////////
147 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 147 // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 //
148 /////////////////////////////////////////////////////////////////////////// 148 ///////////////////////////////////////////////////////////////////////////
149 float wasFmod(float a, float p) { 149 float wasFmod(float a, float p) {
150 if(p == 0) return (float)"nan"; 150 if(p == 0) return (float)"nan";
151 return a - ((integer)(a/p) * p); 151 return a - ((integer)(a/p) * p);
152 } 152 }
153   153  
154 /////////////////////////////////////////////////////////////////////////// 154 ///////////////////////////////////////////////////////////////////////////
155 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 155 // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 //
156 // Original: Clive Page, Leicester University, UK. 1995-MAY-2 // 156 // Original: Clive Page, Leicester University, UK. 1995-MAY-2 //
157 /////////////////////////////////////////////////////////////////////////// 157 ///////////////////////////////////////////////////////////////////////////
158 list wasUnixTimeToDateTime(integer seconds) { 158 list wasUnixTimeToDateTime(integer seconds) {
159 integer mjday = (integer)(seconds/86400 + 40587); 159 integer mjday = (integer)(seconds/86400 + 40587);
160 integer dateYear = 1858 + (integer)( (mjday + 321.51) / 365.25); 160 integer dateYear = 1858 + (integer)( (mjday + 321.51) / 365.25);
161 float day = (integer)( wasFmod(mjday + 262.25, 365.25) ) + 0.5; 161 float day = (integer)( wasFmod(mjday + 262.25, 365.25) ) + 0.5;
162 integer dateMonth = 1 + (integer)(wasFmod(day / 30.6 + 2.0, 12.0) ); 162 integer dateMonth = 1 + (integer)(wasFmod(day / 30.6 + 2.0, 12.0) );
163 integer dateDay = 1 + (integer)(wasFmod(day,30.6)); 163 integer dateDay = 1 + (integer)(wasFmod(day,30.6));
164 float nsecs = wasFmod(seconds, 86400); 164 float nsecs = wasFmod(seconds, 86400);
165 integer dateSeconds = (integer)wasFmod(nsecs, 60); 165 integer dateSeconds = (integer)wasFmod(nsecs, 60);
166 nsecs = nsecs / 60; 166 nsecs = nsecs / 60;
167 integer dateMinutes = (integer)wasFmod(nsecs, 60); 167 integer dateMinutes = (integer)wasFmod(nsecs, 60);
168 integer dateHour = (integer)(nsecs / 60); 168 integer dateHour = (integer)(nsecs / 60);
169 return [ dateYear, 169 return [ dateYear,
170 dateMonth, dateDay, dateHour, dateMinutes, dateSeconds ]; 170 dateMonth, dateDay, dateHour, dateMinutes, dateSeconds ];
171 } 171 }
172   172  
173 // for changing states 173 // for changing states
174 string nextstate = ""; 174 string nextstate = "";
175   175  
176 // notecard reading 176 // notecard reading
177 integer line = 0; 177 integer line = 0;
178 list tuples = []; 178 list tuples = [];
179   179  
180 // corrade data 180 // corrade data
181 key CORRADE = NULL_KEY; 181 key CORRADE = NULL_KEY;
182 string GROUP = ""; 182 string GROUP = "";
183 string PASSWORD = ""; 183 string PASSWORD = "";
184 // the owner of the rental system 184 // the owner of the rental system
185 // the dude or dudette that gets paid 185 // the dude or dudette that gets paid
186 key OWNER = NULL_KEY; 186 key OWNER = NULL_KEY;
187 // the price of the rent 187 // the price of the rent
188 integer PRICE = 0; 188 integer PRICE = 0;
189 // the time for the rent in seconds 189 // the time for the rent in seconds
190 integer RENT = 0; 190 integer RENT = 0;
191 string URL = ""; 191 string URL = "";
192 // the role to invite rentants to 192 // the role to invite rentants to
193 string ROLE = ""; 193 string ROLE = "";
194   194  
195 default { 195 default {
196 state_entry() { 196 state_entry() {
197 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) { 197 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
198 llSetText("Sorry, could not find an inventory notecard.", <1, 0, 0>, 1.0); 198 llSetText("Sorry, could not find an inventory notecard.", <1, 0, 0>, 1.0);
199 return; 199 return;
200 } 200 }
201 llSetText("Reading configuration notecard...", <1, 1, 0>, 1.0); 201 llSetText("Reading configuration notecard...", <1, 1, 0>, 1.0);
202 llGetNotecardLine("configuration", line); 202 llGetNotecardLine("configuration", line);
203 } 203 }
204 dataserver(key id, string data) { 204 dataserver(key id, string data) {
205 if(data == EOF) { 205 if(data == EOF) {
206 // invariant, length(tuples) % 2 == 0 206 // invariant, length(tuples) % 2 == 0
207 if(llGetListLength(tuples) % 2 != 0) { 207 if(llGetListLength(tuples) % 2 != 0) {
208 llSetText("Error in configuration notecard.", <1, 0, 0>, 1.0); 208 llSetText("Error in configuration notecard.", <1, 0, 0>, 1.0);
209 return; 209 return;
210 } 210 }
211 CORRADE = (key)llList2String( 211 CORRADE = (key)llList2String(
212 tuples, 212 tuples,
213 llListFindList( 213 llListFindList(
214 tuples, 214 tuples,
215 [ 215 [
216 "corrade" 216 "corrade"
217 ] 217 ]
218 ) 218 )
219 +1); 219 +1);
220 if(CORRADE == NULL_KEY) { 220 if(CORRADE == NULL_KEY) {
221 llSetText("Error in configuration notecard: corrade", <1, 0, 0>, 1.0); 221 llSetText("Error in configuration notecard: corrade", <1, 0, 0>, 1.0);
222 return; 222 return;
223 } 223 }
224 GROUP = llList2String( 224 GROUP = llList2String(
225 tuples, 225 tuples,
226 llListFindList( 226 llListFindList(
227 tuples, 227 tuples,
228 [ 228 [
229 "group" 229 "group"
230 ] 230 ]
231 ) 231 )
232 +1); 232 +1);
233 if(GROUP == "") { 233 if(GROUP == "") {
234 llSetText("Error in configuration notecard: group", <1, 0, 0>, 1.0); 234 llSetText("Error in configuration notecard: group", <1, 0, 0>, 1.0);
235 return; 235 return;
236 } 236 }
237 PASSWORD = llList2String( 237 PASSWORD = llList2String(
238 tuples, 238 tuples,
239 llListFindList( 239 llListFindList(
240 tuples, 240 tuples,
241 [ 241 [
242 "password" 242 "password"
243 ] 243 ]
244 ) 244 )
245 +1); 245 +1);
246 if(PASSWORD == "") { 246 if(PASSWORD == "") {
247 llSetText("Error in configuration notecard: password", <1, 0, 0>, 1.0); 247 llSetText("Error in configuration notecard: password", <1, 0, 0>, 1.0);
248 return; 248 return;
249 } 249 }
250 OWNER = (key)llList2String( 250 OWNER = (key)llList2String(
251 tuples, 251 tuples,
252 llListFindList( 252 llListFindList(
253 tuples, 253 tuples,
254 [ 254 [
255 "owner" 255 "owner"
256 ] 256 ]
257 ) 257 )
258 +1); 258 +1);
259 if(OWNER == NULL_KEY) { 259 if(OWNER == NULL_KEY) {
260 llSetText("Error in configuration notecard: owner", <1, 0, 0>, 1.0); 260 llSetText("Error in configuration notecard: owner", <1, 0, 0>, 1.0);
261 return; 261 return;
262 } 262 }
263 PRICE = (integer)llList2String( 263 PRICE = (integer)llList2String(
264 tuples, 264 tuples,
265 llListFindList( 265 llListFindList(
266 tuples, 266 tuples,
267 [ 267 [
268 "price" 268 "price"
269 ] 269 ]
270 ) 270 )
271 +1); 271 +1);
272 if(PRICE == 0) { 272 if(PRICE == 0) {
273 llSetText("Error in configuration notecard: price", <1, 0, 0>, 1.0); 273 llSetText("Error in configuration notecard: price", <1, 0, 0>, 1.0);
274 return; 274 return;
275 } 275 }
276 RENT = (integer)llList2String( 276 RENT = (integer)llList2String(
277 tuples, 277 tuples,
278 llListFindList( 278 llListFindList(
279 tuples, 279 tuples,
280 [ 280 [
281 "rent" 281 "rent"
282 ] 282 ]
283 ) 283 )
284 +1); 284 +1);
285 if(RENT == 0) { 285 if(RENT == 0) {
286 llSetText("Error in configuration notecard: rent", <1, 0, 0>, 1.0); 286 llSetText("Error in configuration notecard: rent", <1, 0, 0>, 1.0);
287 return; 287 return;
288 } 288 }
289 ROLE = llList2String( 289 ROLE = llList2String(
290 tuples, 290 tuples,
291 llListFindList( 291 llListFindList(
292 tuples, 292 tuples,
293 [ 293 [
294 "role" 294 "role"
295 ] 295 ]
296 ) 296 )
297 +1 297 +1
298 ); 298 );
299 if(ROLE == "") { 299 if(ROLE == "") {
300 llSetText("Error in configuration notecard: role", <1, 0, 0>, 1.0); 300 llSetText("Error in configuration notecard: role", <1, 0, 0>, 1.0);
301 return; 301 return;
302 } 302 }
303 303
304 llSetText("Read configuration notecard.", <0, 1, 0>, 1.0); 304 llSetText("Read configuration notecard.", <0, 1, 0>, 1.0);
305 305
306 // if data is set switch to rented state 306 // if data is set switch to rented state
307 if(llGetObjectDesc() != "") state rented; 307 if(llGetObjectDesc() != "") state rented;
308 // otherwise switch to the payment state 308 // otherwise switch to the payment state
309 state payment; 309 state payment;
310 } 310 }
311 if(data == "") jump continue; 311 if(data == "") jump continue;
312 integer i = llSubStringIndex(data, "#"); 312 integer i = llSubStringIndex(data, "#");
313 if(i != -1) data = llDeleteSubString(data, i, -1); 313 if(i != -1) data = llDeleteSubString(data, i, -1);
314 list o = llParseString2List(data, ["="], []); 314 list o = llParseString2List(data, ["="], []);
315 // get rid of starting and ending quotes 315 // get rid of starting and ending quotes
316 string k = llDumpList2String( 316 string k = llDumpList2String(
317 llParseString2List( 317 llParseString2List(
318 llStringTrim( 318 llStringTrim(
319 llList2String( 319 llList2String(
320 o, 320 o,
321 0 321 0
322 ), 322 ),
323 STRING_TRIM), 323 STRING_TRIM),
324 ["\""], [] 324 ["\""], []
325 ), "\""); 325 ), "\"");
326 string v = llDumpList2String( 326 string v = llDumpList2String(
327 llParseString2List( 327 llParseString2List(
328 llStringTrim( 328 llStringTrim(
329 llList2String( 329 llList2String(
330 o, 330 o,
331 1 331 1
332 ), 332 ),
333 STRING_TRIM), 333 STRING_TRIM),
334 ["\""], [] 334 ["\""], []
335 ), "\""); 335 ), "\"");
336 if(k == "" || v == "") jump continue; 336 if(k == "" || v == "") jump continue;
337 tuples += k; 337 tuples += k;
338 tuples += v; 338 tuples += v;
339 @continue; 339 @continue;
340 llGetNotecardLine("configuration", ++line); 340 llGetNotecardLine("configuration", ++line);
341 } 341 }
342 on_rez(integer num) { 342 on_rez(integer num) {
343 llResetScript(); 343 llResetScript();
344 } 344 }
345 changed(integer change) { 345 changed(integer change) {
346 if(change & CHANGED_INVENTORY) { 346 if(change & CHANGED_INVENTORY) {
347 llResetScript(); 347 llResetScript();
348 } 348 }
349 } 349 }
350 } 350 }
351   351  
352 state trampoline { 352 state trampoline {
353 state_entry() { 353 state_entry() {
354 llSetTimerEvent(5); 354 llSetTimerEvent(5);
355 } 355 }
356 timer() { 356 timer() {
357 llSetTimerEvent(0); 357 llSetTimerEvent(0);
358 // State jump table 358 // State jump table
359 if(nextstate == "url") state url; 359 if(nextstate == "url") state url;
360 if(nextstate == "getmembers") state getmembers; 360 if(nextstate == "getmembers") state getmembers;
361 if(nextstate == "getrolemembers") state getrolemembers; 361 if(nextstate == "getrolemembers") state getrolemembers;
362 if(nextstate == "addtorole") state addtorole; 362 if(nextstate == "addtorole") state addtorole;
363 if(nextstate == "invite") state invite; 363 if(nextstate == "invite") state invite;
364 if(nextstate == "rented") state rented; 364 if(nextstate == "rented") state rented;
365 if(nextstate == "demote") state demote; 365 if(nextstate == "demote") state demote;
366 // automata in invalid state 366 // automata in invalid state
367 } 367 }
368 on_rez(integer num) { 368 on_rez(integer num) {
369 llResetScript(); 369 llResetScript();
370 } 370 }
371 changed(integer change) { 371 changed(integer change) {
372 if(change & CHANGED_INVENTORY) { 372 if(change & CHANGED_INVENTORY) {
373 llResetScript(); 373 llResetScript();
374 } 374 }
375 } 375 }
376 } 376 }
377   377  
378 state payment { 378 state payment {
379 state_entry() { 379 state_entry() {
380 llSetPayPrice(PRICE, [PRICE]); 380 llSetPayPrice(PRICE, [PRICE]);
381 llSetClickAction(CLICK_ACTION_PAY); 381 llSetClickAction(CLICK_ACTION_PAY);
382 llSetText("☀ Touch me to rent this place! ☀", <0, 1, 0>, 1.0); 382 llSetText("☀ Touch me to rent this place! ☀", <0, 1, 0>, 1.0);
383 } 383 }
384 money(key id, integer amount) { 384 money(key id, integer amount) {
385 // Get the current time stamp. 385 // Get the current time stamp.
386 list stamp = llList2List( 386 list stamp = llList2List(
387 llParseString2List( 387 llParseString2List(
388 llGetTimestamp(), 388 llGetTimestamp(),
389 ["-",":","T", "."],[""] 389 ["-",":","T", "."],[""]
390 ), 390 ),
391 0, 5 391 0, 5
392 ); 392 );
393 // convert to seconds and add the rent 393 // convert to seconds and add the rent
394 integer delta = wasDateTimeToStamp( 394 integer delta = wasDateTimeToStamp(
395 llList2Integer(stamp, 0), 395 llList2Integer(stamp, 0),
396 llList2Integer(stamp, 1), 396 llList2Integer(stamp, 1),
397 llList2Integer(stamp, 2), 397 llList2Integer(stamp, 2),
398 llList2Integer(stamp, 3), 398 llList2Integer(stamp, 3),
399 llList2Integer(stamp, 4), 399 llList2Integer(stamp, 4),
400 llList2Integer(stamp, 5) 400 llList2Integer(stamp, 5)
401 ) + 401 ) +
402 // the amount of time is the amount paid 402 // the amount of time is the amount paid
403 // times the rent time divided by the price 403 // times the rent time divided by the price
404 amount * (integer)( 404 amount * (integer)(
405 (float)RENT / 405 (float)RENT /
406 (float)PRICE 406 (float)PRICE
407 ); 407 );
408 // convert back to a timestamp 408 // convert back to a timestamp
409 stamp = wasUnixTimeToDateTime(delta); 409 stamp = wasUnixTimeToDateTime(delta);
410 // and set the renter and the eviction date 410 // and set the renter and the eviction date
411 llSetObjectDesc( 411 llSetObjectDesc(
412 wasKeyValueEncode( 412 wasKeyValueEncode(
413 [ 413 [
414 "rentantUUID", id, 414 "rentantUUID", id,
415 "rentantName", llKey2Name(id), 415 "rentantName", llKey2Name(id),
416 "expiresDate", llList2String(stamp, 0) + 416 "expiresDate", llList2String(stamp, 0) +
417 "-" + llList2String(stamp, 1) + 417 "-" + llList2String(stamp, 1) +
418 "-" + llList2String(stamp, 2) + 418 "-" + llList2String(stamp, 2) +
419 "T" + llList2String(stamp, 3) + 419 "T" + llList2String(stamp, 3) +
420 ":" + llList2String(stamp, 4) + 420 ":" + llList2String(stamp, 4) +
421 ":" + llList2String(stamp, 5) 421 ":" + llList2String(stamp, 5)
422 ] 422 ]
423 ) 423 )
424 ); 424 );
425 nextstate = "getmembers"; 425 nextstate = "getmembers";
426 state url; 426 state url;
427 } 427 }
428 on_rez(integer num) { 428 on_rez(integer num) {
429 llResetScript(); 429 llResetScript();
430 } 430 }
431 changed(integer change) { 431 changed(integer change) {
432 if(change & CHANGED_INVENTORY) { 432 if(change & CHANGED_INVENTORY) {
433 llResetScript(); 433 llResetScript();
434 } 434 }
435 } 435 }
436 } 436 }
437   437  
438 state url { 438 state url {
439 state_entry() { 439 state_entry() {
440 // release any previous URL 440 // release any previous URL
441 llReleaseURL(URL); 441 llReleaseURL(URL);
442 // request a new URL 442 // request a new URL
443 llRequestURL(); 443 llRequestURL();
444 } 444 }
445 http_request(key id, string method, string body) { 445 http_request(key id, string method, string body) {
446 if(method != URL_REQUEST_GRANTED) { 446 if(method != URL_REQUEST_GRANTED) {
447 llSetText("☀ Unable to get an URL! ☀", <1, 0, 0>, 1.0); 447 llSetText("☀ Unable to get an URL! ☀", <1, 0, 0>, 1.0);
448 nextstate = "url"; 448 nextstate = "url";
449 state trampoline; 449 state trampoline;
450 } 450 }
451 URL = body; 451 URL = body;
452 // state URL jump table 452 // state URL jump table
453 if(nextstate == "getmembers") state getmembers; 453 if(nextstate == "getmembers") state getmembers;
454 if(nextstate == "demote") state demote; 454 if(nextstate == "demote") state demote;
455 // automata in invalid state 455 // automata in invalid state
456 } 456 }
457 on_rez(integer num) { 457 on_rez(integer num) {
458 llResetScript(); 458 llResetScript();
459 } 459 }
460 changed(integer change) { 460 changed(integer change) {
461 if(change & CHANGED_INVENTORY) { 461 if(change & CHANGED_INVENTORY) {
462 llResetScript(); 462 llResetScript();
463 } 463 }
464 } 464 }
465 } 465 }
466   466  
467 state getmembers { 467 state getmembers {
468 state_entry() { 468 state_entry() {
469 llSetText("☀ Getting group members... ☀", <1, 1, 0>, 1.0); 469 llSetText("☀ Getting group members... ☀", <1, 1, 0>, 1.0);
470 llInstantMessage(CORRADE, 470 llInstantMessage(CORRADE,
471 wasKeyValueEncode( 471 wasKeyValueEncode(
472 [ 472 [
473 "command", "getmembers", 473 "command", "getmembers",
474 "group", wasURLEscape(GROUP), 474 "group", wasURLEscape(GROUP),
475 "password", wasURLEscape(PASSWORD), 475 "password", wasURLEscape(PASSWORD),
476 // we just care if the agent is in the group 476 // we just care if the agent is in the group
477 // so we use Corrade's sifting ability in order 477 // so we use Corrade's sifting ability in order
478 // to reduce the script memory usage 478 // to reduce the script memory usage
479 "sift", wasURLEscape( 479 "sift", wasURLEscape(
480 "(" + 480 "(" +
481 wasKeyValueGet( 481 wasKeyValueGet(
482 "rentantUUID", 482 "rentantUUID",
483 llGetObjectDesc() 483 llGetObjectDesc()
484 ) + 484 ) +
485 ")*" 485 ")*"
486 ), 486 ),
487 "callback", wasURLEscape(URL) 487 "callback", wasURLEscape(URL)
488 ] 488 ]
489 ) 489 )
490 ); 490 );
491 llSetTimerEvent(60); 491 llSetTimerEvent(60);
492 } 492 }
493 http_request(key id, string method, string body) { 493 http_request(key id, string method, string body) {
494 if(wasKeyValueGet("success", body) != "True") { 494 if(wasKeyValueGet("success", body) != "True") {
495 llSetText("☀ Could not get group members! ☀", <1, 0, 0>, 1.0); 495 llSetText("☀ Could not get group members! ☀", <1, 0, 0>, 1.0);
496 nextstate = "getmembers"; 496 nextstate = "getmembers";
497 state trampoline; 497 state trampoline;
498 } 498 }
499 // check that the payer is part of the role 499 // check that the payer is part of the role
500 integer i = 500 integer i =
501 llListFindList( 501 llListFindList(
502 wasCSVToList( 502 wasCSVToList(
503 wasURLUnescape( 503 wasURLUnescape(
504 wasKeyValueGet( 504 wasKeyValueGet(
505 "data", 505 "data",
506 body 506 body
507 ) 507 )
508 ) 508 )
509 ), 509 ),
510 (list)wasKeyValueGet( 510 (list)wasKeyValueGet(
511 "rentantUUID", 511 "rentantUUID",
512 llGetObjectDesc() 512 llGetObjectDesc()
513 ) 513 )
514 ); 514 );
515 llSetTimerEvent(0); 515 llSetTimerEvent(0);
516 // if they are in the group then check roles. 516 // if they are in the group then check roles.
517 if(i != -1) state getrolemembers; 517 if(i != -1) state getrolemembers;
518 // otherwise invite them to the group role. 518 // otherwise invite them to the group role.
519 state invite; 519 state invite;
520 } 520 }
521 timer() { 521 timer() {
522 llSetTimerEvent(0); 522 llSetTimerEvent(0);
523 nextstate = "getmembers"; 523 nextstate = "getmembers";
524 state trampoline; 524 state trampoline;
525 } 525 }
526 on_rez(integer num) { 526 on_rez(integer num) {
527 llResetScript(); 527 llResetScript();
528 } 528 }
529 changed(integer change) { 529 changed(integer change) {
530 if(change & CHANGED_INVENTORY) { 530 if(change & CHANGED_INVENTORY) {
531 llResetScript(); 531 llResetScript();
532 } 532 }
533 } 533 }
534 } 534 }
535   535  
536 state getrolemembers { 536 state getrolemembers {
537 state_entry() { 537 state_entry() {
538 llSetText("☀ Getting role members... ☀", <1, 1, 0>, 1.0); 538 llSetText("☀ Getting role members... ☀", <1, 1, 0>, 1.0);
539 llInstantMessage(CORRADE, 539 llInstantMessage(CORRADE,
540 wasKeyValueEncode( 540 wasKeyValueEncode(
541 [ 541 [
542 "command", "getrolemembers", 542 "command", "getrolemembers",
543 "group", wasURLEscape(GROUP), 543 "group", wasURLEscape(GROUP),
544 "password", wasURLEscape(PASSWORD), 544 "password", wasURLEscape(PASSWORD),
545 "role", wasURLEscape(ROLE), 545 "role", wasURLEscape(ROLE),
546 // we just care if the agent is in the renter role 546 // we just care if the agent is in the renter role
547 // so we use Corrade's sifting ability in order 547 // so we use Corrade's sifting ability in order
548 // to reduce the script memory usage 548 // to reduce the script memory usage
549 "sift", wasURLEscape( 549 "sift", wasURLEscape(
550 "(" + 550 "(" +
551 wasKeyValueGet( 551 wasKeyValueGet(
552 "rentantUUID", 552 "rentantUUID",
553 llGetObjectDesc() 553 llGetObjectDesc()
554 ) + 554 ) +
555 ")*" 555 ")*"
556 ), 556 ),
557 "callback", wasURLEscape(URL) 557 "callback", wasURLEscape(URL)
558 ] 558 ]
559 ) 559 )
560 ); 560 );
561 llSetTimerEvent(60); 561 llSetTimerEvent(60);
562 } 562 }
563 http_request(key id, string method, string body) { 563 http_request(key id, string method, string body) {
564 if(wasKeyValueGet("success", body) != "True") { 564 if(wasKeyValueGet("success", body) != "True") {
565 llSetText("☀ Could not get role members! ☀", <1, 0, 0>, 1.0); 565 llSetText("☀ Could not get role members! ☀", <1, 0, 0>, 1.0);
566 nextstate = "getrolemembers"; 566 nextstate = "getrolemembers";
567 state trampoline; 567 state trampoline;
568 } 568 }
569 // check that the payer is part of the role 569 // check that the payer is part of the role
570 integer i = 570 integer i =
571 llListFindList( 571 llListFindList(
572 wasCSVToList( 572 wasCSVToList(
573 wasURLUnescape( 573 wasURLUnescape(
574 wasKeyValueGet( 574 wasKeyValueGet(
575 "data", 575 "data",
576 body 576 body
577 ) 577 )
578 ) 578 )
579 ), 579 ),
580 (list)wasKeyValueGet( 580 (list)wasKeyValueGet(
581 "rentantUUID", 581 "rentantUUID",
582 llGetObjectDesc() 582 llGetObjectDesc()
583 ) 583 )
584 ); 584 );
585 llSetTimerEvent(0); 585 llSetTimerEvent(0);
586 // if they are in the role then skip inviting them. 586 // if they are in the role then skip inviting them.
587 if(i != -1) state rented; 587 if(i != -1) state rented;
588 // otherwise add them to the land role. 588 // otherwise add them to the land role.
589 state addtorole; 589 state addtorole;
590 } 590 }
591 timer() { 591 timer() {
592 llSetTimerEvent(0); 592 llSetTimerEvent(0);
593 nextstate = "getrolemembers"; 593 nextstate = "getrolemembers";
594 state trampoline; 594 state trampoline;
595 } 595 }
596 on_rez(integer num) { 596 on_rez(integer num) {
597 llResetScript(); 597 llResetScript();
598 } 598 }
599 changed(integer change) { 599 changed(integer change) {
600 if(change & CHANGED_INVENTORY) { 600 if(change & CHANGED_INVENTORY) {
601 llResetScript(); 601 llResetScript();
602 } 602 }
603 } 603 }
604 } 604 }
605   605  
606 state addtorole { 606 state addtorole {
607 state_entry() { 607 state_entry() {
608 llSetText("☀ Adding to role... ☀", <1, 1, 0>, 1.0); 608 llSetText("☀ Adding to role... ☀", <1, 1, 0>, 1.0);
609 llInstantMessage(CORRADE, 609 llInstantMessage(CORRADE,
610 wasKeyValueEncode( 610 wasKeyValueEncode(
611 [ 611 [
612 "command", "addtorole", 612 "command", "addtorole",
613 "group", wasURLEscape(GROUP), 613 "group", wasURLEscape(GROUP),
614 "password", wasURLEscape(PASSWORD), 614 "password", wasURLEscape(PASSWORD),
615 "agent", wasURLEscape( 615 "agent", wasURLEscape(
616 wasKeyValueGet( 616 wasKeyValueGet(
617 "rentantUUID", 617 "rentantUUID",
618 llGetObjectDesc() 618 llGetObjectDesc()
619 ) 619 )
620 ), 620 ),
621 "role", wasURLEscape(ROLE), 621 "role", wasURLEscape(ROLE),
622 "callback", wasURLEscape(URL) 622 "callback", wasURLEscape(URL)
623 ] 623 ]
624 ) 624 )
625 ); 625 );
626 llSetTimerEvent(60); 626 llSetTimerEvent(60);
627 } 627 }
628 http_request(key id, string method, string body) { 628 http_request(key id, string method, string body) {
629 if(wasKeyValueGet("success", body) != "True") { 629 if(wasKeyValueGet("success", body) != "True") {
630 llSetText("☀ Could not add to role! ☀", <1, 0, 0>, 1.0); 630 llSetText("☀ Could not add to role! ☀", <1, 0, 0>, 1.0);
631 nextstate = "addtorole"; 631 nextstate = "addtorole";
632 state trampoline; 632 state trampoline;
633 } 633 }
634 // otherwise invite them to the group role. 634 // otherwise invite them to the group role.
635 state rented; 635 state rented;
636 } 636 }
637 timer() { 637 timer() {
638 llSetTimerEvent(0); 638 llSetTimerEvent(0);
639 nextstate = "addtorole"; 639 nextstate = "addtorole";
640 state trampoline; 640 state trampoline;
641 } 641 }
642 on_rez(integer num) { 642 on_rez(integer num) {
643 llResetScript(); 643 llResetScript();
644 } 644 }
645 changed(integer change) { 645 changed(integer change) {
646 if(change & CHANGED_INVENTORY) { 646 if(change & CHANGED_INVENTORY) {
647 llResetScript(); 647 llResetScript();
648 } 648 }
649 } 649 }
650 } 650 }
651   651  
652 state invite { 652 state invite {
653 state_entry() { 653 state_entry() {
654 llSetText("☀ Please accept the group invite! ☀", <1, 1, 0>, 1.0); 654 llSetText("☀ Please accept the group invite! ☀", <1, 1, 0>, 1.0);
655 // invite the agent to the land group 655 // invite the agent to the land group
656 llInstantMessage(CORRADE, 656 llInstantMessage(CORRADE,
657 wasKeyValueEncode( 657 wasKeyValueEncode(
658 [ 658 [
659 "command", "invite", 659 "command", "invite",
660 "group", wasURLEscape(GROUP), 660 "group", wasURLEscape(GROUP),
661 "password", wasURLEscape(PASSWORD), 661 "password", wasURLEscape(PASSWORD),
662 "agent", wasURLEscape( 662 "agent", wasURLEscape(
663 wasKeyValueGet( 663 wasKeyValueGet(
664 "rentantUUID", 664 "rentantUUID",
665 llGetObjectDesc() 665 llGetObjectDesc()
666 ) 666 )
667 ), 667 ),
668 "role", wasURLEscape(ROLE), 668 "role", wasURLEscape(ROLE),
669 "callback", wasURLEscape(URL) 669 "callback", wasURLEscape(URL)
670 ] 670 ]
671 ) 671 )
672 ); 672 );
673 // handle any Corrade timeouts 673 // handle any Corrade timeouts
674 llSetTimerEvent(60); 674 llSetTimerEvent(60);
675 } 675 }
676 http_request(key id, string method, string body) { 676 http_request(key id, string method, string body) {
677 llHTTPResponse(id, 200, "OK"); 677 llHTTPResponse(id, 200, "OK");
678 // Checks if the invite was sent successfully or if that fails but the 678 // Checks if the invite was sent successfully or if that fails but the
679 // agent is already in the group (status 15345) then continue. 679 // agent is already in the group (status 15345) then continue.
680 // Otherwise, jump to the trampoline and send the invite again. 680 // Otherwise, jump to the trampoline and send the invite again.
681 // Status codes: 681 // Status codes:
682 // http://grimore.org/secondlife/scripted_agents/corrade/status_codes/progressive 682 // http://grimore.org/secondlife/scripted_agents/corrade/status_codes/progressive
683 if(wasKeyValueGet("success", body) != "True" && 683 if(wasKeyValueGet("success", body) != "True" &&
684 wasKeyValueGet("status", body) != "15345") { 684 wasKeyValueGet("status", body) != "15345") {
685 llSetText("☀ Group invite could not be sent! ☀", <1, 0, 0>, 1.0); 685 llSetText("☀ Group invite could not be sent! ☀", <1, 0, 0>, 1.0);
686 nextstate = "invite"; 686 nextstate = "invite";
687 state trampoline; 687 state trampoline;
688 } 688 }
689 llSetText("☀ Group invitation sent! ☀", <1, 1, 0>, 1.0); 689 llSetText("☀ Group invitation sent! ☀", <1, 1, 0>, 1.0);
690 llSetTimerEvent(0); 690 llSetTimerEvent(0);
691 state rented; 691 state rented;
692 } 692 }
693 timer() { 693 timer() {
694 llSetTimerEvent(0); 694 llSetTimerEvent(0);
695 nextstate = "invite"; 695 nextstate = "invite";
696 state trampoline; 696 state trampoline;
697 } 697 }
698 } 698 }
699   699  
700 state rented { 700 state rented {
701 state_entry() { 701 state_entry() {
702 // Get the expiration date 702 // Get the expiration date
703 list expires = llList2List( 703 list expires = llList2List(
704 llParseString2List( 704 llParseString2List(
705 wasKeyValueGet( 705 wasKeyValueGet(
706 "expiresDate", 706 "expiresDate",
707 llGetObjectDesc() 707 llGetObjectDesc()
708 ), 708 ),
709 ["-",":","T", "."],[""] 709 ["-",":","T", "."],[""]
710 ), 710 ),
711 0, 5 711 0, 5
712 ); 712 );
713 // Get the current date 713 // Get the current date
714 list stamp = llList2List( 714 list stamp = llList2List(
715 llParseString2List( 715 llParseString2List(
716 llGetTimestamp(), 716 llGetTimestamp(),
717 ["-",":","T", "."],[""] 717 ["-",":","T", "."],[""]
718 ), 718 ),
719 0, 5 719 0, 5
720 ); 720 );
721 721
722 integer delta = wasDateTimeToStamp( 722 integer delta = wasDateTimeToStamp(
723 llList2Integer(expires, 0), 723 llList2Integer(expires, 0),
724 llList2Integer(expires, 1), 724 llList2Integer(expires, 1),
725 llList2Integer(expires, 2), 725 llList2Integer(expires, 2),
726 llList2Integer(expires, 3), 726 llList2Integer(expires, 3),
727 llList2Integer(expires, 4), 727 llList2Integer(expires, 4),
728 llList2Integer(expires, 5) 728 llList2Integer(expires, 5)
729 ) - wasDateTimeToStamp( 729 ) - wasDateTimeToStamp(
730 llList2Integer(stamp, 0), 730 llList2Integer(stamp, 0),
731 llList2Integer(stamp, 1), 731 llList2Integer(stamp, 1),
732 llList2Integer(stamp, 2), 732 llList2Integer(stamp, 2),
733 llList2Integer(stamp, 3), 733 llList2Integer(stamp, 3),
734 llList2Integer(stamp, 4), 734 llList2Integer(stamp, 4),
735 llList2Integer(stamp, 5) 735 llList2Integer(stamp, 5)
736 ); 736 );
737 737
738 // the rent has expired, now evict the rentant 738 // the rent has expired, now evict the rentant
739 if(delta <= 0) { 739 if(delta <= 0) {
740 llSetTimerEvent(0); 740 llSetTimerEvent(0);
741 nextstate = "demote"; 741 nextstate = "demote";
742 state url; 742 state url;
743 } 743 }
744 744
745 // otherwise, update the remaining time 745 // otherwise, update the remaining time
746 list remaining = wasUnixTimeToDateTime(delta); 746 list remaining = wasUnixTimeToDateTime(delta);
747 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 0)-1970 ], 0, 0); 747 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 0)-1970 ], 0, 0);
748 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 1)-1 ], 1, 1); 748 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 1)-1 ], 1, 1);
749 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 2)-1 ], 2, 2); 749 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 2)-1 ], 2, 2);
750 750
751 llSetText( 751 llSetText(
752 "☀ Private property! ☀" 752 "☀ Private property! ☀"
753 + "\n" + 753 + "\n" +
754 "Rented by: " + 754 "Rented by: " +
755 wasKeyValueGet( 755 wasKeyValueGet(
756 "rentantName", 756 "rentantName",
757 llGetObjectDesc() 757 llGetObjectDesc()
758 ) 758 )
759 + "\n" + 759 + "\n" +
760 "Expires on: " + 760 "Expires on: " +
761 wasKeyValueGet( 761 wasKeyValueGet(
762 "expiresDate", 762 "expiresDate",
763 llGetObjectDesc() 763 llGetObjectDesc()
764 ) 764 )
765 + "\n" + 765 + "\n" +
766 "Remaining: " + 766 "Remaining: " +
767 llList2String(remaining, 0) + "-" + 767 llList2String(remaining, 0) + "-" +
768 llList2String(remaining, 1) + "-" + 768 llList2String(remaining, 1) + "-" +
769 llList2String(remaining, 2) + " " + 769 llList2String(remaining, 2) + " " +
770 llList2String(remaining, 3) + ":" + 770 llList2String(remaining, 3) + ":" +
771 llList2String(remaining, 4) 771 llList2String(remaining, 4)
772 + "\n" + 772 + "\n" +
773 "Touch to extend rent.", 773 "Touch to extend rent.",
774 <0, 1, 1>, 774 <0, 1, 1>,
775 1.0 775 1.0
776 ); 776 );
777 llSetPayPrice(PRICE, [PRICE]); 777 llSetPayPrice(PRICE, [PRICE]);
778 llSetClickAction(CLICK_ACTION_PAY); 778 llSetClickAction(CLICK_ACTION_PAY);
779 // set the countdown every minute 779 // set the countdown every minute
780 llSetTimerEvent(60); 780 llSetTimerEvent(60);
781 } 781 }
782 money(key id, integer amount) { 782 money(key id, integer amount) {
783 // Get the expiration date 783 // Get the expiration date
784 list stamp = llList2List( 784 list stamp = llList2List(
785 llParseString2List( 785 llParseString2List(
786 wasKeyValueGet( 786 wasKeyValueGet(
787 "expiresDate", 787 "expiresDate",
788 llGetObjectDesc() 788 llGetObjectDesc()
789 ), 789 ),
790 ["-",":","T", "."],[""] 790 ["-",":","T", "."],[""]
791 ), 791 ),
792 0, 5 792 0, 5
793 ); 793 );
794 // convert to seconds and add the extended rent 794 // convert to seconds and add the extended rent
795 integer delta = wasDateTimeToStamp( 795 integer delta = wasDateTimeToStamp(
796 llList2Integer(stamp, 0), 796 llList2Integer(stamp, 0),
797 llList2Integer(stamp, 1), 797 llList2Integer(stamp, 1),
798 llList2Integer(stamp, 2), 798 llList2Integer(stamp, 2),
799 llList2Integer(stamp, 3), 799 llList2Integer(stamp, 3),
800 llList2Integer(stamp, 4), 800 llList2Integer(stamp, 4),
801 llList2Integer(stamp, 5) 801 llList2Integer(stamp, 5)
802 ) + 802 ) +
803 // the amount of time to extend is the amount 803 // the amount of time to extend is the amount
804 // paid times the rent time divided by the price 804 // paid times the rent time divided by the price
805 amount * (integer)( 805 amount * (integer)(
806 (float)RENT / 806 (float)RENT /
807 (float)PRICE 807 (float)PRICE
808 ); 808 );
809 // convert back to a timestamp 809 // convert back to a timestamp
810 stamp = wasUnixTimeToDateTime(delta); 810 stamp = wasUnixTimeToDateTime(delta);
811 // and set the renter and the eviction date 811 // and set the renter and the eviction date
812 llSetObjectDesc( 812 llSetObjectDesc(
813 wasKeyValueEncode( 813 wasKeyValueEncode(
814 [ 814 [
815 "rentantUUID", wasKeyValueGet( 815 "rentantUUID", wasKeyValueGet(
816 "rentantUUID", 816 "rentantUUID",
817 llGetObjectDesc() 817 llGetObjectDesc()
818 ), 818 ),
819 "rentantName", wasKeyValueGet( 819 "rentantName", wasKeyValueGet(
820 "rentantName", 820 "rentantName",
821 llGetObjectDesc() 821 llGetObjectDesc()
822 ), 822 ),
823 "expiresDate", llList2String(stamp, 0) + 823 "expiresDate", llList2String(stamp, 0) +
824 "-" + llList2String(stamp, 1) + 824 "-" + llList2String(stamp, 1) +
825 "-" + llList2String(stamp, 2) + 825 "-" + llList2String(stamp, 2) +
826 "T" + llList2String(stamp, 3) + 826 "T" + llList2String(stamp, 3) +
827 ":" + llList2String(stamp, 4) + 827 ":" + llList2String(stamp, 4) +
828 ":" + llList2String(stamp, 5) 828 ":" + llList2String(stamp, 5)
829 ] 829 ]
830 ) 830 )
831 ); 831 );
832 llSetText("☀ Updating... ☀", <1, 1, 0>, 1.0); 832 llSetText("☀ Updating... ☀", <1, 1, 0>, 1.0);
833 llSetTimerEvent(0); 833 llSetTimerEvent(0);
834 nextstate = "rented"; 834 nextstate = "rented";
835 state trampoline; 835 state trampoline;
836 } 836 }
837 timer() { 837 timer() {
838 // Get the expiration date 838 // Get the expiration date
839 list expires = llList2List( 839 list expires = llList2List(
840 llParseString2List( 840 llParseString2List(
841 wasKeyValueGet( 841 wasKeyValueGet(
842 "expiresDate", 842 "expiresDate",
843 llGetObjectDesc() 843 llGetObjectDesc()
844 ), 844 ),
845 ["-",":","T", "."],[""] 845 ["-",":","T", "."],[""]
846 ), 846 ),
847 0, 5 847 0, 5
848 ); 848 );
849 // Get the current date 849 // Get the current date
850 list stamp = llList2List( 850 list stamp = llList2List(
851 llParseString2List( 851 llParseString2List(
852 llGetTimestamp(), 852 llGetTimestamp(),
853 ["-",":","T", "."],[""] 853 ["-",":","T", "."],[""]
854 ), 854 ),
855 0, 5 855 0, 5
856 ); 856 );
857 857
858 integer delta = wasDateTimeToStamp( 858 integer delta = wasDateTimeToStamp(
859 llList2Integer(expires, 0), 859 llList2Integer(expires, 0),
860 llList2Integer(expires, 1), 860 llList2Integer(expires, 1),
861 llList2Integer(expires, 2), 861 llList2Integer(expires, 2),
862 llList2Integer(expires, 3), 862 llList2Integer(expires, 3),
863 llList2Integer(expires, 4), 863 llList2Integer(expires, 4),
864 llList2Integer(expires, 5) 864 llList2Integer(expires, 5)
865 ) - wasDateTimeToStamp( 865 ) - wasDateTimeToStamp(
866 llList2Integer(stamp, 0), 866 llList2Integer(stamp, 0),
867 llList2Integer(stamp, 1), 867 llList2Integer(stamp, 1),
868 llList2Integer(stamp, 2), 868 llList2Integer(stamp, 2),
869 llList2Integer(stamp, 3), 869 llList2Integer(stamp, 3),
870 llList2Integer(stamp, 4), 870 llList2Integer(stamp, 4),
871 llList2Integer(stamp, 5) 871 llList2Integer(stamp, 5)
872 ); 872 );
873 873
874 // the rent has expired, now evict the rentant 874 // the rent has expired, now evict the rentant
875 if(delta <= 0) { 875 if(delta <= 0) {
876 llSetTimerEvent(0); 876 llSetTimerEvent(0);
877 nextstate = "demote"; 877 nextstate = "demote";
878 state url; 878 state url;
879 } 879 }
880 880
881 // otherwise, update the remaining time 881 // otherwise, update the remaining time
882 list remaining = wasUnixTimeToDateTime(delta); 882 list remaining = wasUnixTimeToDateTime(delta);
883 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 0)-1970 ], 0, 0); 883 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 0)-1970 ], 0, 0);
884 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 1)-1 ], 1, 1); 884 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 1)-1 ], 1, 1);
885 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 2)-1 ], 2, 2); 885 remaining = llListReplaceList(remaining, [ llList2Integer(remaining, 2)-1 ], 2, 2);
886 886
887 llSetText( 887 llSetText(
888 "☀ Private property! ☀" 888 "☀ Private property! ☀"
889 + "\n" + 889 + "\n" +
890 "Rented by: " + 890 "Rented by: " +
891 wasKeyValueGet( 891 wasKeyValueGet(
892 "rentantName", 892 "rentantName",
893 llGetObjectDesc() 893 llGetObjectDesc()
894 ) 894 )
895 + "\n" + 895 + "\n" +
896 "Expires on: " + 896 "Expires on: " +
897 wasKeyValueGet( 897 wasKeyValueGet(
898 "expiresDate", 898 "expiresDate",
899 llGetObjectDesc() 899 llGetObjectDesc()
900 ) 900 )
901 + "\n" + 901 + "\n" +
902 "Remaining: " + 902 "Remaining: " +
903 llList2String(remaining, 0) + "-" + 903 llList2String(remaining, 0) + "-" +
904 llList2String(remaining, 1) + "-" + 904 llList2String(remaining, 1) + "-" +
905 llList2String(remaining, 2) + " " + 905 llList2String(remaining, 2) + " " +
906 llList2String(remaining, 3) + ":" + 906 llList2String(remaining, 3) + ":" +
907 llList2String(remaining, 4) 907 llList2String(remaining, 4)
908 + "\n" + 908 + "\n" +
909 "Touch to extend rent.", 909 "Touch to extend rent.",
910 <0, 1, 1>, 910 <0, 1, 1>,
911 1.0 911 1.0
912 ); 912 );
913 913
914 } 914 }
915 on_rez(integer num) { 915 on_rez(integer num) {
916 llResetScript(); 916 llResetScript();
917 } 917 }
918 changed(integer change) { 918 changed(integer change) {
919 if(change & CHANGED_INVENTORY) { 919 if(change & CHANGED_INVENTORY) {
920 llResetScript(); 920 llResetScript();
921 } 921 }
922 } 922 }
923 } 923 }
924   924  
925 state demote { 925 state demote {
926 state_entry() { 926 state_entry() {
927 llSetText("☀ Rent has expired! ☀", <1, 0, 0>, 1.0); 927 llSetText("☀ Rent has expired! ☀", <1, 0, 0>, 1.0);
928 // demote the agent from the renter role 928 // demote the agent from the renter role
929 llInstantMessage(CORRADE, 929 llInstantMessage(CORRADE,
930 wasKeyValueEncode( 930 wasKeyValueEncode(
931 [ 931 [
932 "command", "deletefromrole", 932 "command", "deletefromrole",
933 "group", wasURLEscape(GROUP), 933 "group", wasURLEscape(GROUP),
934 "password", wasURLEscape(PASSWORD), 934 "password", wasURLEscape(PASSWORD),
935 "agent", wasURLEscape( 935 "agent", wasURLEscape(
936 wasKeyValueGet( 936 wasKeyValueGet(
937 "rentantUUID", 937 "rentantUUID",
938 llGetObjectDesc() 938 llGetObjectDesc()
939 ) 939 )
940 ), 940 ),
941 "role", wasURLEscape(ROLE), 941 "role", wasURLEscape(ROLE),
942 "callback", wasURLEscape(URL) 942 "callback", wasURLEscape(URL)
943 ] 943 ]
944 ) 944 )
945 ); 945 );
946 // handle any Corrade timeouts 946 // handle any Corrade timeouts
947 llSetTimerEvent(60); 947 llSetTimerEvent(60);
948 } 948 }
949 http_request(key id, string method, string body) { 949 http_request(key id, string method, string body) {
950 llHTTPResponse(id, 200, "OK"); 950 llHTTPResponse(id, 200, "OK");
951 // Checks if the demote was sent successfully or if that fails but the 951 // Checks if the demote was sent successfully or if that fails but the
952 // agent has already left the group (status 11502) then continue. 952 // agent has already left the group (status 11502) then continue.
953 // Otherwise, jump to the trampoline and send the demote again. 953 // Otherwise, jump to the trampoline and send the demote again.
954 // Status codes: 954 // Status codes:
955 // http://grimore.org/secondlife/scripted_agents/corrade/status_codes/progressive 955 // http://grimore.org/secondlife/scripted_agents/corrade/status_codes/progressive
956 if(wasKeyValueGet("success", body) != "True" && 956 if(wasKeyValueGet("success", body) != "True" &&
957 wasKeyValueGet("status", body) != "11502") { 957 wasKeyValueGet("status", body) != "11502") {
958 llSetText("☀ Could not demote! ☀", <1, 0, 0>, 1.0); 958 llSetText("☀ Could not demote! ☀", <1, 0, 0>, 1.0);
959 nextstate = "demote"; 959 nextstate = "demote";
960 state trampoline; 960 state trampoline;
961 } 961 }
962 llSetText("☀ Renter demoted! ☀", <1, 1, 0>, 1.0); 962 llSetText("☀ Renter demoted! ☀", <1, 1, 0>, 1.0);
963 llSetTimerEvent(0); 963 llSetTimerEvent(0);
964 964
965 // Now clean up the rental and restart. 965 // Now clean up the rental and restart.
966 llSetObjectDesc(""); 966 llSetObjectDesc("");
967 llResetScript(); 967 llResetScript();
968 } 968 }
969 timer() { 969 timer() {
970 llSetTimerEvent(0); 970 llSetTimerEvent(0);
971 nextstate = "demote"; 971 nextstate = "demote";
972 state trampoline; 972 state trampoline;
973 } 973 }
974 } 974 }
975   975  
976   976