Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

scan for avatars in range

FoxyHollow Guardian
Registered User
Join date: 29 Oct 2009
Posts: 9
11-26-2009 08:10
have been trying to search, but the results I get are to many so it would probably take me a week to find what I am looking for. Hope anyone of you kind souls could come to my aid. :)

I am trying to scan for avatars in range, but not quite sure how to do that.

This is what I have at the moment:
list avatars;
list keys;
default
{
state_entry()
{
float range = 10.0; //Meters

llSensor("", "", AGENT, range, PI);
}
sensor (integer numberDetected)
{
string msg = "This is the avatars within 10 meter radius:";
integer i = 0;
while(numberDetected > ++i)
{
avatars = (list)llDetectedName(i);
keys = (list)llDetectedKey(i);
}
llDialog(Tadao, msg, avatars, Dialog_Chan);
}
}

This is the first tme I play around with sensors, so I am not quite sure of how to do it.
I need the dialog to tell me what avatars what is in range, and then collect the name (or key) from an listen event.
If I can't get both keys and avatars like I am trying above, then only getting the keys would work too thanks to the llKey2Name (I wish there was an llName2Key aswell) :p

After the name (or key) has been catched, I will send it off to an external server for storage in my MySQL database, that's why I need both key and name in the end.

Anyone who has an good solution to my problem?
Thanks in advance!
/Tadao
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
11-26-2009 08:40
I'm not sure why you think you need llDialog and a listen event. All the information you need is already being collected in the sensor event. You just need to build the lists and provide a way to send them to your external server with an llHTTPRequest function. So, your sensor event could look something like this ....

CODE

sensor (integer numberDetected)
{
llOwnerSay( "These are the avatars within a 10 meter radius:");
integer i = 0;
do
{
llOwnerSay(llDetectedName(i) + " : " + llDetectedKey(i));//Tells you info in private chat
avatars += llDetectedName(i) ; //Builds your list of avatars
keys += llDetectedKey(i); //Builds the list of keys
}
while(numberDetected > ++i);
llHTTPRequest( "url1", [POST], llDumpList2String(avatars, ",") ); //sends a comma-delimited list to url1
llHTTPRequest( "url2", [POST], llDumpList2String(keys, ",") ); //sends a comma-delimited list to url2
avatars = []; //clears the list to prepare for the next scan cycle, if any
keys = [];
}
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
FoxyHollow Guardian
Registered User
Join date: 29 Oct 2009
Posts: 9
11-26-2009 09:02
The llDialog will be needed to select the avatar name and key in my database.
here may be 10 avatars around the object, but only one should be recorded.

The script provided is a part of an vendor script that will set up an commission account on my server. And as there is only one who should recieve commissions, I need the dialog to show me what names are around the object so I can select the one who should have an account created. :)

Edit: And, by the way.. Can I really use two httprequests in the same state?
I was pretty sure only one httprequest could be used in each state.
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
11-26-2009 10:01
From: FoxyHollow Guardian
The llDialog will be needed to select the avatar name and key in my database.
here may be 10 avatars around the object, but only one should be recorded.

The script provided is a part of an vendor script that will set up an commission account on my server. And as there is only one who should receive commissions, I need the dialog to show me what names are around the object so I can select the one who should have an account created. :)

OK, that makes sense. It also potentially makes it more complicated, since there could be a very large number of avatars in the list. Still, it's doable. I'd try something like this ...

CODE

sensor (integer numberDetected)
{
llOwnerSay( "Scan in progress ... Compiling lists. Say \"Sort\" on channel 47 to select names.");
integer i = 0;
do
{
avatars += llDetectedName(i) ; //Builds your list of avatars
keys += llDetectedKey(i); //Builds the list of keys
}
while(numberDetected > ++i);
handle = llListen(47,"",llGetOwner(),"");
llListen(-5678,"","","");
}

listen(integer channel, string name, key id, string msg)
{
integer i;
integer len = llGetListLength(avatars);
if (llToLower(msg) == "sort")
{
llDialog(id,"Do you want to send "+llList2String(avatars,0)+" to the SQL database?", ["Yes","No","Finished"], -5678);
llListenRemove(handle);
i = 0;
}
else if (channel == -5678)
{
if (msg == "Yes")
{
KeepAv = llList2String(avatars,i);
KeepKey = llList2Key(keys,i);
}
else if (msg == "Finished" && (KeepAv != ""))
{
llHTTPRequest(url,[POST], KeepAv +"|" +KeepKey);
}
++i;
if (i <= len-1)
{
llDialog(id,"Do you want to send "+llList2String(avatars,i)+" to the SQL database?", ["Yes","No","Finished"], -5678);
}
}
}


