Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discussion: Auto-updater Server

Kage Seraph
I Dig Giant Mecha
Join date: 3 Nov 2004
Posts: 513
01-21-2006 20:02
Hi, all,

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!
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Original Thread
01-22-2006 07:24
/15/56/83781/1.html

edit - heh, fixed 'origiinal'. ne
_____________________
i've got nothing. ;)
Patch Lamington
Blumfield SLuburban
Join date: 2 Nov 2005
Posts: 188
02-15-2006 02:01
This looks like a very handy script.. surprised it hasnt been discussed more.

I assume that if the email message were amended to include a security code, then you could make this secure from attempts to 'steal' updates quite easily. (Obviously take out the touch events too)

Even on attachments, with the current population of SL I dont imagine that a server would be swamped to the point of being unable to handle requests. That could change of course.
_____________________
Blumfield - a regular everyday kind of 'burb in an irregular world.
This notice brought to you by the Blumfield Visitors and Residents Bureau.
Patch Lamington
Blumfield SLuburban
Join date: 2 Nov 2005
Posts: 188
non-freebie Auto Updater
03-22-2006 16:30
My simple hack of Kage's scripts.
Lets you know who has had their THING updated (if you really need to know).
If there are any gaping security flaws with this, let me know cos I cant see them, but I dont know SL inside out like some do :-)

Remember to make the Client Script no-trans!

The really simple client:
CODE

string version = "001";//change this as you make updates to your object
string code = "SECRETCODE";

default
{
state_entry()
{
llSleep(2);
key sender_key = llGetOwner();
llEmail("SERVER_KEY@lsl.secondlife.com",sender_key,
version+code+llKey2Name(llGetOwner()) );
}

on_rez(integer start_param)
{
llResetScript();
}

}


The 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.

// hacked by Patch Lamington to remove freebie giveaway and to use a security code

float newestVersion = 002; //the most recent version of the inventory object
string objectName = "THING"; //the object you're serving
string notesName = "THING Notes"; //the optional notecard that goes with the obj
string code = "SECRETCODE";

default
{
on_rez(integer start_param)
{
llOwnerSay((string)llGetKey());
}

state_entry()
{
llOwnerSay((string)llGetKey());
llSetTimerEvent(10); //we poll for new emails every 5 seconds
llSetText("THING Updater\n=)",<1,1,1>,1);
}

timer()
{
llGetNextEmail("","");
}


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);

string version = llGetSubString(messageWithoutHeaders,0,2);

// check for verification code...
integer tmp = 2+llStringLength(code);
string msg_code = llGetSubString(messageWithoutHeaders,3,tmp);
if (msg_code != code)
return;

if ( (float)version < newestVersion )
{//someone's rezzed an obsolete version of your INVENTORY_OBJECT


llInstantMessage(requestorKey,"Your THING is obsolete. I am sending the latest version to you now.");
llGiveInventory(requestorKey, objectName);
llGiveInventory(requestorKey, notesName);
llEmail("your.address@mail.server","Updated a THING",
"Belonging to "+llGetSubString(messageWithoutHeaders,tmp+1,-1) );
}
else
{//they're up to date and we dont' have to do anything, really.
llInstantMessage(requestorKey, "Your THING is up to date.");
//llEmail("YOUR EMAIL ADDY HERE","INVENTORY_OBJECT is current","");

}
}
}
_____________________
Blumfield - a regular everyday kind of 'burb in an irregular world.
This notice brought to you by the Blumfield Visitors and Residents Bureau.
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
03-23-2006 17:41
Can someone please comment the client better; I still don't understand what goes where.