Jump to content

Auto-Script Updater & HTTP comms


Jettero Borkotron
 Share

You are about to reply to a thread that has been inactive for 463 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I would like to make an auto-script updater. I understand there are limitations with cross sim comms and email seems to be the only way... but then if an object gets re-rezzed or a sim restarted then the email address changes. So my client objects might lose contact with the updater object. Therefore my understanding is that it must somehow be done through an external website. 

Additionally I would like to maintain a database in an external website that I can send and retrieve information from (just names and numbers).

I have no experience of this and don't know where to start. Particularly I don't understand:

- Where / how to host the external website

- How I program it

- How to store the data

- How to send a script externally into sl for the script updater.

I can't find any tutorials on this anywhere and would be very grateful if someone could point me in the right direction. I do have some experience of scripting in SL and previous C++ hobby programmer, but have no experience with web stuff - which I probably why I'm coming across so clueless.

Thank you in advance for anyone who can point me in the right direction.

Link to comment
Share on other sites

DNS for prims would be an awesome feature for LL to add.

I've done this before with a bit of PHP & MySQL on a web server. The prim would poke the external server, register itself, and when other prims wanted its in SL details they could poke the server too. I don't have anything running now and the code is long gone. There has to be some off the shelf examples, this isn't a new problem.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Jettero Borkotron said:

How to send a script externally into sl for the script updater.

This step in particular is impossible (excluding the possibility of a manual copy/paste using the viewer). So that leaves only a few possibilities:

  1. Automatically send an updated version of the object/system to all owners of the previous version.
    • You track those owners either via the distribution method somehow (depends on whether you use MP/casper/something-else.) or send a message to your server the first time the product is rezzed.
    • It's pretty trivial to write a script that llGiveInventoryList()'s to a list of people, although it gets slightly less trivial depending on your order of magnitude.
  2. Send users of the old version a box that interacts with your old version and eventually uses llRemoteLoadScriptPin() to update the scripts.
    • This is fussy and prone to weird failures. IMO not worth it in most cases unless the script has a lot of userdata in script memory (which can now survive transfer in a less fiddly manner with llLinkSetData)
    • If your scripts are only to be used in one specific spot (A roleplaying region or something) this technique might be a bit more viable. The "box" could just be set up in the region.
  3. The scripts are "dumb" and mostly rely on internal data which can be updated.
    • For example, a "texture HUD" could send a message to your server on each rez, and the server could message back if some of the textures are different in the new version.

In most cases, getting stuff done in-world involves having a permanently rezzed prim or two. Prims do not change UUID on region-reset, so slow email communications are stable, but they will lose a url they acquired via llRequest(Secure)URL().

As for the more general "how do I get and use a webserver" question, (amazon-web-services)AWS free tier, seems like a decent entry-point if you don't have the technical know-how or reliable enough internet connection to self host with apache or similar.

Link to comment
Share on other sites

1 hour ago, Jettero Borkotron said:

database in an external website that I can send and retrieve information from (just names and numbers).

If you're a premium member, and the script only ever runs on your land, or land on which your experience is enabled, consider using the experience database llCreateKeyValue and related functions.

Link to comment
Share on other sites

Not sure if it's helpful, but I have a teleporter wearable over on OSGrid that's written using only LSL.  It uses a spreadsheet at Google to record destinations and an llHTTPRequest routine (I think by Maria Korolov at Hypergrid Business) to look up coordinates.  So long as you're just looking up variables and not actually recoding a script, something like it might work for your needs here.

Link to comment
Share on other sites

Hi everybody, thank you very much for your help.

Tessa - that was really detailed and helpful, I will consider the different options. 

Sean - that is also really helpful - I would like to look at your teleporter script if it is possible.

Thanks again to all of you, it is much appreciated. I think I now may have a starting point at least!

Jet. x

Link to comment
Share on other sites

On 12/20/2022 at 2:28 AM, Jettero Borkotron said:

Sean - that is also really helpful - I would like to look at your teleporter script if it is possible.

It's no problem to share the script.  It's a work in progress and more of a learning exercise than anything else.  I just noticed that it uses osTeleportOwner, but llTeleportAgent with the owner's key should work in SL.  I also just noticed that I haven't gotten the portal and beam working yet; that's on the list of things to fix when I circle back around to this.
 

// Script: OS Teleport from Google Sheets database
// by Duncan Steuart@hg.osgrid.org:80
// June, 2018
//
// ==================================================
//             Global Variables
// ==================================================
//
// Set up Google Sheet to store teleport coordinates with columns "", "Destination", "SimName", "LandingPoint.x", "LandingPoint.y", "LandingPoint.z", "LookAt.x", "LookAt.y", and "LookAt.z"  Note first blank column; this is necessary because llCSV2List() does not properly interpret Google exported line ends.

