corrade-lsl-templates – Blame information for rev 29
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | /////////////////////////////////////////////////////////////////////////// |
29 | office | 2 | // Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 // |
3 | // Please see: https://creativecommons.org/licenses/by/2.0 for legal details, // |
||
4 | office | 4 | // rights of fair usage, the disclaimer and warranty conditions. // |
5 | /////////////////////////////////////////////////////////////////////////// |
||
6 | |||
7 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 8 | // Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 9 | /////////////////////////////////////////////////////////////////////////// |
10 | list wasListReverse(list lst) { |
||
11 | if(llGetListLength(lst)<=1) return lst; |
||
12 | return wasListReverse( |
||
13 | llList2List(lst, 1, llGetListLength(lst)) |
||
14 | ) + llList2List(lst,0,0); |
||
15 | } |
||
16 | |||
17 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 18 | // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 19 | /////////////////////////////////////////////////////////////////////////// |
20 | string wasDayOfWeek(integer year, integer month, integer day) { |
||
21 | return llList2String( |
||
22 | [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", |
||
23 | "Saturday", "Sunday" ], |
||
24 | ( |
||
25 | day |
||
26 | + ((153 * (month + 12 * ((14 - month) / 12) - 3) + 2) / 5) |
||
27 | + (365 * (year + 4800 - ((14 - month) / 12))) |
||
28 | + ((year + 4800 - ((14 - month) / 12)) / 4) |
||
29 | - ((year + 4800 - ((14 - month) / 12)) / 100) |
||
30 | + ((year + 4800 - ((14 - month) / 12)) / 400) |
||
31 | - 32045 |
||
32 | ) % 7 |
||
33 | ); |
||
34 | } |
||
35 | |||
36 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 37 | // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 38 | /////////////////////////////////////////////////////////////////////////// |
39 | integer wasGetYearDays(integer year) { |
||
40 | integer leap = (year % 4 == 0 && year % 100 != 0) || |
||
41 | (year % 400 == 0); |
||
42 | if(leap == TRUE) { |
||
43 | return 366; |
||
44 | } |
||
45 | return 365; |
||
46 | } |
||
47 | |||
48 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 49 | // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 50 | /////////////////////////////////////////////////////////////////////////// |
51 | integer wasGetMonthDays(integer month, integer year) { |
||
52 | if (month == 4 || month == 6 || month == 9 || month == 11) { |
||
53 | return 30; |
||
54 | } |
||
55 | if(month == 2) { |
||
56 | integer leap = (year % 4 == 0 && year % 100 != 0) || |
||
57 | (year % 400 == 0); |
||
58 | if(leap == TRUE) { |
||
59 | return 29; |
||
60 | } |
||
61 | return 28; |
||
62 | } |
||
63 | return 31; |
||
64 | } |
||
65 | |||
66 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 67 | // Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 68 | /////////////////////////////////////////////////////////////////////////// |
69 | string wasUnixTimeToStamp(integer unix) { |
||
70 | integer year = 1970; |
||
71 | integer dayno = unix / 86400; |
||
72 | do { |
||
73 | dayno -= wasGetYearDays(year); |
||
74 | ++year; |
||
75 | } while (dayno >= wasGetYearDays(year)); |
||
76 | integer month = 1; |
||
77 | do { |
||
78 | dayno -= wasGetMonthDays(month, year); |
||
79 | ++month; |
||
80 | } while (dayno >= wasGetMonthDays(month, year)); |
||
81 | return (string)year + "-" + |
||
82 | (string)month + "-" + |
||
83 | (string)(dayno + 1) + "T" + |
||
84 | (string)((unix % 86400) / 3600) + ":" + |
||
85 | (string)(((unix % 86400) % 3600) / 60) + ":" + |
||
86 | (string)(unix % 60) + ".0Z"; |
||
87 | } |
||
88 | |||
89 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 90 | // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 91 | /////////////////////////////////////////////////////////////////////////// |
92 | integer wasMenuIndex = 0; |
||
93 | list wasDialogMenu(list input, list actions, string direction) { |
||
94 | integer cut = 11-wasListCountExclude(actions, [""]); |
||
95 | if(direction == ">" && (wasMenuIndex+1)*cut+wasMenuIndex+1 < llGetListLength(input)) { |
||
96 | ++wasMenuIndex; |
||
97 | jump slice; |
||
98 | } |
||
99 | if(direction == "<" && wasMenuIndex-1 >= 0) { |
||
100 | --wasMenuIndex; |
||
101 | jump slice; |
||
102 | } |
||
103 | @slice; |
||
104 | integer multiple = wasMenuIndex*cut; |
||
105 | input = llList2List(input, multiple+wasMenuIndex, multiple+cut+wasMenuIndex); |
||
106 | input = wasListMerge(input, actions, ""); |
||
107 | return input; |
||
108 | } |
||
109 | |||
110 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 111 | // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 112 | /////////////////////////////////////////////////////////////////////////// |
113 | integer wasListCountExclude(list input, list exclude) { |
||
114 | if(llGetListLength(input) == 0) return 0; |
||
115 | if(llListFindList(exclude, (list)llList2String(input, 0)) == -1) |
||
116 | return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); |
||
117 | return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); |
||
118 | } |
||
119 | |||
120 | /////////////////////////////////////////////////////////////////////////// |
||
29 | office | 121 | // Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
4 | office | 122 | /////////////////////////////////////////////////////////////////////////// |
123 | list wasListMerge(list l, list m, string merge) { |
||
124 | if(llGetListLength(l) == 0 && llGetListLength(m) == 0) return []; |
||
125 | string a = llList2String(m, 0); |
||
126 | if(a != merge) return [ a ] + |
||
127 | wasListMerge(l, llDeleteSubList(m, 0, 0), merge); |
||
128 | return [ llList2String(l, 0) ] + |
||
129 | wasListMerge( |
||
130 | llDeleteSubList(l, 0, 0), |
||
131 | llDeleteSubList(m, 0, 0), |
||
132 | merge |
||
133 | ); |
||
134 | } |
||
135 | |||
136 | // for notecard reading |
||
137 | integer line = 0; |
||
138 | // time to execute |
||
139 | list time = []; |
||
140 | // message to send |
||
141 | list exec = []; |
||
142 | // subject to send |
||
143 | list subj = []; |
||
144 | // item to send |
||
145 | list item = []; |
||
146 | // inventory notecards |
||
147 | list notes = []; |
||
148 | // current notecard |
||
149 | string note = ""; |
||
150 | key agent = NULL_KEY; |
||
151 | // minute store |
||
152 | integer minute = -1; |
||
153 | |||
154 | default { |
||
155 | state_entry() { |
||
156 | // get all the inventory notecards |
||
157 | integer i = llGetInventoryNumber(INVENTORY_NOTECARD)-1; |
||
158 | if(i == -1) { |
||
159 | llSay(0, "No notecards found, idling..."); |
||
160 | return; |
||
161 | } |
||
162 | do { |
||
163 | notes += llGetInventoryName(INVENTORY_NOTECARD, i); |
||
164 | } while(--i>-1); |
||
165 | note = llList2String(notes, 0); |
||
166 | notes = llDeleteSubList(notes, 0, 0); |
||
167 | line = 0; |
||
168 | llSay(0, "Reading notecard: " + note); |
||
169 | llGetNotecardLine(note, line); |
||
170 | } |
||
171 | dataserver(key id, string data) { |
||
172 | if(data == EOF) { |
||
173 | // if we have read all the notecards, |
||
174 | // start processing |
||
175 | if(llGetListLength(notes) == 0) { |
||
176 | // check if the crons are set-up properly or bail |
||
177 | if(llGetListLength(time) == 0 || |
||
178 | llGetListLength(exec) == 0 || |
||
179 | llGetListLength(time) != llGetListLength(exec)) { |
||
180 | llSay(0, "No valid schedules found..."); |
||
181 | return; |
||
182 | } |
||
183 | llSay(0, "All notecards have been read..."); |
||
184 | state cron; |
||
185 | } |
||
186 | // otherwise permute |
||
187 | note = llList2String(notes, 0); |
||
188 | notes = llDeleteSubList(notes, 0, 0); |
||
189 | line = 0; |
||
190 | llSay(0, "Reading notecard: " + note); |
||
191 | llGetNotecardLine(note, line); |
||
192 | return; |
||
193 | } |
||
194 | if(data == "") jump continue; |
||
195 | integer i = llSubStringIndex(data, "#"); |
||
196 | if(i != -1) data = llDeleteSubString(data, i, -1); |
||
197 | if(data == "") jump continue; |
||
198 | list data = llParseString2List(data, [" "], []); |
||
199 | // * * * * * message to send to the link-set |
||
200 | // sanity check a little |
||
201 | if(llGetListLength(data) < 6 || |
||
202 | (llList2String(data, 2) != "*" && llList2Integer(data, 2) == 0) || |
||
203 | (llList2String(data, 3) != "*" && llList2Integer(data, 3) == 0)) jump continue; |
||
204 | list t = llList2List(data, 0, 4); |
||
205 | // normalize 0x |
||
206 | i = llGetListLength(t)-1; |
||
207 | do { |
||
208 | if(llList2String(t, i) == "*") jump wildcard; |
||
209 | t = llListReplaceList(t, [ llList2Integer(t, i) ], i, i); |
||
210 | @wildcard; |
||
211 | } while(--i>-1); |
||
212 | time += llDumpList2String(t, " "); |
||
213 | list ms = llParseString2List(llDumpList2String(llList2List(data, 5, -1), " "), ["|"], []); |
||
214 | // check if subject and message are present |
||
215 | if(llGetListLength(ms) > 0) { |
||
216 | subj += llList2String(ms, 0); |
||
217 | jump message; |
||
218 | } |
||
219 | subj += ""; |
||
220 | @message; |
||
221 | if(llGetListLength(ms) > 1) { |
||
222 | exec += llList2String(ms, 1); |
||
223 | jump attachment; |
||
224 | } |
||
225 | exec += ""; |
||
226 | @attachment; |
||
227 | if(llGetListLength(ms) >= 2) { |
||
228 | item += llList2String(ms, 2); |
||
229 | jump continue; |
||
230 | } |
||
231 | item += ""; |
||
232 | @continue; |
||
233 | llGetNotecardLine(note, ++line); |
||
234 | } |
||
235 | changed(integer change) { |
||
236 | if(change & CHANGED_INVENTORY) llResetScript(); |
||
237 | } |
||
238 | on_rez(integer num) { |
||
239 | llResetScript(); |
||
240 | } |
||
241 | } |
||
242 | |||
243 | /////////////////////////////////////////////////////////////////////////// |
||
244 | // [WaS-K] Cron @ http://was.fm/secondlife/cron // |
||
245 | /////////////////////////////////////////////////////////////////////////// |
||
246 | state cron { |
||
247 | state_entry() { |
||
248 | // cron runs every minute so we bind the event handler |
||
249 | // to the second in order to be precisely on the minute |
||
250 | llSetTimerEvent(1); |
||
251 | llSay(0, "Scheduler activated..."); |
||
252 | } |
||
253 | touch_start(integer num) { |
||
254 | /////////////////////////////////////////////////////////////////////////// ENABLE ME |
||
255 | // not part of the same group, so bail |
||
256 | //if(llDetectedGroup(0) == FALSE) return; |
||
257 | integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6)); |
||
258 | llListen(comChannel, "", "", ""); |
||
259 | llDialog(llDetectedKey(0), "\n Welcome to the Scheduler.\nCreated in 2014 by Wizardry and Steamworks\n 10 September 2014: Version: 1.0\n\n", ["⌚ Show", "⎙ Remove"], comChannel); |
||
260 | } |
||
261 | listen(integer channel, string name, key toucher, string message) { |
||
262 | if(message == "⌚ Show") { |
||
263 | llInstantMessage(toucher, "-----------------------------------------"); |
||
264 | integer i = llGetListLength(time)-1; |
||
265 | do { |
||
266 | llInstantMessage(toucher, llList2String(time, i) + " ▶︎ " + llList2String(exec, i)); |
||
267 | } while(--i>-1); |
||
268 | llInstantMessage(toucher, "-----------------------------------------"); |
||
269 | return; |
||
270 | } |
||
271 | if(message == "⎙ Remove") { |
||
272 | llSetTimerEvent(0); |
||
273 | agent = toucher; |
||
274 | state remove; |
||
275 | } |
||
276 | } |
||
277 | timer() { |
||
278 | // build the current date |
||
279 | list stamp = llParseString2List( |
||
280 | wasUnixTimeToStamp(llGetUnixTime() - ((integer) llGetGMTclock() - (integer) llGetWallclock())), |
||
281 | ["-",":","T"],[""] |
||
282 | ); |
||
283 | |||
284 | // only once per minute |
||
285 | if(llList2Integer(stamp, 4) == minute) return; |
||
286 | |||
287 | list ymd = llList2List(stamp, 0, 2); |
||
288 | integer weekDay = llListFindList( |
||
289 | // convert to cron syntax where Sunday counts as day 0 or 7 |
||
290 | [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], |
||
291 | [ |
||
292 | wasDayOfWeek( |
||
293 | llList2Integer(ymd, 0), |
||
294 | llList2Integer(ymd, 1), |
||
295 | llList2Integer(ymd, 2) |
||
296 | ) |
||
297 | ] |
||
298 | ); |
||
299 | |||
300 | // minute, hour, day, month, day of week |
||
301 | list date = wasListReverse(llList2List(stamp, 1, -2)) + weekDay; |
||
302 | integer i = llGetListLength(date)-1; |
||
303 | // normalize 0x |
||
304 | do { |
||
305 | date = llListReplaceList(date, [ llList2Integer(date, i) ], i, i); |
||
306 | } while(--i>-1); |
||
307 | |||
308 | // check if it is time |
||
309 | list times = time; |
||
310 | list execs = exec; |
||
311 | list subjs = subj; |
||
312 | list items = item; |
||
313 | do { |
||
314 | list cron = llParseString2List(llList2String(times, 0), [" "], []); |
||
315 | do { |
||
316 | // crontab syntax counts Sunday as day 0 or 7 |
||
317 | // so we add an exception on the week day element |
||
318 | if(llGetListLength(times) == 1 && |
||
319 | llList2Integer(date, 0) == 0 && |
||
320 | llList2Integer(cron, 0) != 0 && |
||
321 | llList2Integer(cron, 7) != 7) { |
||
322 | jump continue; |
||
323 | } |
||
324 | if(llList2String(date, 0) != llList2String(cron, 0) && llList2String(cron, 0) != "*") { |
||
325 | jump continue; |
||
326 | } |
||
327 | date = llDeleteSubList(date, 0, 0); |
||
328 | cron = llDeleteSubList(cron, 0, 0); |
||
329 | } while(llGetListLength(cron)); |
||
330 | // Send the notice information. |
||
331 | llMessageLinked( |
||
332 | LINK_SET, |
||
333 | 0, |
||
334 | llList2CSV( |
||
335 | [ |
||
336 | llList2String(subjs, 0), |
||
337 | llList2String(execs, 0), |
||
338 | llList2String(items, 0) |
||
339 | ] |
||
340 | ), |
||
341 | NULL_KEY |
||
342 | ); |
||
343 | @continue; |
||
344 | times = llDeleteSubList(times, 0, 0); |
||
345 | execs = llDeleteSubList(execs, 0, 0); |
||
346 | subjs = llDeleteSubList(subjs, 0, 0); |
||
347 | items = llDeleteSubList(items, 0, 0); |
||
348 | } while(llGetListLength(times)); |
||
349 | |||
350 | // only once per minute |
||
351 | minute = llList2Integer(stamp, 4); |
||
352 | } |
||
353 | changed(integer change) { |
||
354 | if(change & CHANGED_INVENTORY) llResetScript(); |
||
355 | } |
||
356 | on_rez(integer num) { |
||
357 | llResetScript(); |
||
358 | } |
||
359 | } |
||
360 | |||
361 | /////////////////////////////////////////////////////////////////////////// |
||
362 | // Remove Notecard // |
||
363 | /////////////////////////////////////////////////////////////////////////// |
||
364 | state remove { |
||
365 | state_entry() { |
||
366 | // get all the inventory notecards |
||
367 | integer i = llGetInventoryNumber(INVENTORY_NOTECARD)-1; |
||
368 | do { |
||
369 | notes += llGetSubString(llGetInventoryName(INVENTORY_NOTECARD, i), 0, 8); |
||
370 | } while(--i>-1); |
||
371 | integer channel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6)); |
||
372 | llListen(channel, "", "", ""); |
||
373 | llDialog(agent, "\n Welcome to the Scheduler.\nCreated in 2014 by Wizardry and Steamworks\n 10 September 2014: Version: 1.0\n\n", wasDialogMenu(notes, ["⟵ Back", "⏏ Exit", "Next ⟶"], ""), channel); |
||
374 | llSetTimerEvent(60); |
||
375 | } |
||
376 | listen(integer channel, string name, key id, string message) { |
||
377 | if(message == "⟵ Back") { |
||
378 | llSetTimerEvent(60); |
||
379 | llDialog(id, "\n Welcome to the Scheduler.\nCreated in 2014 by Wizardry and Steamworks\n 10 September 2014: Version: 1.0\n\n", wasDialogMenu(notes, ["⟵ Back", "⏏ Exit", "Next ⟶"], "<"), -10); |
||
380 | return; |
||
381 | } |
||
382 | if(message == "Next ⟶") { |
||
383 | llSetTimerEvent(60); |
||
384 | llDialog(id, "\n Welcome to the Scheduler.\nCreated in 2014 by Wizardry and Steamworks\n 10 September 2014: Version: 1.0\n\n", wasDialogMenu(notes, ["⟵ Back", "⏏ Exit", "Next ⟶"], ">"), -10); |
||
385 | return; |
||
386 | } |
||
387 | if(message == "⏏ Exit") { |
||
388 | llInstantMessage(id, "Resuming operations..."); |
||
389 | llResetScript(); |
||
390 | } |
||
391 | integer i = llGetInventoryNumber(INVENTORY_NOTECARD)-1; |
||
392 | do { |
||
393 | string name = llGetInventoryName(INVENTORY_NOTECARD, i); |
||
394 | if(llSubStringIndex(name, message) == -1) jump continue_inventory; |
||
395 | llInstantMessage(id, "Deleting notecard: " + message); |
||
396 | llRemoveInventory(name); |
||
397 | integer j = llGetListLength(notes)-1; |
||
398 | do { |
||
399 | note = llList2String(notes, j); |
||
400 | if(llSubStringIndex(name, note) == -1) jump continue_notes; |
||
401 | notes = llDeleteSubList(notes, j, j); |
||
402 | jump menu; |
||
403 | @continue_notes; |
||
404 | } while(--j>-1); |
||
405 | @continue_inventory; |
||
406 | } while(--i>-1); |
||
407 | @menu; |
||
408 | llSetTimerEvent(60); |
||
409 | llDialog(id, "\n Welcome to the Scheduler.\nCreated in 2014 by Wizardry and Steamworks\n 10 September 2014: Version: 1.0\n\n", wasDialogMenu(notes, ["⟵ Back", "⏏ Exit", "Next ⟶"], ""), channel); |
||
410 | } |
||
411 | timer() { |
||
412 | llInstantMessage(agent, "Dialog expired, resuming operations..."); |
||
413 | llResetScript(); |
||
414 | } |
||
415 | changed(integer change) { |
||
416 | if(change & CHANGED_INVENTORY) llResetScript(); |
||
417 | } |
||
418 | on_rez(integer num) { |
||
419 | llResetScript(); |
||
420 | } |
||
421 | } |