Jump to content

Notecard in inventory


LissomePrey
 Share

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

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

Recommended Posts

I am trying to read a notecard (code below) within the inventory of the object. When I wear the object, it can read the notecard perfectly well. When I give a copy of the object to someone else it fails to find the notecard, which is No Modify.

Reading up it seems that maybe the object doesn't actually have the card but simply its key and so when the object but not the card itself is transferred to the other person, the key doesn't correspond to any known object. Is this the problem and if so is there a workaround using notecards or do I need a totally different route?

        if (avatarNumber == 0)
        {
            if (llGetInventoryKey("Identity") == NULL_KEY)
            {
                llOwnerSay( "Notecard '" + "Identity" + "' missing or unwritten");
            }
            notecardQueryId = llGetNotecardLine("Identity", notecardLine);
        }

 

Edited by LissomePrey
simplifying code example
Link to comment
Share on other sites

I think something else is going on, I just don't know what. To figure that out, we'd need more code, a more complete error message, or both.

This code is trying to read from a notecard in Inventory caled "Identity". It's possible for a script to read a notecard by UUID that doesn't need to exist in Inventory, but this isn't doing that.

If the notecard in an object's contents couldn't be transferred, the object containing it wouldn't be transferable either, so that's not what's going on.

In general, though, there's almost never any reason to read a no-modify notecard; if the end user can't modify it, the script itself may as well just contain whatever's in the notecard, saving the overhead of having to read it. The main exception would be if the script only needed to know a few lines at a time from a much larger notecard (or from multiple notecards).

Link to comment
Share on other sites

A couple things jump out at me:

Firstly, based on the code you provided, it appears that your script isn't using a UUID key to reference the notecard. You're giving the function the string literal "Identify" so the script will expect it's host prim's inventory to have a notecard with that exact name. Sidenote, the way you've structured your llOwnewrsay line is generally how one would do so if they were using a variable where "Identify" is. That's what the + symbols are for, to join multiple string or variables together. Just to be sure, is "Idrntify" supposed to be a literal, or a variable?

Secondly, the wiki page for llGetInventoryKey mentions that if the target inventory asset isn't copy+mod+trans, it will return NULL_KEY. So if your notecard is no-modify, I believe that test will always evaluate true.

Link to comment
Share on other sites

10 minutes ago, Fenix Eldritch said:

A couple things jump out at me:

Firstly, based on the code you provided, it appears that your script isn't using a UUID key to reference the notecard. You're giving the function the string literal "Identify" so the script will expect it's host prim's inventory to have a notecard with that exact name. Sidenote, the way you've structured your llOwnewrsay line is generally how one would do so if they were using a variable where "Identify" is. That's what the + symbols are for, to join multiple string or variables together. Just to be sure, is "Idrntify" supposed to be a literal, or a variable?

Secondly, the wiki page for llGetInventoryKey mentions that if the target inventory asset isn't copy+mod+trans, it will return NULL_KEY. So if your notecard is no-modify, I believe that test will always evaluate true.

Yes the full perm looks like the answer, I should read more carefully. My code does have a variable there, I was trying to simplify.

In response to Qie's points, each copy of the object needs to have a unique unchangeable number, I thought a notecard was the easiest. Editing the script each time is a pain particularly as it will undoubtedly get updated. Does anyone have a favourite way of getting a unique integer into a script?

Link to comment
Share on other sites

2 minutes ago, LissomePrey said:

Yes the full perm looks like the answer, I should read more carefully. My code does have a variable there, I was trying to simplify.

In response to Qie's points, each copy of the object needs to have a unique unchangeable number, I thought a notecard was the easiest. Editing the script each time is a pain particularly as it will undoubtedly get updated. Does anyone have a favourite way of getting a unique integer into a script?

One global integer variable at the top of the script.

Using a notecard doesn't reduce the amount of editing you need to do, it increases it. If you have the number in the script, you can change that as you update the rest of the script. If you use a notecard, now you have to update the script and the notecard, and you rely on no one taking out the notecard or you have to make the whole object no-modify. If your object is already no-modify, you could use the object's description instead if you aren't already using it for something else. see: llGetObjectDesc, llSetObjectDesc

Link to comment
Share on other sites

What happens if I get, maybe, 50 people out there, each with a unique script then find a bug or want an enhancement?

