Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

llInstantMessage Group

Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-02-2006 09:03
Hi!

I'm trying to get a script to talk to any online member of a group. I tried by deeding an object which talks to owner to group but that didn't work. I tried to manually enter the key of the owner when set to group but that also didn't work.

I can't find anywhere that says that I can't, but I also can't find anywhere that says that I can. Search brings up so many results I figured it's easier to just ask at this point!

Thanks for any help guys!
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
Sorry.
11-02-2006 09:44
It doesn`t work.:(

The closest you can come is to have the script attempt to use llInstantMessage() to send a private chat [note: this is not a "real" "instant message"] to everyone on a list. Unfortunately for you, you will have to maintain that list manually, and you will have to have your script send the message to each person individually. Even then, they still have to be in the same sim to get it.
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
11-02-2006 10:05
Most of Lauren's reply is 100% correct. llInstantMessage presents as object chat if you're online, but it's more like a normal IM than she is saying. It will reach you anywhere on the grid, and if you're offline will be forwarded to your email if you have that option for your IMs.

llOwnerSay is the one that won't reach outside the sim (although it will reach you if you're a child agent of the sim as well).
_____________________
Eloise's MiniMall
Visit Eloise's Minimall
New, smaller footprint, same great materials.

Check out the new blog
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
Oops!
11-02-2006 10:42
From: Eloise Pasteur
Most of Lauren's reply is 100% correct. llInstantMessage presents as object chat if you're online, but it's more like a normal IM than she is saying. It will reach you anywhere on the grid, and if you're offline will be forwarded to your email if you have that option for your IMs.

llOwnerSay is the one that won't reach outside the sim (although it will reach you if you're a child agent of the sim as well).
::blush:::o I seem to have confused those two. My apologies. I haven`t made much use of them yet. Just trying to help.
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-02-2006 12:35
Yeah, I'm aware of llInstantMessage, I use it to listen for people coming into my place. When they cross through the door, I receive a message, but only when I'm online. I wanted it to work for the whole group, but since that doesn't work I guess I'll be adding keys then!

I assume a list of users would be the best option? Let me see what I come up with and I'll post it, see what you guys think
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-02-2006 13:35
OK, this is not working... here is the script I started out with. It will IM me if I'm online to tell me someone is there, I need to set it to allow me to add multiple (user) keys to IM them, but again only when they're online. I have got it to IM them all, but can't seem to get it down to only when they're online.

CODE
float ONLINE;

default
{
state_entry()
{
llVolumeDetect(TRUE);
llSetTimerEvent(1);
}

dataserver(key queryid, string data)
{
ONLINE = (float)data;
if (ONLINE == TRUE)
{
llSetObjectDesc("ACTIVE");
}
}

collision_start(integer num_detected)
{
if (ONLINE == TRUE)
{
llInstantMessage(llGetOwner(), llDetectedName(0) + " just entered the building.");
}
}

timer()
{
llRequestAgentData(llGetOwner(), DATA_ONLINE);
llSetTimerEvent(60);
}
}

_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
11-02-2006 15:41
It looks like you need to have a list of the people you want notified, and a second list for who is online at the moment. When the collision_start fires, loop through the list of who is online and fire off IMs to all of them.

That was the easy part.

For the more difficult part, the Dataserver event needs to loop over the list of contacts and update the list of contacts who are online. The dataserver loop is started by the timer event and by script initialization.
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-02-2006 15:48
Yeah, I've got that now. I have a list of keys, and another list that is supposed to be generated from the list of keys and only shows users who are online.

What I've tried is to pass the three keys as key1|key2|key3 through DataServer, and then see how that matches up, but I've just got this output from it: (lopped off the last three chars from each key)

