In developing my current project, an open-source plane, I figured it'd be fun to distribute beta copies of it. Then I figured it'd be nice to update folks' inventory automatically as new features were added, bugs were squished, and UI was polished up. So I cooked up a very basic email-based server / client functionality. If you want to push updates to your clients from a central server you may find a little use for this.
The server script gives its (free) inventory with a click. To turn this into a proper vendor, you'll have to add money-handling functionality. This server doesn't collect any personally-identifiable information, but it could be easily modded to do so, leading to concerns of privacy. Also, anyone smart enough to get the key of this server can easily craft a script to get free copies of the inventory. That's fine for me as my inventory is in this case free, but it may not be appropriate for your needs. Caveat emptor.
Server:
CODE
//License is granted to use, reproduce, modify, bundle, and distribute this script so long as
//this header remains intact and in this script. --Kage Seraph Ad majorem Dei gloriam.
//Or something.
float newestVersion = 0.1; //the most recent version of the inventory object
string objectName = "NAME_OF_INVENTORY_OBJECT"; //the object you're serving
string notesName = "Tread Release Notes"; //the optional notecard that goes with the obj
integer numberServed = 0;
//the server remembers how many objects it has served. That count starts at
//numberServed, which must be updated each time the script is saved.
default
{
on_rez(integer start_param)
{
llOwnerSay((string)llGetKey());
//you must hardcode this key into the client script placed in the object,
//so it knows how to communicate with this server script.
//NOTE: once you rez this server, *don't* rerez it, as that will change
//the key being used. =)
}
state_entry()
{
llOwnerSay((string)llGetKey());
llSetTimerEvent(5); //we poll for new emails every 5 seconds
llOwnerSay("Did you remember to reset the numberServed integer?");
llSetText("Click me\nto recieve a free\nINVENTORY_OBJECT_NAME\n=)",<1,1,1>,1);
}
timer()
{
llGetNextEmail("","");
}
touch_start(integer total_num)
{
++numberServed;
llGiveInventory(llDetectedKey(0),objectName);
llGiveInventory(llDetectedKey(0), notesName);
llInstantMessage(llDetectedKey(0),"Thanks for choosing BeachHead!");
llEmail("YOUR EMAIL ADDY HERE", "Server-Served a INVENTORY_OBJECT (#"+(string)numberServed+")","");
}
email(string time, string address, string subject, string message, integer num_left)
{//syntax for the email: subject = requestor's key, body = version number as a float
key requestorKey = (key)subject;
string messageWithoutHeaders = llDeleteSubString(message, 0, llSubStringIndex(message, "\n\n") + 1);
if ((float)messageWithoutHeaders < 0 )
{
//if someone clicks a rezzed copy of the inventory object,
//the server sends them a fresh copy of the inv. object.
++numberServed;
llInstantMessage(requestorKey,"Your INVENTORY_OBJECT is on its way!");
llGiveInventory(requestorKey, objectName);
llGiveInventory(requestorKey, notesName);
llEmail("YOUR EMAIL ADDY HERE", "Click-Served a INVENTORY_OBJECT (#"+(string)numberServed+")","");
}
else if ( (float)messageWithoutHeaders < newestVersion )
{//someone's rezzed an obsolete version of your INVENTORY_OBJECT
llInstantMessage(requestorKey,"Your INVENTORY_OBJECT is obsolete. I am sending the latest version to you now.");
llGiveInventory(requestorKey, objectName);
llGiveInventory(requestorKey, notesName);
llEmail("YOUR EMAIL ADDY HERE","Updated a INVENORY_OBJECT","");
}
else
{//they're up to date and we dont' have to do anything, really.
llInstantMessage(requestorKey, "Your INVENTORY_OBJECT is up to date.");
llEmail("YOUR EMAIL ADDY HERE","INVENTORY_OBJECT is current","");
}
}
}
The client script goes into the object you're distributing. Every time the object is rezzed, it fires off an email to the server containing the owner's key and the object's version number. This works well for vehicles and things that are rezzed, say, a few times a day. It works less well for attachments that are rezzed every time the user attaches them and every time they teleport-- that's a lot of emails. Your mileage may vary. Be sure to swap in the key of the server object as necessary.
Client script:
CODE
string version = "0.2";//change this as you make updates to your object
default
{
state_entry()
{
llSleep(2);
key sender_key = llGetOwner();
llEmail("KEY_OF_THE_SERVER@lsl.secondlife.com",sender_key,version);
}
on_rez(integer start_param)
{
llResetScript();
}
touch_start(integer foo)
{
if(llDetectedKey(0) != llGetOwner())
{
llGiveInventory(llDetectedKey(0),"NAME_OF_LANDMARK_TO_YOUR_SHOP");
llInstantMessage(llDetectedKey(0),"Delivering your free THINGAMAJIG to you.");
llEmail("SERVER_KEY@lsl.secondlife.com",(string)llDetectedKey(0),"-1");
}
}
}
Have fun! If you mod this or find it particularly useful, drop me a line inworld!