Jump to content

self updating teleporter - communication troubles


Tabris Daxter
 Share

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

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

Recommended Posts

hi all,

i'm trying to make a self updating teleporter. (ie. doesn't use notecards or databases etc)

for testing purposes the are positioned no more that 10m apart and all have exactly the same script(shift copythe prim) and all four objects are reset together.

the prims will send the data to each other BUT each prim only recieves the data from one other prim.

integer locnum;
string addydata;
integer startparam;
string dest;
key addy;
list clients = [];
integer bcastchan;
list destnames = [];


default
{
    state_entry()
    {
        clients = [];
        llSetTimerEvent(30);
        bcastchan = llGetUnixTime() / 86400;
        llListen(bcastchan,"","","");
        llSay(bcastchan,"whereareyou");
    }
    
    touch_start(integer badtouch)
    {
        integer i =0;
        while(llGetListLength(clients) > i)
        {
            destnames += llList2String(clients,3);
            i++;
        }
        llDialog(llDetectedKey(0),"Please Select A Destination.",destnames,llGetUnixTime()*-10);
        llOwnerSay(llDumpList2String(destnames,"\n"));
    }
    
    link_message(integer sender, integer num, string msg, key id)
    {
        if (msg == "TELE")
        {
            llSetColor(<1.0,0.0,0.0>,ALL_SIDES);
            
            startparam = llGetUnixTime();
            llListen(startparam,"~~TPSEAT","","");
        }
        else if (msg == "PORT")
        {
            llRezObject("~~TPSEAT",llGetPos()+<0.0,0.0,1.0>,ZERO_VECTOR,ZERO_ROTATION,startparam);
        }
    }
        //llMessageLinked(LINK_THIS,255,"PORT","");
    
    object_rez(key id) 
    {
        llListen(startparam,"~~TPSEAT", id, "");        
        llRemoteLoadScriptPin(id, "TeleScript", startparam, TRUE, startparam);
    }
    
    listen(integer chan, string name, key id, string msg)
    {
        list tmp = llCSV2List(msg);
        if (llList2String(tmp,0) == "whereto")
        {
            list addytmp = llCSV2List(addydata);
            dest = llList2String(addytmp,0);
            addy = llList2Key(addytmp,1);
            llRegionSayTo(addy,bcastchan,"change");
            llWhisper(startparam,"goto,"+dest);
        }
        
        else if (msg == "whereareyou")
        {
            llSay(bcastchan,"loc,"+(string)llGetPos()+","+(string)llGetKey()+","+llGetObjectName());
        }
        else if(llList2String(tmp,0) == "loc")
        {
            clients = llCSV2List(msg);
            //llOwnerSay("ding");
            llSetColor(<0.0,1.0,0.0>,ALL_SIDES);
        }
        else if (~chan = llListFindList( clients, [msg] ))
        {
            /*string 
            llMessageLinked(LINK_THIS,255,"TELE","0,2");*/
            llOwnerSay("found");
        }
    }
            
    timer()
    {
        llSay(bcastchan,"whereareyou");
        llSetColor(<1.0,0.0,0.0>,ALL_SIDES);
        llSetText((string)llGetListLength(destnames),<0.0,1.0,0.0>,1);
        clients = [];
        destnames = [];
    }
}

 the object_rez & link_message areas can be ignored at the moment as they are part of the teleport and not related to the communications for the update.

 

any help is appreciated.

(i know my code may be "dirty" but this is just an early version)

Link to comment
Share on other sites

Your code is not "dirty". It is simply as bad as they come.

Your specific problem is in here:

else if(llList2String(tmp,0) == "loc")
{
clients = llCSV2List(msg);
//llOwnerSay("ding");
llSetColor(<0.0,1.0,0.0>,ALL_SIDES);
}

Each subsequent message overwrites your clients list. Should be:

else if(llList2String(tmp,0) == "loc")
{
clients += llCSV2List(msg);
//llOwnerSay("ding");
llSetColor(<0.0,1.0,0.0>,ALL_SIDES);
}
Link to comment
Share on other sites

/facepalm

BUT


the prims will send the data to each other BUT each prim only recieves the data from one other prim.


now i'm getting 3x the data but still only the data from one other prim. before it was outputting 4 names in the touch event now it puts out 12

EDIT:

narrowed down the problem:

it's in the touch event