CODE
[15:41]  Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 580fe82a-3d26-69b1-301c-252f4243b
[15:41] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 580fe82a-3d26-69b1-301c-252f4243b
[15:41] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 580fe82a-3d26-69b1-301c-252f4243b
[15:41] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 47bf2a36-6927-bcb8-3006-13354b8eb
[15:41] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 47bf2a36-6927-bcb8-3006-13354b8eb
[15:41] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 47bf2a36-6927-bcb8-3006-13354b8eb
[15:41] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 7e3d4f75-6449-a9bd-fa56-6b9c47180
[15:41] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 7e3d4f75-6449-a9bd-fa56-6b9c47180
[15:41] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 7e3d4f75-6449-a9bd-fa56-6b9c47180
[15:41] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 912ec935-699a-bc0c-2999-3da80faca
[15:41] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 912ec935-699a-bc0c-2999-3da80faca
[15:41] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 912ec935-699a-bc0c-2999-3da80faca
[15:42] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: b9eb81d6-b39c-47fd-7547-79a1762b8
[15:42] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: b9eb81d6-b39c-47fd-7547-79a1762b8
[15:42] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: b9eb81d6-b39c-47fd-7547-79a1762b8
[15:42] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 5d59fe05-720c-583b-fe5b-f24b8990e
[15:42] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 5d59fe05-720c-583b-fe5b-f24b8990e
[15:42] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 5d59fe05-720c-583b-fe5b-f24b8990e
[15:42] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 64070541-c08f-c504-7165-ba0a89083
[15:42] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 64070541-c08f-c504-7165-ba0a89083
[15:42] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 64070541-c08f-c504-7165-ba0a89083
[15:42] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 54112572-5d37-380f-52ef-f41aa6a58
[15:42] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 54112572-5d37-380f-52ef-f41aa6a58
[15:42] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 54112572-5d37-380f-52ef-f41aa6a58
[15:42] Door Bell Test: User Key: 1dc1b901-b6e1-4664-8486-342386817
queryid: 690a20c7-b82d-8600-4982-b2768febf
[15:42] Door Bell Test: User Key: ff147a38-925b-4043-9cb3-344eb2abe
queryid: 690a20c7-b82d-8600-4982-b2768febf
[15:42] Door Bell Test: User Key: bd939a87-1a06-45c2-8e4d-3674f9408
queryid: 690a20c7-b82d-8600-4982-b2768febf


Notice the pattern? I do, the user keys are rattling off in the right order no problem, but every third attempt, the queryid changes. I assume this is no coincidence!

Oh, and I know I've rattled them off in quick succesion, this won't be something that will happen eventually, it's just for debugging, as is the output I have at the mo
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
11-02-2006 15:55
Can you post your dataserver code, please?
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-02-2006 16:08
If you want the code, you can have the code, but I've messed with it so much I no longer know what's going on and it's so damn messy!

CODE
list ALL_USER_KEYS = [ "key1", "key2", "key3" ];
list ONLINE_USER_KEYS;

string ONLINE_USERS;

key THIS_USER;

integer TOTAL_USERS;
integer USER_INDEX;
integer t;

default
{
state_entry()
{
llVolumeDetect(TRUE);
llSetTimerEvent(1);
TOTAL_USERS = llGetListLength(ALL_USER_KEYS);
llInstantMessage(llGetOwner(), (string)TOTAL_USERS + " entries found in Key list");
integer i;
string USER_ENTRY;
//for (i = 0; i < TOTAL_USERS; i++)
//{
// USER_ENTRY = llList2String(ALL_USER_KEYS, i);
// string MESSAGE = (string)i + ": " + USER_ENTRY;
// llInstantMessage(llGetOwner(), MESSAGE);
//}
llInstantMessage(llGetOwner(), "Ready");
}

dataserver(key queryid, string data)
{
integer c;
for (c = 0; c < TOTAL_USERS; c++)
{
string USER_KEY = llList2String(ALL_USER_KEYS, c);
llInstantMessage(llGetOwner(), "User Key: " + USER_KEY + "\nqueryid: " + (string)queryid + "\nTHIS_USER: " + (string)THIS_USER);
if (USER_KEY == queryid)
{
float ONLINE = (float)data;

if (ONLINE == TRUE)
{
llInstantMessage(llGetOwner(), "We have an online member, " + (string)USER_KEY);
}
}
}
}

collision_end(integer num_detected)
{
llOwnerSay("Online Users:\n" + ONLINE_USERS);
//llInstantMessage(llGetOwner(), llDetectedName(0) + " just entered the building.");
}

timer()
{
integer e;
string USER_LIST_STRING;
for (e = 0; e < TOTAL_USERS; e++)
{
if (e > 0)
{
USER_LIST_STRING += "|";
}
USER_LIST_STRING += llList2String(ALL_USER_KEYS, e);
THIS_USER = llRequestAgentData(USER_LIST_STRING, DATA_ONLINE);
}
llInstantMessage(llGetOwner(), USER_LIST_STRING);
THIS_USER = llRequestAgentData(USER_LIST_STRING, DATA_ONLINE);
llSetTimerEvent(5);
}
}