Just be sure to make integer handle a global variable.
I think this code or something like it ought to work. Totally untested, of course, and probably containing a typo or two....

From: someone
Edit: And, by the way.. Can I really use two httprequests in the same state?
I was pretty sure only one httprequest could be used in each state.

Nope. My mistake.... That's why I jammed both KeepAv and KeepKey into the same request this time and put a | delimiter between them. You can separate them with PHP on the other end.
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
FoxyHollow Guardian
Registered User
Join date: 29 Oct 2009
Posts: 9
11-26-2009 10:55
Hmm.. this is not quite the way I am hoping for...

Let me try explain in a different way :)

In the default state, in an on_rez event, I have an dialog popping up, asking "Do you want to create an commission account?"

If I answer "yes", it takes me to state Create_account

In the state_entry of the Create_account, I need the sensor to pick up the avatars that is within a given radius (here set to 10 meters, might get fine tuned a shorter distance).
When the scan is complete, I need an dialog, giving me buttons with names of the avatars nearby (the same way as many of these hug huds or what ever to give you options of who to hug).

Lets say I have 3 avatars near by, Me, John Doe and Jane Doe.
The dialog should give me 3 buttons.. One for each avatar, labeled after the avatar names.

I intend to create the commission account for Jane Doe, so I click button labeled Jane Doe, which should set the following variables:
string Avatar_name = "Jane Doe";
key Avatar_key = "UUID of Jane Doe";

When it comes to the llHTTPRequest adn the PHP scripts, they are all done, all I need is a way to set these two variables.

I could ofcourse just have an listen evnt and manually write something like:

/4444 Jane Doe Key password 20 Parcel name
(Jane Doe, UUID, Password, 30 percent commission, name of parcel)

But it gets so much simplier with the dialogs.

Here's a better example of the code I have.
Now, I have not included the global variables as that list is pretty long (and I don't think it's needed that much either, the globals are set accordingly to the code). :)
CODE

default
{
on_rez(integer start_param)
{
Rez_Dialog = llListen( Dialog_Chan, "", NULL_KEY, "");
llDialog(Tadao, "Shall we set up commissions?",["Yes", "No"], Dialog_Chan);
}

listen(integer Dialog_Chan, string com_dialog_name, key com_dialog_id, string com_dialog_message)
{
llOwnerSay(com_dialog_message);
if ( com_dialog_message == "Yes" )
{
llListenRemove(Rez_Dialog);
state setup_commission_account;
}
else if ( com_dialog_message == "No" )
{
llListenRemove(Rez_Dialog);
state get_perm;
}
}
}

state setup_commission_account
{
state_entry()
{
float range = 10.0; //Meters

llSensor("", "", AGENT, range, PI);
}
sensor (integer numberDetected)
{
string msg = "Select who to give an commission account";
integer i = 0;
while(numberDetected > ++i)
{
list avatars = (list)llDetectedName(i);
list keys = (list)llDetectedKey(i);
}
llDialog(Tadao, msg, avatars, Dialog_Chan);

//To be used for commission_password
// string passwd = randomPass(10);
//
//string data = "auth="+ auth
//+ "&Name=" +Avatar_name
//+ "&UUID=" +Avatar_key
//+ "&Password=" +passwd
//+ "&Location=" +Location
//+ "&Percent=" +Percent
//+ "&Machine=" +Vendor_name;
// create_account = llHTTPRequest(server + "create_commission_account.php" + "?" + data, [ HTTP_METHOD, "GET"], "");
}

}
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
11-26-2009 11:14
Yes, I considered creating a single dialog with multiple buttons and discarded that plan for two reasons. First, labels on buttons have to be very short so most avatar names won't fit on a button. They'll be truncated unless they ARE really short names (like Jane Doe). That's potentially confusing. Second, you might have many people standing around instead of just two or three, so a single dialog can be more complex to construct. That's why I suggested simply reading through the list of stored names one at a time and tossing up a dialog that says "Yes" or "No" for each one.

Of course, as you suggest, you could always save yourself the trouble of doing a scan, sorting names and picking them with a dialog, and so forth by just typing the information manually in chat. Unless you have hundreds of employees and are going to be creating new accounts several times a week, that might be a smarter option anyway.
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
FoxyHollow Guardian
Registered User
Join date: 29 Oct 2009
Posts: 9
11-26-2009 12:06
Well, I won't have any employees, and I doubt I am going to find myself rezzing the vendor at a highly crowded space. If it would be that crowded, I would simply ask the store/venue owner to come with me to my skybox where it will only be me, the person who will have the account, and perhaps an co-owner of the store/venue the vendor will be placed at.

