4e6eb8317b759672152c9579fb0be82ad6911a63
[feisty_meow.git] / huffware / huffotronic_scripts / zenmondos_mailbox_v0.4.txt
1 
2 // huffware script: zen mondo's mailbox, modified by fred huffhines.
3 //
4 // original attributions are below.
5 //
6 // my changes are licensed via:
7 //   this script is licensed by the GPL v3 which is documented at: http://www.gnu.org/licenses/gpl.html
8 //   do not use it in objects without fully realizing you are implicitly accepting that license.
9 //
10
11 //////////////////////////////////////
12 // ZenMondo's Mailbox by ZenMondo Wormser
13 //
14 // Displays Online Status, as well as accepting
15 // notecard "mail" to be be delivered to owner.
16 //
17 // Cleans Up after itself, deletes non-notecards.
18 //
19 //
20 // LICENSE:
21 //
22 //  This script is given for free, and may NOT be 
23 //  resold or used in a commercial product.
24 //  You may copy and distribute this script for free.
25 //  When you redistribute or copy this script, you must
26 //  do so with FULL PERMS (modify, copy, and transfer),
27 //  and leave this notice intact.
28 //
29 //  You are free to modify this code, but any derivitive
30 //  scripts must not be used in a commercial product or
31 //  or sold, and must contain this license.  
32 //
33 //  This script is provided free for learning 
34 //  purposes, take it apart, break it, fix it, 
35 //  learn something.  If you come up with something 
36 //  clever, share it.
37 //
38 //  Questions about codepoetry (scripting) can always be addressed
39 //  to me, ZenMondo Wormser.
40 //
41 ///////////////////////////////////////// 
42
43 key online_query;
44
45 key name_query;
46
47 string user_name;
48
49
50 //////////////
51 // huffware script: auto-retire, by fred huffhines, version 2.5.
52 // distributed under BSD-like license.
53 //   !!  keep in mind that this code must be *copied* into another
54 //   !!  script that you wish to add auto-retirement capability to.
55 // when a script has auto_retire in it, it can be dropped into an
56 // object and the most recent version of the script will destroy
57 // all older versions.
58 //
59 // the version numbers are embedded into the script names themselves.
60 // the notation for versions uses a letter 'v', followed by two numbers
61 // in the form "major.minor".
62 // major and minor versions are implicitly considered as a floating point
63 // number that increases with each newer version of the script.  thus,
64 // "hazmap v0.1" might be the first script in the "hazmap" script continuum,
65 // and "hazmap v3.2" is a more recent version.
66 //
67 // example usage of the auto-retirement script:
68 //     default {
69 //         state_entry() {
70 //            auto_retire();  // make sure newest addition is only version of script.
71 //        }
72 //     }
73 // this script is partly based on the self-upgrading scripts from markov brodsky
74 // and jippen faddoul.
75 //////////////
76 auto_retire() {
77     string self = llGetScriptName();  // the name of this script.
78     list split = compute_basename_and_version(self);
79     if (llGetListLength(split) != 2) return;  // nothing to do for this script.
80     string basename = llList2String(split, 0);  // script name with no version attached.
81     string version_string = llList2String(split, 1);  // the version found.
82     integer posn;
83     // find any scripts that match the basename.  they are variants of this script.
84     for (posn = llGetInventoryNumber(INVENTORY_SCRIPT) - 1; posn >= 0; posn--) {
85         string curr_script = llGetInventoryName(INVENTORY_SCRIPT, posn);
86         if ( (curr_script != self) && (llSubStringIndex(curr_script, basename) == 0) ) {
87             // found a basic match at least.
88             list inv_split = compute_basename_and_version(curr_script);
89             if (llGetListLength(inv_split) == 2) {
90                 // see if this script is more ancient.
91                 string inv_version_string = llList2String(inv_split, 1);  // the version found.
92                 // must make sure that the retiring script is completely the identical basename;
93                 // just matching in the front doesn't make it a relative.
94                 if ( (llList2String(inv_split, 0) == basename)
95                     && ((float)inv_version_string < (float)version_string) ) {
96                     // remove script with same name from inventory that has inferior version.
97                     llRemoveInventory(curr_script);
98                 }
99             }
100         }
101     }
102 }
103 //
104 // separates the base script name and version number.  used by auto_retire.
105 list compute_basename_and_version(string to_chop_up)
106 {
107     // minimum script name is 2 characters plus a version.
108     integer space_v_posn;
109     // find the last useful space and 'v' combo.
110     for (space_v_posn = llStringLength(to_chop_up) - 3;
111         (space_v_posn >= 2) && (llGetSubString(to_chop_up, space_v_posn, space_v_posn + 1) != " v");
112         space_v_posn--) {
113         // look for space and v but do nothing else.
114     }
115     if (space_v_posn < 2) return [];  // no space found.
116     // now we zoom through the stuff after our beloved v character and find any evil
117     // space characters, which are most likely from SL having found a duplicate item
118     // name and not so helpfully renamed it for us.
119     integer indy;
120     for (indy = llStringLength(to_chop_up) - 1; indy > space_v_posn; indy--) {
121         if (llGetSubString(to_chop_up, indy, indy) == " ") {
122             // found one; zap it.  since we're going backwards we don't need to
123             // adjust the loop at all.
124             to_chop_up = llDeleteSubString(to_chop_up, indy, indy);
125         }
126     }
127     string full_suffix = llGetSubString(to_chop_up, space_v_posn, -1);
128     // ditch the space character for our numerical check.
129     string chop_suffix = llGetSubString(full_suffix, 1, llStringLength(full_suffix) - 1);
130     // strip out a 'v' if there is one.
131     if (llGetSubString(chop_suffix, 0, 0) == "v")
132         chop_suffix = llGetSubString(chop_suffix, 1, llStringLength(chop_suffix) - 1);
133     // if valid floating point number and greater than zero, that works for our version.
134     string basename = to_chop_up;  // script name with no version attached.
135     if ((float)chop_suffix > 0.0) {
136         // this is a big success right here.
137         basename = llGetSubString(to_chop_up, 0, -llStringLength(full_suffix) - 1);
138         return [ basename, chop_suffix ];
139     }
140     // seems like we found nothing useful.
141     return [];
142 }
143 //
144 //////////////
145
146
147 default {
148     state_entry() { if (llSubStringIndex(llGetObjectName(), "huffotronic") < 0) state real_default; }
149     on_rez(integer parm) { state rerun; }
150 }
151 state rerun { state_entry() { state default; } }
152
153 state real_default
154 {
155     state_entry()
156     {
157         auto_retire();
158         llAllowInventoryDrop(TRUE);
159         name_query = llRequestAgentData(llGetOwner(), DATA_NAME);
160         llSetText("Setting Up, Ready in one minute.", <0,1,1>, 1.0);
161         llSetTimerEvent(60);
162         
163         
164     }
165
166     timer()
167     {
168         online_query = llRequestAgentData(llGetOwner(),DATA_ONLINE);          
169     }
170     
171     dataserver(key queryid, string data)
172     {
173         
174         if(queryid == name_query)
175         {
176             user_name = data;
177             //llSay(0, data + " " + user_name);
178         }
179         
180         if(queryid == online_query)
181         {
182             integer online = (integer) data;
183         
184             if(online)
185             {
186                 llSetText(user_name + " is ONLINE\nDrop a NoteCard into me\nto Send " + user_name + " a message.", <0,1,0>, 1.0);
187                 return;   
188             }
189         
190             else
191             {
192                 llSetText(user_name + " is OFFLINE\nDrop a NoteCard into me\nto Send " + user_name + " a message.", <1,0,0>, 1.0);
193                 return;
194             }
195        
196         }     
197     }
198     
199     changed(integer mask)
200     {
201         if(mask & (CHANGED_ALLOWED_DROP | CHANGED_INVENTORY))
202         {
203             integer num_notes = llGetInventoryNumber(INVENTORY_NOTECARD);
204             
205             if(num_notes > 0)
206             {
207                 string note_name = llGetInventoryName(INVENTORY_NOTECARD, 0);
208                             
209                 llSay(0, "Sending Notecard, '" + note_name +"' please stand by.");
210             
211                 llGiveInventory(llGetOwner(), note_name);
212                 
213                 llInstantMessage(llGetOwner(), "A NoteCard has been sent to you: " + note_name);
214                 llSay(0, "The Notecard, " + note_name + " has been sent. Thank you.");
215                 
216             
217                 llRemoveInventory(note_name);
218                 
219                 num_notes = llGetInventoryNumber(INVENTORY_NOTECARD);
220                 
221                 while(num_notes > 0) // They dropped more than one notecard. Clean it up
222                 {   
223                     note_name = llGetInventoryName(INVENTORY_NOTECARD, 0);
224                       
225                     llSay(0, "Deleting " + note_name + ". It was not submitted.  Try Dropping one note at a time.");
226                     
227                     llRemoveInventory(note_name);
228                     
229                     num_notes = llGetInventoryNumber(INVENTORY_NOTECARD);
230                     
231                 }
232                 
233             }
234             
235             else //Not a Notecard
236             {
237                //find out what was dropped and remove it.  
238                 
239                 
240                 list inventory;
241                 integer num_inv = llGetInventoryNumber(INVENTORY_ALL); // Should be 2
242                 integer counter = 0;
243                 while(counter < num_inv)
244                 {
245                     inventory += [llGetInventoryName(INVENTORY_ALL, counter)];
246                     counter ++;   
247                 }
248                 
249                 // WHat we expect to find
250                 list this_script = [llGetScriptName()];
251                 
252                 //Delete this script (which belong in the inventory) from the list
253                 integer index = llListFindList(inventory, this_script);
254                 inventory = llDeleteSubList(inventory, index, index);
255                 
256                 
257                 index = llGetListLength(inventory);
258                 
259                 
260                 //Just in case they snuck in more than one inventory item
261                 while (index >= 1)
262                 {                
263                     llSay(0, "That was not a notecard. Removing " + llList2String(inventory, 0));
264                     llRemoveInventory(llList2String(inventory, 0));
265                     inventory = llDeleteSubList(inventory, 0, 0);
266                     index = llGetListLength(inventory);   
267                 } 
268             }
269         }
270     }
271     
272     on_rez(integer start_param)
273     {
274         llResetScript();
275     }
276 }