// NB: Google Sheets is used here, but it should be possible to use any publishable spreadsheet tool

// Publish Google Sheet as CSV and paste link here.
string URL ="https://docs.google.com/spreadsheets/d/e/2PACX-1vTG2Gz4EUNKYehv86zRmfViykKDyW4j8fcMIoZ-o8GSCZ5z8LYYtrjCEmliHCFzWFv13MUKn5taHGe4/pub?gid=0&single=true&output=csv";

// Variables used in retrieving coordinates list and looking up information from it.
key HTTPkey;
list DataList = [];
integer LocationIndex;

// Variables for teleport coordinates function.
string Destination;
string SimName;
vector LandingPoint;
vector LookAt;
string Coordinates;

// Other variables.
key Owner;
key Transportee;
integer ListenHandle;
//
// ==================================================
//             Functions
// ==================================================

vector getLandingPoint(string fDestination)
{   
        LandingPoint.x = llList2Float(DataList, LocationIndex + 2);
        LandingPoint.y = llList2Float(DataList, LocationIndex + 3);
        LandingPoint.z = .05 + (llList2Float(DataList, LocationIndex + 4));
        return LandingPoint;
}

vector getLookAt(vector fDestination)
{
        LookAt.x = llList2Float(DataList, LocationIndex + 5);
        LookAt.y = llList2Float(DataList, LocationIndex + 6);
        LookAt.z = llList2Float(DataList, LocationIndex + 7);
        return LookAt;
}

//
// ==================================================
//             Main Routine
// ==================================================
//
default 
{
    on_rez(integer start_param)
    {
        llResetScript();
    }
    
    changed(integer change)     // something changed, take action
    {
        if(change & CHANGED_OWNER)
        {
            llResetScript();
        }
        else if (change & CHANGED_TELEPORT)
        {                       
            llResetScript();
        }
    }
    
    state_entry()
    {
        HTTPkey = llHTTPRequest(URL, [] ,"");
        Owner = llGetOwner();
    }

    http_response(key id, integer status, list meta, string Body)   // Retrieve CSV file from online spreadsheet
    {
        Body = llToLower(Body);         // Convert to lowercase
        DataList = llCSV2List(Body);    // Convert CSV-delimited string body retrieved from URL to LSL list Datalist.  This is a strided list; consider using "2D Pseudo Array" user functions at http://wiki.secondlife.com/wiki/2D_Pseudo-Array
        state listening;    // After retrieving the list, listen for commands
    }
}
    
state listening
{
    state_entry()
    {
        llListenRemove(ListenHandle);
        ListenHandle = llListen(0, "", Owner, "");   // Listen only to owner on ch. 0
    }

    listen(integer channel, string name, key id, string OwnerSez)
    {
        OwnerSez = llToLower(OwnerSez); // Clean input & avoid LSL pickiness
        string OwnerCommand = llGetSubString(OwnerSez, 0, 1);
        
        if(OwnerSez == "t reset")
        {
            llOwnerSay("Resetting coordinates database\nPlease stand by");
            llResetScript();
        }
        
        else if (LocationIndex != -1)
        {
            Destination = llStringTrim(llGetSubString(OwnerSez, 2, -1),STRING_TRIM);
            LocationIndex = llListFindList(DataList, [Destination]);                
            SimName = llList2String(DataList, LocationIndex + 1);
            LandingPoint = getLandingPoint(Destination);
            LookAt = getLookAt(Destination);
        }
        
        else llResetScript;
        
        // Parse commands and process
        if(OwnerCommand == "t ")
        {
            state transport;
        }
        
        else if(OwnerCommand == "p ")
        {
            state portal;
        }
    }
}

state transport
{
    state_entry()
    {
//        llListenRemove(ListenHandle);
        // Rez beam & sound effect for dematerialize
        // llRezObject("Beam 2.0", llGetPos(), ZERO_VECTOR, ZERO_ROTATION, 0);
        llSleep(1.5);
        // Then teleport user.  Rez beam for materialize.
        osTeleportOwner(SimName, LandingPoint, LookAt);
//        llRezObject("Beam 2.0", llGetPos(), ZERO_VECTOR, ZERO_ROTATION, 0);
        LocationIndex = 0;     // Clear location for next transport
        state listening;
    }
}

state portal
{
    state_entry()
    {
         state default;  // Do nothing yet
    }
}
// ==================================================
//             END
// ==================================================

Hope this is helpful.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 463 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...