touch_start(integer badtouch)    {        integer i =0;        while(llGetListLength(clients) > i)        {            destnames += llList2String(clients,3);            i++;        }        //llDialog(llDetectedKey(0),"Please Select A Destination.",destnames,llGetUnixTime()*-10);        llOwnerSay(llDumpList2String(destnames,"\n"));    }

 in the loop building the destnames list but i don't know where/what it is.

Link to comment
Share on other sites

Here is how I would re-write your script:

// ##########// Important: The multiple TP rezzers must have a unique name.// Same script but different names.// ##########integer CAST_CHANNEL;list NameList;list DestList;key TP_Key;integer TP_Channel;integer TP_Handle;vector TP_Dest;integer DialogChannel;integer DialogHandle;default{    state_entry()    {        CAST_CHANNEL = (integer)("0xF" + llGetSubString((string)llGetOwner(), 0, 6));        // Channel is based on owner UUID         // so that you don't need to reset all of them at once.        llListen(CAST_CHANNEL, "", NULL_KEY, "");        llRegionSay(CAST_CHANNEL, "whereareyou");        llSetTimerEvent(30.0);    }        touch_start(integer badtouch)    {        integer DialogChannel = llGetUnixTime() / -10;        DialogHandle = llListen(DialogChannel, "", llDetectedKey(0), "");        llDialog(llDetectedKey(0), "Please Select A Destination.", NameList, DialogChannel);        llOwnerSay(llDumpList2String(NameList, "\n")); // DEBUG    }        listen(integer chan, string name, key id, string msg)    {        if (chan == TP_Channel)        {            llRegionSayTo(TP_Key, TP_Channel, (string)TP_Dest);            llListenRemove(TP_Handle); // Close TP listener        }        else if (chan == CAST_CHANNEL)        {            if (llGetOwnerKey(id) != llGetOwner()) { return; }            //            if (msg == "whereareyou")            {                // No need to transmit the UUID, nor store it either.                // Let's just keep the name for some corner cases.                llRegionSay(CAST_CHANNEL, "loc, " + (string)llGetPos() + ", " + llGetObjectName());            }            else            {                list tmp = llCSV2List(msg);                //                if (llList2String(tmp, 0) == "loc")                {                    msg = llList2List(tmp, -1, -1); // Name actually                    integer i = llListFindList(NameList, [msg]);                    if (i != -1)                    {                        // Name already known. Let's replace the pos.                        DestList = llListReplaceList(DestList, [(vector)llList2String(tmp, 1)], i, i);                    }                    else                    {                        // Name unknown. Store the name and the pos.                        NameList += msg;                        DestList += (vector)llList2String(tmp, 1);                    }                    llSetColor(<0.0, 1.0, 0.0>, ALL_SIDES);                }            }        }        else if (chan == DialogChannel)        {            llListenRemove(DialogHandle); // Close dialog listener.            // Store the pos matching the name            TP_Dest = llList2Vector(DestList, llListFindList(NameList, [msg]));            TP_Channel = llGetUnixTime();            llRezObject("~~TPSEAT", llGetPos() + <0, 0, 1>, ZERO_VECTOR, ZERO_ROTATION, TP_Channel);        }    }        object_rez(key id)     {        TP_Key = id;        TP_Handle = llListen(TP_Channel, "", TP_Key, "whereto");        // Using llRemoteLoadScriptPin() can't work if you don't set the pin beforehand.        // You can either set a constant pin on the TP seats        // or else they must already contain the needed script.    }    timer()    {        llRegionSay(CAST_CHANNEL, "whereareyou");        llSetColor(<1.0, 0.0, 0.0>, ALL_SIDES);        llSetText((string)llGetListLength(NameList), <0.0, 1.0, 0.0>, 1); // DEBUG    }} 

It works... in theory... Assuming the TP rezzers have different names and the script in the TP seat does what I guessed.

Keep me informed.

Link to comment
Share on other sites

Still bad :) what OP is trying to do is creating a peer-to-peer network and such, no matter how simple, should comply with standard design principles. In a simple peer-to-peer network, each element could be reached from another element so the network topology is simpy a list of existing elements by name or by address (uuid in our case) and routes to them (their positions in our case). This topology list must be dynamic as the elements may come and go.

The list is updated as follows. Each element when it appears <rezzed :)> sends a "hello" message to inform others of its existence so they could adjust their topology lists to include this new peer. After that an element periodically  (30 sec is fine) broadcasts an "ad" message informing others that it is still there and of its position. If an "ad" is not received from an element (twice in a row) all others exclude it from their network topologies.

Y'all instead of "ads" send queries ("whereareyou") which require response. So let's say you have 5 elements. Each sends a query every 30 sec (5 msgs) and 4 others respond to each query, which would be 20 msgs for the total of 25 msgs. In the above standard "ads" scheme there would be only 5 msgs every 30 sec.

Link to comment
Share on other sites

Kal, ty for the help.

i used your script (had to fix a couple of bits :matte-motes-big-grin-wink:) and merged it into mine.

the problem i'm having now with both yours (copied from the forum) and mine is the they BOTH don't rez the ~~TPSEAT object and i can't see any reason why they don't.