This is not expected to operate as intended, it's at a point where it's debugging output here and there. It does run through fairly quickly though so you only need it to run for a few seconds and then need to stop it
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
11-02-2006 16:33
I`m very sorry to say, but you`ve got this all wrong.

Do not put a loop inside the dataserver event. Make a loop of the dataserver event.

Each time the dataserver event fires, you need to copy the current UUID from the users list to the online users list, advance the pointer, and fire off another dataserver request, until you run out of users.

Something like:
CODE

dataserver(blah....)
{
ONLINE_USER_KEYS =+ [llList2Key(ALL_USER_KEYS, index)];
index ++ ;
if (index < llListLengh(ALL_USER_KEYS)) llRequestAgentData(llList2Key(ALL_USER_KEYS, index), DATA_ONLINE);
}
Your collision_end event, on the other hand does need a loop:
CODE

collision_start(blah...) {
integer i;
for (i=0; i<UsersOnLine; i++) {
llInstantMessage(llList2Key(ONLINE_USER_KEYS, i);
};
};
Bah! I can`t get the code to format properly!
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-02-2006 16:43
OK thanks, I knew I'd got it all wrong, it's the way LSL works, it's been a head ache for me since day one. PHP however, that's a piece of cake, cos I can call things here, there and everywhere as and when I want!

Thanks for your input, I shall try it later, it's too late here now and I want my bed!

Cheers!
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
11-02-2006 17:32
No offence intended; I`m glad none was taken.:) I hope you can get the oddities figured out soon. I had very little difficulty learning LSL, myself, as it is very similar to Javascript, which I already knew, but it took me quite a while to wrap my head arould the llFunction() library and the event list. I struggled with it for weeks, and it suddenly started making sense, without me even noticing the transition. I still have difficulties with individual functions and events, but at least I know the way they fit together now.:) I see that you are still on the other side of that transition, but with some luck and work, it should just start making sense soon.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
11-03-2006 03:25
From: Landing Normandy
OK thanks, I knew I'd got it all wrong, it's the way LSL works, it's been a head ache for me since day one. PHP however, that's a piece of cake, cos I can call things here, there and everywhere as and when I want!

Thanks for your input, I shall try it later, it's too late here now and I want my bed!

Cheers!



I think the problem stems from the fact that you are not used to event driven systems. PHP by comparison to LSL is quite simple.

EDIT:
I dont mean that to sound like a dig, It's a pretty fundamental change in how you have to approach things. In procedural languages you call libraries and get a result, with event triggers you have to wait for the result to find its way to you. Once that concept is absorbed then it does become far easier!
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-03-2006 06:26
Hey guys. Don't worry about offending me, I'll just go postal on you all when I have time. Only kidding. The first person to notice that I don't know what I'm doing was me, the rest of you are just telling me what I already know!