So I believe there won't be any problems with that.

May I please ask you. Without considering the posibility of having 50+ avatars in the scanned area, or the fact that the labels will be truncated (I knew that from the very beginning). Do you know the solution to what I am looking for? Because I'd really like to have it just that way.
FoxyHollow Guardian
Registered User
Join date: 29 Oct 2009
Posts: 9
11-26-2009 16:04
I almost managed to get it.. I think...

Hoping someone can help me sort out the last piece...

This one gives me the avatar names on the buttons:
CODE

sensor (integer numberDetected)
{
string msg = "Select who to give an commission account";
integer i;
while((i < numberDetected) && (i < 9))
{
if (llDetectedKey(i) != llGetOwner())
{
avatarlist += [llDetectedName(i)];
keylist += [llDetectedKey(i)];
}
++i;
}
if (llGetListLength(avatarlist) > 0)
{
avatarlist += ["Cancel"];
llDialog(Tadao, msg, avatarlist, Dialog_Chan);
}


Now is just the question:
When I click the button named "Jane Doe", the listen event gets the message "Jane Doe", but how do I get Janes key?

Or if I take another approach that I have not succeeded with...
If I collect only keys in my loop, how do I:
1. Translate the keys to names for the button labels?
(I tried with using llKey2Name(keylist) in the llDialog, but it didn't work. And just as a
test to see what I would get, I tried with just setting the button variable to "keylist" in
the llDialog, but then got the error "llDialog: Button list must contain only strings";)

2. Set the variables "name" and "uuid" to "Jane Doe" and "Jane does key"

Isn't there anyone who could tell me how to get it the way I want?
It is really the last piece in the puzzle, and I would really love to have it done. Please? :)
Beverly Ultsch
Registered User
Join date: 6 Sep 2007
Posts: 229
11-26-2009 16:54
From: FoxyHollow Guardian

Now is just the question:
When I click the button named "Jane Doe", the listen event gets the message "Jane Doe", but how do I get Janes key?


The two lists avatarlist and keylist are matched so in the listen event you do something like

integer position = llListFindList(avatarlist, message); //where message is the name clicked on
key Avatar_key = llList2Key(keylist, position);
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
11-26-2009 17:17
From: Beverly Ultsch
The two lists avatarlist and keylist are matched so in the listen event you do something like

integer position = llListFindList(avatarlist, message); //where message is the name clicked on
key Avatar_key = llList2Key(keylist, position);

Yup. If you look at the logic in the listen event of the two sample I posted earlier, that's exactly what I did too. So long as the two lists are built together so their elements are in the same order, you can use the index in one to serve the other as well. That's how I can put the avatar name in the text of a dialog and then use the index i of its position in both lists when I go to select the name/key specific pair to save. You could accomplish the same thing by building a single strided list, but paired lists are a lot cleaner to work with.
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask.... ;)

Look for my work in XStreetSL at
FoxyHollow Guardian
Registered User
Join date: 29 Oct 2009
Posts: 9
11-27-2009 02:08
Thank you beverly, it almost worked. Just had to typecast "message" to list, but other than that, it worked just fine. :)

Now there is just one more thing I can't get the hang of..
Have tried a few different approaches without any good results.

The dialog popping up and showing me the names works perfect.
Next thing, I need an second popup that lets me choose how many percent the store/venue owner will get from the sales.

I just can't get the listen to work, and I am not uite sure what I am doing wrong.

Tried to have the percentages on a different channel (-5563) as the normal dialog_chan is on -5564.

I don't know if it is my if statements that are wrong, or if I am just placing the llDialog on the wrong place:

CODE

default
{
touch_start(integer start_param)
{
Rez_Dialog = llListen( Dialog_Chan, "", NULL_KEY, "");
llDialog(Tadao, "Shall we set up commissions?",["Yes", "No"], Dialog_Chan);
}

listen(integer Dialog_Chan, string com_dialog_name, key com_dialog_id, string com_dialog_message)
{
llOwnerSay(com_dialog_message);
if ( com_dialog_message == "Yes" )
{
llListenRemove(Rez_Dialog);
state setup_commission_account;
}
else if ( com_dialog_message == "No" )
{
llListenRemove(Rez_Dialog);
// state get_perm;
}
}
}