// ##########// Important: The multiple TP rezzers must have a unique name.// Same script but different names.// ##########list alpha_names = ["Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliett","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu"]; //gets a unique name will be changed for "live"integer CAST_CHANNEL;list NameList;list DestList;key TP_Key;integer TP_Handle;vector TP_Dest;integer DialogChannel;integer DialogHandle;integer startparam; //this sets the script pin & comm channel for the TP object.default{    state_entry()    {        CAST_CHANNEL = (integer)("0xF" + llGetSubString((string)llGetOwner(), 0, 6));        // Channel is based on owner UUID         // so that you don't need to reset all of them at once.        llSetObjectName(llList2String(alpha_names,(integer)llFrand(26)));        llListen(CAST_CHANNEL, "", NULL_KEY, "");        llRegionSay(CAST_CHANNEL, "whereareyou");        llSetTimerEvent(30.0); //will eventually be llGetUnixTime / 604800 (7 days)    }        touch_start(integer badtouch)    {        integer DialogChannel = llGetUnixTime() / -10;        DialogHandle = llListen(DialogChannel, "", llDetectedKey(0), "");        llDialog(llDetectedKey(0), "Please Select A Destination.", NameList, DialogChannel);        llOwnerSay(llDumpList2String(NameList, "\n")); // DEBUG        llMessageLinked(LINK_THIS,255,"TELE","0,2");    }        listen(integer chan, string name, key id, string msg)    {        if (chan == startparam)        {            llRegionSayTo(TP_Key, startparam, (string)TP_Dest);            llListenRemove(TP_Handle); // Close TP listener        }        else if (chan == CAST_CHANNEL)        {            if (llGetOwnerKey(id) != llGetOwner()) { return; }            //            if (msg == "whereareyou")            {                // No need to transmit the UUID, nor store it either.                // Let's just keep the name for some corner cases.                llRegionSay(CAST_CHANNEL, "loc, " + (string)llGetPos() + ", " + llGetObjectName());            }            else            {                list tmp = llCSV2List(msg);                //                if (llList2String(tmp, 0) == "loc")                {                    msg = llList2String(tmp,-1); // Name actually                    integer i = llListFindList(NameList, [msg]);                    if (i != -1)                    {                        // Name already known. Let's replace the pos.                        DestList = llListReplaceList(DestList, [(vector)llList2String(tmp, 1)], i, i);                    }                    else                    {                        // Name unknown. Store the name and the pos.                        NameList += msg;                        DestList += (vector)llList2String(tmp, 1);                    }                    llSetColor(<0.0, 1.0, 0.0>, ALL_SIDES);                }            }        }        else if (chan == DialogChannel)        {            llListenRemove(DialogHandle); // Close dialog listener.            // Store the pos matching the name            TP_Dest = llList2Vector(DestList, llListFindList(NameList, [msg]));            llMessageLinked(LINK_THIS,255,"PORT","");            llRezObject("~~TPSEAT",llGetPos()+<0.0,0.0,1.0>,ZERO_VECTOR,ZERO_ROTATION,startparam); //This Part Doesn't        }    }        link_message(integer sender, integer num, string msg, key id)    {        if (msg == "TELE") //This Part works        {            llSetColor(<1.0,0.0,1.0>,ALL_SIDES);                        startparam = llGetUnixTime();        }        else if (msg == "PORT") //Neither Does This Part        {            llRezObject("~~TPSEAT",llGetPos()+<0.0,0.0,1.0>,ZERO_VECTOR,ZERO_ROTATION,startparam);        llOwnerSay("sit");        }    }        object_rez(key id)     {        TP_Key = id;        TP_Handle = llListen(startparam, "", TP_Key, "whereto");        llRemoteLoadScriptPin(id, "TeleScript", startparam, TRUE, startparam);        // Using llRemoteLoadScriptPin() can't work if you don't set the pin beforehand.        // You can either set a constant pin on the TP seats        // or else they must already contain the needed script.    }    timer()    {        llRegionSay(CAST_CHANNEL, "whereareyou");        llSetColor(<1.0, 0.0, 0.0>, ALL_SIDES);        llSetText((string)llGetListLength(NameList), <0.0, 1.0, 0.0>, 1); // DEBUG    }} 

 comments added where needed

Link to comment
Share on other sites

I found the bug!

    touch_start(integer badtouch)    {        DialogChannel = llGetUnixTime() / -10; // <<<<< Line to change        DialogHandle = llListen(DialogChannel, "", llDetectedKey(0), "");        llDialog(llDetectedKey(0), "Please Select A Destination.", NameList, DialogChannel);        llOwnerSay(llDumpList2String(NameList, "\n")); // DEBUG    }

 And now it will rez. It will even rez twice with your script.

Is there another script in the prim which needs to be made aware of the rezzing? If not, using a link message is just a pure waste of CPU. If yes, remove the llRezObject() in the listen() event.

And my comment in the rez_object() event is still valid.

To be able to use llRemoteLoadScriptPin(), you must set the pin first with llSetRemoteScriptAccessPin() in the prim which will receive the script. Since you want to be able to rez the object and send a script into it, the pin must be set before you put this object into the inventory of the TP rezzer. There is no way around. Using a dynamic pin based on UnixTime is just impossible...

Unless you already have a script in the TP seat which changes the pin on rez and then asks for the script transfer. Besides the whole concept being slow, it is also tortuous... Well, YMMV.

Next thing to think about: What happens when somebody clicks "Ignore" instead of chosing a destination?

 

 

Link to comment
Share on other sites

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

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...