I usually figure out where I'm going wrong and it soon works itself out. It's a mess normally but I slowly neaten it up until I'm happy. This one however has been much more difficult than I anticipated, and I appreciate all the help I can get!
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
11-03-2006 07:21
Have you had a chance yet to try to integrate my code suggestions into your script?
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-03-2006 08:16
Not yet, busy day, will try later.
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
11-03-2006 10:03
From: Landing Normandy
Hey guys. Don't worry about offending me, I'll just go postal on you all when I have time. Only kidding. The first person to notice that I don't know what I'm doing was me, the rest of you are just telling me what I already know!

I usually figure out where I'm going wrong and it soon works itself out. It's a mess normally but I slowly neaten it up until I'm happy. This one however has been much more difficult than I anticipated, and I appreciate all the help I can get!


All of the code tweaking or even minor scripts from scratch really don't let you have a chance to really start to understand LSL. But a project like this...... going to bed at 1 am disgusted that it isn't working and then jumping out of bed an hour later when something clicks. THAT is when it all starts to come together. I am still learning, I would imagine we all are. But after the first big project it is all so much easier.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
11-03-2006 14:47
Not sure if this is the sort of thing you wanted or not.
I've only had a limited chance to test it but it appears to work.

CODE
// Informer v1.0 - Newgate Ludd
// Inform anyone currently online about intruders
//
// Intruder detection left to an external system to send a message
//
list Inform; // People to inform
list OnlineStatus; // Current Online Status
integer Index = 0; // Index into List
integer Max = 0;
//
string notecard = "Inform"; // List of People to inform
integer lineCounter = 0;
key dataRequestID = NULL_KEY;
integer Channel = 0;
//
//----------------------------------------------------------------------------------------
GetParameters(string str)
{
list ldata = llParseString2List(str, ["="], [""]);
string command = llList2String(ldata,0);
string value = llList2String(ldata,1);
if("Channel" == command)
{
Channel = (integer)value;
}
else if("Inform" == command)
{
key id = llList2Key(ldata,1);;
Inform = (Inform = []) + Inform + id;
llOwnerSay("Adding \""+ llKey2Name(id) + "\" (" + value + ") to Inform List");
}
}
//----------------------------------------------------------------------------------------
Reset()
{
Inform = [];
OnlineStatus = [];
dataRequestID = NULL_KEY;
lineCounter = 0;
Index = 0;
}
//---------------------------------------------------------------------------------------------
ItemChanged(integer change)
{
// Test for a changed inventory
if (change & CHANGED_INVENTORY)
{
llResetScript();
}
else if (change & CHANGED_OWNER)
{
llResetScript();
}
}
//----------------------------------------------------------------------------------------
CheckOnline()
{
key TrackId = llList2Key( Inform, Index);
dataRequestID = llRequestAgentData( TrackId, DATA_ONLINE );
}
//----------------------------------------------------------------------------------------
default
{
state_entry() { state ReadConfig; }

on_rez( integer sparam ) { llResetScript(); }

changed(integer change) { ItemChanged(change); }
}
//----------------------------------------------------------------------------------------
state Running
{
// Initial State entry
state_entry()
{
if(Channel == 0)Channel = (integer)llFrand(100);
llOwnerSay("Intruder Sensor Operational. Using channel " + (string)Channel);
llListen(Channel,"","","");
Max = llGetListLength(Inform);
CheckOnline();
llSetTimerEvent(15);
}

listen(integer channel, string name, key id, string message)
{
string str = message + " has entered the restricted area";
integer i;
for(i=0;i<Max;i++)
{
integer online = llList2Integer(OnlineStatus,i);
key userid = llList2Key(Inform,i);
if(online)
llInstantMessage(userid,str);
}
}

// Data Server reply to our request for data
dataserver( key query, string data )
{
if ( query == dataRequestID )
{
// Clear The Timer
llSetTimerEvent(0);
if ( (integer)data ) //Are they online?
OnlineStatus = llListReplaceList(OnlineStatus,[ TRUE ],Index,Index);
else
OnlineStatus = llListReplaceList(OnlineStatus,[ FALSE ],Index,Index);

if(Index < Max)
++Index;
else
Index = 0;
CheckOnline();
llSetTimerEvent(15);
}
}

// NEWGY GOOFED - Forgot to put the timer event in!
timer()
{
llOwnerSay("ERROR - Dataserver time out!");
if(Index < Max)
++Index;
else
Index = 0;
CheckOnline();
}

// Rez from Inventory
on_rez( integer sparam ) { llResetScript(); }

changed(integer change) { ItemChanged(change); }
}
//--------------------------------------------------------------------------------
state ReadConfig
{
state_entry()
{
Reset();
integer itemtype = llGetInventoryType(notecard);
if(INVENTORY_NOTECARD == itemtype)
{
dataRequestID = llGetNotecardLine(notecard, lineCounter);
llSetTimerEvent(10);
}
else
{
llOwnerSay("Error - configuration notecard missing. Owner only operation!");
state Running;
}

}

dataserver( key query_id, string data ) // read from the notecard
{
if(query_id == dataRequestID)
{
if (data != EOF)
{
if(llStringLength(data) > 3)
{
GetParameters(data);
}
lineCounter++;
dataRequestID = llGetNotecardLine( notecard, lineCounter );
}
else
{
llSetTimerEvent(0);
state Running;
}
}
}

timer()
{
llOwnerSay("ERROR - Dataserver time out! aborting");
llSetTimerEvent(0);
state Running;
}

on_rez(integer num) { llResetScript(); }

changed(integer change) { ItemChanged(change); }
}