Even having an updater, which I'm thinking of, doesn't really help in that respect. If the notecard worked it would be immutable, they would always keep their number so only the one script would need to be updated.. But it doesn't sadly.

Link to comment
Share on other sites

4 minutes ago, LissomePrey said:

What happens if I get, maybe, 50 people out there, each with a unique script then find a bug or want an enhancement?

Even having an updater, which I'm thinking of, doesn't really help in that respect. If the notecard worked it would be immutable, they would always keep their number so only the one script would need to be updated.. But it doesn't sadly.

New question: Does every copy of the product have a unique number in a separate notecard, even if the script is the same? How do you manage to do that? What is the number used for?

Edited by Wulfie Reanimator
Link to comment
Share on other sites

Just now, Wulfie Reanimator said:

New question: Does every copy of the product have a unique number, even if the script is the same? What is the number used for?

To identify which copy it is and, most importantly, to allocate channels that will be unique. So each object will use "base channel" plus its unique number.

I think your idea of getObjectDesc might work, I just change the description for each copy. That would be immutable if the object was no mod?

Link to comment
Share on other sites

36 minutes ago, LissomePrey said:

To identify which copy it is and, most importantly, to allocate channels that will be unique. So each object will use "base channel" plus its unique number.

I was guessing that was what you were doing. In that case, I'd suggest a little trick: Creating a channel from the object owner's UUID, plus a base channel for the specific product.

integer channel = (integer)("0x" + (string)llGetOwner());

To explain that a little bit, you can write integers in a hexadecimal format (up to 8 characters after 0x), for example, 0x601693cb is 1612092363.

All UUIDs use only hexadecimal characters, so you can use any UUID for this.

For example (using my UUID), the code  "0x" + (string)llGetOwner()  gets you "0x601693cb-8c20-4a28-86f1-073d9e23bab2". This is too long to be an integer, but when you typecast it to an integer, it gets shortened to be a proper length and you get 0x601693cb. This is now a valid number you can use as a channel, and add whatever numbers you want. This way, the same line of code always gives a unique channel for each user and you only need to change that base channel for completely different products.

Edited by Wulfie Reanimator
  • Like 2
Link to comment
Share on other sites

Thanks that is a thought but I'd like to constrain them to be  a relatively small number, ideally sequential from 1. I want another amendable notecard in the object too so the no mod won't work.

My current idea is a simple routine that fakes a UUID given a root number and then put that as the object description. Doubt anyone would try to change it even though they could and the object can decode back to the number when rezzed.

Thanks as always for useful input.

Link to comment
Share on other sites

8 hours ago, LissomePrey said:

I am trying to read a notecard (code below) within the inventory of the object. When I wear the object, it can read the notecard perfectly well. When I give a copy of the object to someone else it fails to find the notecard, which is No Modify.

Reading up it seems that maybe the object doesn't actually have the card but simply its key and so when the object but not the card itself is transferred to the other person, the key doesn't correspond to any known object. Is this the problem and if so is there a workaround using notecards or do I need a totally different route?

        if (avatarNumber == 0)
        {
            if (llGetInventoryKey("Identity") == NULL_KEY)
            {
                llOwnerSay( "Notecard '" + "Identity" + "' missing or unwritten");
            }
            notecardQueryId = llGetNotecardLine("Identity", notecardLine);
        }

 

As far as i am aware a no mod note card when transfered can not be read by the script.

Edited by steph Arnott
Link to comment
Share on other sites

1 hour ago, steph Arnott said:

As far as i am aware a no mod note card when transfered can not be read by the script.

This is incorrect, you can read no-mod notecards that you didn't create, even if it was given in a box. This would make sense because you can even read notecards that only exists in someone else's inventory, if you have the UUID.

6 hours ago, LissomePrey said:

Thanks that is a thought but I'd like to constrain them to be  a relatively small number, ideally sequential from 1. I want another amendable notecard in the object too so the no mod won't work. 

My current idea is a simple routine that fakes a UUID given a root number and then put that as the object description. Doubt anyone would try to change it even though they could and the object can decode back to the number when rezzed.

Thanks as always for useful input.

What are you trying to create, exactly?

Low channels make sense for chat commands, but not much else. I can't imagine the practicality of "I want sequential channels for each copy of the product, starting from 1, that is unique to each person." Whatever you are doing, surely there must be a simpler way to do it?