state setup_commission_account
{
state_entry()
{
float range = 10.0; //Meters
Name_Dialog = llListen( Dialog_Chan, "", NULL_KEY, "");
llSensor("", "", AGENT, range, PI);
}

sensor (integer numberDetected)
{
string msg = "Select who to give an commission account";
integer i;
while((i < numberDetected) && (i < 9))
{
if (llDetectedKey(i) != llGetOwner())
{
avatarlist += [llDetectedName(i)];
keylist += [llDetectedKey(i)];
}
++i;
}
if (llGetListLength(avatarlist) > 0)
{
avatarlist += ["Cancel"];
llDialog(Tadao, msg, avatarlist, Dialog_Chan);
}
}
listen (integer Channel, string name, key id, string msg)
{
integer position1 = llListFindList(avatarlist, (list)msg); //where message is the name clicked on
string Selected_Avatar = llList2String(avatarlist, position1);

if ( msg == Selected_Avatar )
{
llDialog(Tadao, "Select commission percent rate", ["0","5","7","10","12","15","18","20"], Dialog_Chan);

if ( Channel == -5564 && msg == "0" )
{
Percent = 100;
}
else if ( Channel == -5563 && msg == "5" )
{
Percent = 5;
}
else if ( Channel == -5563 && msg == "7" )
{
Percent = 7;
}
else if ( msg == "10" )
{
Percent = 10;
}
else if ( Channel == -5563 && msg == "12" )
{
Percent = 12;
}
else if ( Channel == -5563 && msg == "15" )
{
Percent = 15;
}
else if ( Channel == -5563 && msg == "18" )
{
Percent = 18;
}
else if ( Channel == -5563 && msg == "20" )
{
Percent = 20;
}

vector regionbase = llGetPos();
list parcel_details = [PARCEL_DETAILS_NAME, PARCEL_DETAILS_DESC];
list details = llGetParcelDetails(regionbase, parcel_details);
string Location = llList2String(details,0);
string passwd = randomPass(5);
list Avatar_Name = llParseString2List(msg, [" "],[]);
string Account_username = llList2String(Avatar_Name,0) +"_" +llList2String(Avatar_Name,1);
integer position2 = llListFindList(avatarlist, (list)msg);
key Avatar_Key = llList2Key(keylist, position2);

string ObjectName = llGetObjectName();
string ObjectDesc = llGetObjectDesc();
string Vendor_name = ObjectName +" " +ObjectDesc;

string Commission_Account_Setup = "auth="+ auth
+ "&Name=" +Account_username
+ "&UUID=" +(string)Avatar_Key
+ "&Password=" +passwd
+ "&Location=" +Location
+ "&Percent=" +(string)Percent
+ "&Machine=" +Vendor_name;

llOwnerSay(Commission_Account_Setup);
}
}

}


Everything else works perfectly fine.
The goal is to have it set the string "Commission_Account_Setup" when both avatar and percentage have been selected.
Beverly Ultsch
Registered User
Join date: 6 Sep 2007
Posts: 229
11-27-2009 16:30
From: FoxyHollow Guardian


I don't know if it is my if statements that are wrong, or if I am just placing the llDialog on the wrong place:


Yes the problem is the IF statements.


Cutting some of your code a bit to show the problem we have.

CODE


listen (integer Channel, string name, key id, string msg)
{
integer position1 = llListFindList(avatarlist, (list)msg); //where message is the name clicked on
string Selected_Avatar = llList2String(avatarlist, position1);

if ( msg == Selected_Avatar )
{
llDialog(Tadao, "Select commission percent rate", ["0","5","7","10","12","15","18","20"], Dialog_Chan);

if ( msg == "0" ) // This can never be true, because to get here msg had to equal Selected_Avatar.
{
Percent = 100;
}
else if (msg == "5" )
{
Percent = 5;
}

}
}


You first check to see if msg == Selected_Avatar, if it does you check to see if msg == "5", this can never be true because to get to this check msg must equal Selected_Avatar.

I think you want something like

CODE

listen (integer Channel, string name, key id, string msg)
{
integer position1 = llListFindList(avatarlist, (list)msg); //where message is the name clicked on
string Selected_Avatar = llList2String(avatarlist, position1);

if ( msg == Selected_Avatar )
{
llDialog(Tadao, "Select commission percent rate", ["0","5","7","10","12","15","18","20"], Dialog_Chan);
}
else if ( msg == "0" )
{
Percent = 100;
}
else if (msg == "5" )
{
Percent = 5;
}
}