Script will read a notecard called "Inform" which contains a list of the Keys of people to inform when the sensor is breached.

CODE

Channel=99
Inform=905feb40-ba89-4cc6-b848-2f1b1bafb612


I have purposely left the detection mechanism out, I used a simple volume detect which then broadcast the detected AV's name on the channel that the informer was listening to.
The system could just as easily broadcast the keys and that would allow the informer to only pass on those not on the Inform list.

CODE


listen(integer channel, string name, key id, string message)
{
key id = (key)message;
integer sel = llListFindList(Inform,[id]);
if(sel == -1)
{
string name = llKey2Name(id);
string str = name + " has entered the restricted area";
integer i;
for(i=0;i<Max;i++)
{
integer online = llList2Integer(OnlineStatus,i);
key userid = llList2Key(Inform,i);
if(online)
llInstantMessage(userid,str);
}
}
}


Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-04-2006 06:38
Hey Lauren

Had a go at implementing your ideas, but the code you've written can't just be added and this is why I was trying to write it for myself. Likewise Newgate, although I tried yours and it does seem to be right, when I look at someone else's code it's all just a mess to me; I can't understand what's going on, so now I can't figure out how to have it talk to me on collision(start/end) because although you've commented parts of your code, it doesn't make any sense to me. This is what was raised earlier, because LSL is such an odd language compared to what I understand it means I can't descypher it at all unless I wrote it! I'm looking at loads of subroutines that remind me of the old Atari BASIC I used on the 800XL.

I'm so bad at this that I can't figure out from your code what I need to do extra to make it IM the online users when someone enters. My code, flawed as it was, kinda made sense to me though, and it also seemed a lot shorter.

One other problem I have with just picking up someone else's code is that I don't learn anything. I have loads of scripts that I wrote myself, like a Quaternion Calculator, Online Indicators, Avatar Radars, all the simple things that I could've got from anywhere, but what do I learn by just using copying in someone else's code?

I think the best thing to do is for me to work again from scratch and try to rewrite it. I think I've learnt enough to do that. Sorry if I seem ungrateful, but unlike a lot of people who just want someone to write something for them, I want to learn how to do it myself, and I'm so far behind the level of the people trying to help that I don't think you can help, I dunno!

Thanks though guys. I'll post the code when I finish for you to have a good laugh at the miserable attempt I make myself!
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
11-04-2006 07:42
From: Landing Normandy
Hey Lauren