What do you mean by "faking a UUID given a root number (which is always 1 for linksets and 0 for unlinked)?"

Edited by Wulfie Reanimator
semantics
Link to comment
Share on other sites

1 minute ago, Wulfie Reanimator said:

This is false, you can read no-mod notecards that you didn't create, even if it was given in a box. This would make sense because you can even read notecards that only exists in someone else's inventory, if you have the UUID.

The reply is not 'false' because i stated 'as far as i am aware'. The reply would be 'incorrect'. I never stated it was a fact, if i had the it would have been 'false'

Link to comment
Share on other sites

12 hours ago, Wulfie Reanimator said:

Low channels make sense for chat commands, but not much else. I can't imagine the practicality of "I want sequential channels for each copy of the product, starting from 1, that is unique to each person." Whatever you are doing, surely there must be a simpler way to do it?

What do you mean by "faking a UUID given a root number (which is always 1 for linksets and 0 for unlinked)?"

The channels aren't low numbers because the base is a six digit number but they are grouped together. I need it because there will be simultaneous 1-to-1 communications between pairs of people. Also it is useful for reporting to have people given unique and contiguous numbers.

I'm just making the descriptiom look like a UUID which contains the object number encoded in it. Since I want a modifiable script included, I can't make the whole object No Mod so I just have a description that I doubt people will try to change and it is likely to be easily detected if they do.

The other route I may try is to just add a separate small script that does an llMessageLinked with the number when the object is rezzed. That would probably never need an update so gets round the problem I was talking of earlier about needing to updatre many slightly different scripts for bug solving/enhancements.

Edited by LissomePrey
Link to comment
Share on other sites

6 hours ago, LissomePrey said:

The channels aren't low numbers because the base is a six digit number but they are grouped together. I need it because there will be simultaneous 1-to-1 communications between pairs of people

For simultaneous one-to-one communications, could you not use llRegionSayTo and  thus not have to worry about cross--talk and collisions between channels?

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, Innula Zenovka said:

For simultaneous one-to-one communications, could you not use llRegionSayTo and  thus not have to worry about cross--talk and collisions between channels?

Exactly.  Just for the heck of it, here's a HUD-based script that should manage two-person private conversations among pairs of people, all of whom are wearing the same HUD and are in the same region.  All communication other than the internal dialog messages is handled with a single channel.

Basically, each HUD pings everyone in the region once every 15 seconds to see if the person is wearing a HUD.  It uses ping responses to refresh a list of people who may want to talk and then opens a dialog box to show you who's available.  Click the name in the dialog box to open a text box, type a message, and send it to the person.  Your message is sent as a llRegionSayTo message to that specific person.

This script is quick and dirty, written in about 30 minutes and without fancy bells and whistles.  It works in world but isn't designed to be pretty.  I make no guarantees that it is perfect, but it illustrates one way to manage multiple private conversations with a single channel.

integer iChan = -38174992;
integer iMyChan;
integer idx;
integer iMode;
list lTargetAvs;
list lAvNames;

default
{
    state_entry()
    {
        llListen(iChan,"","","");
        iMyChan = (integer) ("0xF" + llGetSubString(llGetOwner(),0,6)); // Dialog and text box channel
        llListen(iMyChan,"","","");
        llSetTimerEvent(2.0);
        iMode = 0;
    }
    
    timer()
    {
        if (!iMode) // time to gather targets
        {
            list lAllAvs = llGetAgentList(AGENT_LIST_REGION,[]); // All avs in region
            lTargetAvs = [];    // Clear the target list
            lAvNames = [];      // Clear the name list
            integer length = llGetListLength(lAllAvs);
            integer i;
            while(i < length)
            {
                llRegionSayTo(llList2Key(lAllAvs,i),iChan,"Ping!"); // test each av to see if they are wearing a HUD
                llSleep(0.2);
                ++i;
            }
            iMode = 1;
            llSetTimerEvent(2.0);
        }
        else  // Dialog activated
        {
            if (lAvNames != [])
            {
                llDialog(llGetOwner(),"Send a message to ... ",lAvNames,iMyChan);   // Refresh the dialog box
            }
            iMode = 0;
            llSetTimerEvent(15.0);
        }            
    }
    
    listen(integer channel, string name, key id, string message)
    {
        if (message == "Ping!") // Received a test ping from some other av in the region
        {
            llRegionSayTo(id, iChan, "Pong!"); // Send confirmation
        }
        else if (message == "Pong!") // Received conformation to your own Ping
        {
            if (llListFindList(lTargetAvs,[llGetOwnerKey(id)]) == -1 )
            {
                key kAv = llGetOwnerKey(id);
                lTargetAvs += [kAv]; // Add to the target list
                lAvNames += [llGetSubString(llKey2Name(kAv),0,11)];  // Save truncated name as a label
            }
        }
        else if (~llListFindList(lAvNames,[message]) )   // Dialog message
        {
            llSetTimerEvent(0.0); //Pause the dialog box generation to keep from overwriting the text box
            idx = llListFindList(lAvNames,[message]);
            llTextBox(llGetOwner(),"\nType your message and click \"Submit\"",iMyChan);
        }
        else
        {
            llRegionSayTo(llList2Key(lTargetAvs,idx),0,message);    //Send the message from the text box to the target av
            llSetTimerEvent(2.0);  // Reactivate the dialog box regeneration
        }        
    }
}

 

  • Like 2