Had a go at implementing your ideas, but the code you've written can't just be added and this is why I was trying to write it for myself. Likewise Newgate, although I tried yours and it does seem to be right, when I look at someone else's code it's all just a mess to me; I can't understand what's going on, so now I can't figure out how to have it talk to me on collision(start/end) because although you've commented parts of your code, it doesn't make any sense to me. This is what was raised earlier, because LSL is such an odd language compared to what I understand it means I can't descypher it at all unless I wrote it! I'm looking at loads of subroutines that remind me of the old Atari BASIC I used on the 800XL.


Landing, NP, I did it mainly to see if I could and posted it back to let you how I'd approached it. I agree with you, its often easier to rewrite than to adapt, if someone elses coding style is severly different from your own.

The system is currently set to listen on a channel specified in the notecard for names, the second code snippet set it to listen to keys instead.

Below is the code from my volume detect door sensor that I adapted to trigger the system. This was in a different prim.

CODE

// Channel Number encoded into the Description as
// Channel=99
//
integer Channel = -9999;
integer UseNames = 0;

GetParameters()
{
string str = llGetObjectDesc();
list ldata = llParseString2List(str, ["="], [""]);
string command = llList2String(ldata,0);
string value = llList2String(ldata,1);
if("Channel" == command)
{
Channel = (integer)value;
}
if("UseNames" == command)
{
UseNames = (integer)value;
}
}


default
{
state_entry()
{
GetParameters();
llVolumeDetect(TRUE);
llOwnerSay("Sensor Operational. Using channel " + (string)Channel);
}

on_rez(integer num) { llResetScript(); }

collision_start(integer total_number)
{
key id = llDetectedKey(0);
if(UseNames) llSay(Channel,llKey2Name(id));
else llSay(channel,(string)id);
}
}


Quick overview of the rest of the code

The default state is used only to step into the ReadConfig state.

The ReadConfigState iterates its way through the notecard reading its contents.
It then switches to the Running state on completion of initialisation.

The Running state first sets up a listen on the specified channel. If no channel was specified it randomly assigns one.

It then continuiously iterates through the list of Avatars to inform and updates their online status. The data server event simply updates the list of online AV's and then request the next one.

I noticed a bug in my own code here, I havent implemented the timer event that I was going to use in case of stalled dataserver responces. (original code updated)

If the listen event is triggered the code IM's each person on the Inform list who is currently listed as being online. This may give some false negatives and false positives depending upon the sim and the length of the list.

Hope that helps to understand my code even if you dont use it.
Landing Normandy
Proposing 4968
Join date: 28 Nov 2005
Posts: 240
11-04-2006 09:17
Yeah, thanks

You know what I think my problem is? I don't understand what is triggering the DataServer. I put the system in a timed loop hoping that every so-many-seconds the script will check who is online. At that point I expected it to check for all three users. But what is making the DataServer event operate?

I get this much:

state_entry = what to do when said state is first entered. Since I'm only using default in my code this is pretty much as and when it starts up

on_rez = I understand that the state_entry event is not triggered if something is taken and re-rezzed, so this can be used to reset the script

timer = When a llSetTimerEvent countdown expires, the timer event is triggered

Collision_End = When an avatar stops coliding with the object the script is contained within

Now, that all makes sense. But what makes the DataServer event run? If I understood that then no doubt I'll be well away. My v2.0 code (I'm determined to complete this my way!) at present will read the three keys in use from a list and can read them back to me with no problems. I just can't get my head around when the DataServer is running. Look at this as an example of how I'd understand it:

CODE
timer()
Get User Info From Index 0
DataServer Runs
Get User Info From Index 1
DataServer Runs
Get User Info From Index 2
DataServer Runs

data_server()
Gets Online Status of User [INDEX]
If Online, Add to Online User List
Else Do Nothing
Return and Wait for Timer (Unless Collision_End)

collision_end()
IM All Members of Online User List


That makes sense to me, I know when I'm calling DataServer, and I can see how it works. LSL is not in any obvious pattern to me!
_____________________
<VOTE PROPOSITION 4968/>
http://jira.secondlife.com/browse/VWR-4968
For SecondLife Builders who need better mapping for better building
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
11-04-2006 12:30
From: Landing Normandy
Yeah, thanks

You know what I think my problem is? I don't understand what is triggering the DataServer. I put the system in a timed loop hoping that every so-many-seconds the script will check who is online. At that point I expected it to check for all three users. But what is making the DataServer event operate?

I get this much:

state_entry = what to do when said state is first entered. Since I'm only using default in my code this is pretty much as and when it starts up

on_rez = I understand that the state_entry event is not triggered if something is taken and re-rezzed, so this can be used to reset the script

timer = When a llSetTimerEvent countdown expires, the timer event is triggered

Collision_End = When an avatar stops coliding with the object the script is contained within

Now, that all makes sense. But what makes the DataServer event run? If I understood that then no doubt I'll be well away. My v2.0 code (I'm determined to complete this my way!) at present will read the three keys in use from a list and can read them back to me with no problems. I just can't get my head around when the DataServer is running. Look at this as an example of how I'd understand it:

CODE
timer()
Get User Info From Index 0
DataServer Runs
Get User Info From Index 1
DataServer Runs
Get User Info From Index 2
DataServer Runs

data_server()
Gets Online Status of User [INDEX]
If Online, Add to Online User List
Else Do Nothing
Return and Wait for Timer (Unless Collision_End)

collision_end()
IM All Members of Online User List


That makes sense to me, I know when I'm calling DataServer, and I can see how it works. LSL is not in any obvious pattern to me!



OK the big thing here is that the Dataserver doesnt run where you think it does. All that happens is you post a request to it to look up the information. This is a non determenistic, you have no idea when it will respond to you. When it does your data server event will trigger.

Events are not subroutines that you call when you want. They are responces to external triggers.

A more accurate layout would be

CODE
timer()
Get User Info From Index 0
Trigger DataServer Request
Get User Info From Index 1
Trigger DataServer Request
Get User Info From Index 2
Trigger DataServer Request

data_server()
Gets Online Status of User [INDEX]
If Online, Add to Online User List
Else Do Nothing

collision_end()
IM All Members of Online User List


The return / wait for timer are automatic, the event code is completed and the timer will automatically retrigger unless you stop it.

Good luck with writing the script, the satisfaction from doing it yourself and seeing it work is always worth the effort it takes.
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
11-04-2006 12:39
From: Landing Normandy
Hey Lauren

Had a go at implementing your ideas, but the code you've written can't just be added and this is why I was trying to write it for myself.
Hey, Landing, I know you`re wanting to learn how to do it yourself; this is why my code can`t just be added. It was intended to illustrate how to do what you wanted, not to be finished code.

What issues are you having understanding it?

I used collision_start instead of collision_end so it will happen when they arrive, not when they leave. The content of the event handler is a simple loop. It fires off an instant message to everyone in the list of ONLINE_USER_KEYS. Your code sent a single message to yourself when someone left the area.

llRequestAgentData() is a dataserver request.
The dataserver event that the dataserver handler handles is triggered by the results of a dataserver request arriving. You use llRequestAgentData() in script initialization to request the online status of the first resident in ALL_USER_KEYS. When the answer comes, it is handled by the dataserver event. If the resident is online, the handler copies the current UUID from ALL_USER_KEYS to ONLINE_USER_KEYS. If not, not. Either way, the handler then uses llRequestAgentData() on the next agent in ALL_USER_KEYS to fire off another request and trigger the next time through the loop. This repeats until there are no more people in ALL_USER_KEYS, or until the dataserver event fails to trigger [for whatever reason].

The rest of your code looked fairly reasonable.
_____________________
  1. ninjafoo Ng Says:
    November 4th, 2006 at 7:27 am
    We all love secondlife so much and were afraid that the magic will end, nothing this good can ever last…. can it?