Link to comment
Share on other sites

Yup.  It better.  After all, the HUD has to keep refreshing the list of potential people to talk with in the region . It will refresh every 15 seconds, wait two seconds to recreate its dialog, and then rinse and repeat indefinitely.

As I said, I didn't include any bells and whistles, like an ON/OFF toggle.  You may do that if you wish.  😉

Edited by Rolig Loon
Link to comment
Share on other sites

4 minutes ago, Rolig Loon said:

Yup.  It better.  After all, the HUD has to keep refreshing the list of potential people to talk with in the region .I will refresh every 15 minutes, wait two seconds to recreate its dialog, and then rinse and repeat indefinitely.

Well i know it does cycle, just never used that method. Interesting.

Edited by steph Arnott
Link to comment
Share on other sites

@Rolig Loon I know it's only a rough proof of concept without, as you say, bells and whistles, but am I correct in thinking that an actual application would need to handle the possibility that there are more than 12 responses to the ping?    That is, doesn't it either to limit lTargetAvs to 12 entries or allow for multiple page menus? 

Link to comment
Share on other sites

40 minutes ago, Innula Zenovka said:

am I correct in thinking that an actual application would need to handle the possibility that there are more than 12 responses to the ping?

Absolutely.  And probably an option to list Display names instead of login names, and a HUD readout to tell you where people are, a safety function to disable the device unless it's attached, extra code to deal with communicating across region boundaries, and maybe ways to distinguish between "families" or "clans" of people (if this is some sort of conflict game, maybe).  And, of course, the ON/OFF switch that Steph asked for. Once you start, you can go nuts with feature creep.  For this shot, I was simply running with your suggestion of using llRegionSayTo to avoid needing multiple channels, offset codes, and all that. As I said, this isn't pretty or maybe even flawless.  It's just a proof of concept.

Edited by Rolig Loon
  • Like 1
Link to comment
Share on other sites

10 minutes ago, Rolig Loon said:

  It's just a proof of concept.

I know it is a concept script but one thing puzzles me. If the script gets a barrage of in coming messages would the script not be able to keep pace some point? I am just interested in if that would be the case.

Link to comment
Share on other sites

2 minutes ago, steph Arnott said:

I know it is a concept script but one thing puzzles me. If the script gets a barrage of in coming messages would the script not be able to keep pace some point? I am just interested in if that would be the case.

Scripts have an "event queue" of... 64? So even if a script is busy processing a listen event when a new message arrives, that new message will just wait until the first event resolves. That's the general theory anyway, but I think someone did a test recently, showing that chat messages will have an even longer queue, something to do with how the sim stores chat messages unlike other events.

But even if that wasn't the case and you could only queue 64 messages, by the time the 65th message arrived, the script has probably already finished one or more events, allowing for more messages to be caught.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

1 minute ago, Wulfie Reanimator said:

Scripts have an "event queue" of... 64? So even if a script is busy processing a listen event when a new message arrives, that new message will just wait until the first event resolves. That's the general theory anyway, but I think someone did a test recently, showing that chat messages will have an even longer queue, something to do with how the sim stores chat messages unlike other events.

But even if that wasn't the case and you could only queue 64 messages, by the time the 65th message arrived, the script has probably already finished one or more events, allowing for more messages to be caught.

I did not actually know that.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2013 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...