User input
|
|
Dennis Birge
Registered User
Join date: 17 May 2006
Posts: 4
|
03-21-2007 08:21
Hello, I'm attempting to make a script where a user can input data through a number of dialog menu's for static answers that won't change and am trying out several other examples to get input from some kind of keypad. For the keypad someone pointed me to the examples on the lsl wiki but neither seems to work. When I try this one: http://wiki.secondlife.com/wiki/Key_Pad_Door it will just time out, it is not accepting the input from the keys so it always goes to default and then it does nothing. And when trying this one: http://wiki.secondlife.com/wiki/Dialog_NumberPad it does not do anything at all. Is there something broken in a recent update that these scripts won't work anymore ? Also I noticed that I picked up a opensource survey script from ICT library which is very nice but is missing the option to add a open question so I looked around and found something called FormTEC which is also nice but not open source so no way to learn from it to alter the original survey script that was the basis for the FormTEC. Does anyone know if there's a opensource script available that can use both free input from chat and the dialog menu for set options or can someone help me in the right direction ? I will be using the collected information in a llHttpRequest() but since there's no real input tags/controls in the lsl language I find myself stuck and any help would be greatly appreciated. Thanks in advance, Dennis
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
03-21-2007 09:16
|
|
Dennis Birge
Registered User
Join date: 17 May 2006
Posts: 4
|
03-22-2007 01:59
Hi, First of all, thanks for showing me that, that is fun but not exactly what I was looking for. Second, the version based on each question in a seperate notecard does not work, it just starts to time out without waiting for user to click it and it shows no menus at all, it just spams mails with timeouts like this: First mail: Object-Name: Object Region: Atlas (258048, 254464) Local-Position: (144, 185, 316) = TIMED OUT. (Should have been ) Where would you like to do it? = TIMED OUT. (Should have been My Answer 1 ) Last mail: Object-Name: Object Region: Atlas (258048, 254464) Local-Position: (144, 185, 316) = TIMED OUT. (Should have been ) Where would you like to do it? = TIMED OUT. (Should have been My Answer 1 ) Where would you like to do it? = TIMED OUT. (Should have been My Answer 1 ) Where would you like to do it? = TIMED OUT. (Should have been My Answer 1 ) Where would you like to do it? = TIMED OUT. (Should have been My Answer 1 ) Where would you like to do it? = TIMED OUT. (Should have been My Answer 1 ) Where would you like to do it? = TIMED OUT. (Should have been My Answer 1 ) The other script with everything in 1 notecard works and gives me a mail like this: Object-Name: Object Region: Atlas (258048, 254464) Local-Position: (149, 181, 316) Dennis Birge What would you like to do? = My Answer 3 (Should have been My Answer 1 ) Where would you like to do it? = My Answer 3 (Should have been My Answer 1 ) What would you like to do? = My Answer 1 (CORRECT) Where would you like to do it? = My Answer 1 (CORRECT) What would you like to do? = My Answer 1 (CORRECT) Where would you like to do it? = My Answer 1 (CORRECT) ---------------------------------------- This is not exactly what I was looking for, I just want to be able to ask a few questions with static answers that they can choose from a menu and a few open questions using the chat feedback or some kind of keypad that the user can use to click his phonenumber together. The script I was using upto now gave me mails like this: Object-Name: Test object Region: Atlas (258048, 254464) Local-Position: (151, 181, 31  Dennis Birge's answers to the questionnaire on notecard Questions. Q1: Option 1 Q2: Dutch Q3: Loc. 1 Q4: 9:00 Q5: CET Based on this notecard: Choose a option. Option 1|Option 2|Option 3|Option 4 What is your native language? Dutch|English|German Choose a location: Loc. 1|Loc. 2|Loc. 3|Other Please select a time. 9:00|10:00|11:00|12:00|13:00|14:00|15:00|16:00|17:00|18:00|19:00|20:00 Which timezone? CET|GMT|PST
What I am looking for, if it is possible, is a way to add a question where the user can use either a dialogue menu to click together a 10 digit phonenumber or where the user is requested to chat a phonenumber or any other open question, is this possible by modifying this script ? Script in a new post to make it alittle readable.
|
|
Dennis Birge
Registered User
Join date: 17 May 2006
Posts: 4
|
03-22-2007 02:02
Here is the script: //============================================================= //SL SURVEY, 1.1 //Gathers survey responses via dialog, emails results from Second Life //Copyright (C) 2006 Eloise Pasteur and Jeremy Kemp //============================================================= //SETTING UP THE OBJECT =============== //Create an object, its name will be the "From" field in the results email //Include the script and a questions notecard //The notecard name will be listed in the body of the results email //Enter questions on one line, answers on the next, alternating lines //Denote separate options in the answer line with a | pipe character //You may need to fiddle a little with the order of your answers - there is no way to automatically adjust them irrespective of the number of answers you have that will also allow you to ask a reasonable number of questions. The dialog box displays as follows: //10, 11, 12 //7, 8, 9 //4, 5, 6 //1, 2, 3 //Example: //What color is the sky? //blue|orange|green|red //This will display the answers as: //red //blue, orange, green //On the buttons.
//No line can be more than 255 characters //Answers are truncated at 8 characters - they can be up to 24 characters but there is only space for 8 characters to display on the buttons.
//LAUNCHING THE SURVEY =============== //Upon resing, the script will request an email address for results - or you can enter your email directly into the script in the first non-orange line below in the format string address="example@aol.com"; //The script will take longer to setup with more questions //Changes to the card after a survey is started require a manual reset of the script
string address; //The email address. email is a restricted word in lsl - it's an event name. - if you don't want to set these each time you can enter your email directly here - the script will automatically adjust and not ask you for your email. integer pointer=0; //Where we are in the various cycles - reading notecards, asking questions etc. list questions; //The questions we've read in list answers; //The answers in raw form (still in one string per answer set) integer listenID; //So we can turn listeners on and off - less lag that way. key owner; //So I can listen to only the owner, and potentially add some admin functions off a touch (not implemented but the code is there). integer chan; //Channel for the silent email registration - required in state_entry AND listen, hence a global. string card; //Name of the notecard you're using. key questionnaire; //Key of the person taking the questionnaire string totalq; //Total number of questions string responses; //The actual answers given, plus querent's name and card name. float timePerQuestion=60.0; //Although there is a sensor to detect crashed etc. people it's not 100% reliable according to some. This lets you set a time (in seconds) per question (so it's currently 1 minute per question) so that if they take too long they time out. For tricky questions you might want to have some more time...
setQuestions() //A function - we need to access this from a couple of places, hence putting it in as a function { string question=llList2String(questions, pointer); //Raw question question=llDumpList2String(llParseString2List(question, ["|"], []), "\n"); //Swaps | for /n (new line) if(llStringLength(question)!=0) { llDialog(questionnaire, question, llParseString2List(llList2String(answers, pointer), ["|"], []), -1001); //Asks the questions in a dialog box. } }
default //Set everything up { state_entry() { llSetText("Setting up", <1.0, 1.0, 1.0>, 1.0); //Show what we're doing. owner=llGetOwner(); //Grab the owner's key for lower down //chan=(integer)("0x"+llGetSubString((string)owner, 0, 1)); //Set up a channel (not 0) based on the key (1-255) so there's silent entry. if(address=="") //They've not entered their email address in the script. { chan=0; listenID=llListen(0, "", llGetOwner(), ""); //Listen only to the owner as well. llOwnerSay("To what email shall I send responses?"); //Tell them what to say - revised for v0.9.3 } else { if(llGetInventoryNumber(INVENTORY_NOTECARD)!=1) //there's not 1 notecard, so I'm not sure which one to use. Complain! { llOwnerSay("You must put exactly one card in me with the questions and answers on it before I can set up!"); //Complain politely... } else //There is only one, so we'll assume (however rashly) it's the right one. { card=llGetInventoryName(INVENTORY_NOTECARD, 0); //Get the card's name pointer=0; //reset the pointer (this is paranoia, but it doesn't hurt) llGetNotecardLine(card, pointer); //Start reading the card (handled in the dataserver event). } } } listen(integer cha, string name, key id, string msg) //Listen event - grab their details and make sure it's all OK. { if(cha==chan) { address=msg; llListenRemove(listenID); //Tidy up the listen, just in case. listenID=llListen(-1001, "", owner, ""); llDialog(owner, "The email address for results is "+msg+". Is that correct?", ["Yes", "No"], -1001); //Check the email address is right } else if(cha=-1001) { if(msg=="Yes") //Email is OK, so... { llListenRemove(listenID); if(llGetInventoryNumber(INVENTORY_NOTECARD)!=1) //there's not 1 notecard, so I'm not sure which one to use. Complain! { llOwnerSay("You must put exactly one card in me with the questions and answers on it before I can set up!"); //Complain politely... } else //There is only one, so we'll assume (however rashly) it's the right one. { card=llGetInventoryName(INVENTORY_NOTECARD, 0); //Get the card's name pointer=0; //reset the pointer (this is paranoia, but it doesn't hurt) llGetNotecardLine(card, pointer); //Start reading the card (handled in the dataserver event). } } else //They put their email address in wrong { llResetScript(); //Well we've not really done anything. We could cycle back to ask again if we'd done more. } } } dataserver(key id, string data) //This handles various things - this time it's reading data from a notecard. { if(data!=EOF) //It's real data, not the end of the file. { if(llStringLength(data)==0) { llSay(0, "CAUTION! Line "+(string)pointer+"of the notecard is blank! This may cause errors, questions to display out of sync with their answers etc."); } if(pointer%2) //is it an odd numbered line { answers+=data; //if so, it's an answer line } else { questions+=data; //else it's even (0 first remember) - so it's a question } pointer++; //Advance the pointer llGetNotecardLine(card, pointer); //Get the next line. } else //It IS the end of the file, so we've grabbed it all... { totalq=(string)llGetListLength(questions); //Get the number of questions state ready; //Go into a ready state, so we can take answers. } } changed(integer change) { if((change & CHANGED_OWNER) || (change & CHANGED_INVENTORY)) //They've changed the contents, or the owner, so reset it - probably a new card after all. { llResetScript(); } } }
state ready //Waiting for victims to answer questions. { state_entry() { llSetText("Touch to start survey\n"+card+" - "+totalq+" ?s.", <0.0, 1.0, 0.0>, 1.0); //Tell punters what to do } changed(integer change) { if((change & CHANGED_OWNER) || (change & CHANGED_INVENTORY)) //They've changed the contents, or the owner, so reset it - probably a new card after all. { llResetScript(); } } touch_start(integer num) //Process the touch { key temp=llDetectedKey(0); if(temp==owner) //No admin built in, but it's available as an option { //offer some options questionnaire=temp; state running; } else //It's a punter - start the questionnaire. { questionnaire=temp; state running; } } }
state running //We're actually asking questions { state_entry() { llSetTimerEvent(timePerQuestion * (float)totalq); //This is a timer to clean up people that don't finish but the sensor doesn't catch for some reason. llSetText(llKey2Name(questionnaire)+" is taking the questionnaire, please wait!", <0.0, 0.0, 1.0>, 1.0); //Tell the world so! listenID=llListen(-1001, "", questionnaire, ""); //Only listen to the answers, stops spamming llSensorRepeat("", questionnaire, AGENT, 60, PI, 30.0); //Keep checking they're still there - they might have got bored and wondered off, crashed etc. pointer=0; //reset the pointer (recycling variables is good) setQuestions(); //Ask the first question (see function above) } listen(integer chan, string name, key id, string msg) //Listen for the answers. { if(pointer==0) //First answer, so say what's happening. { responses=name+"'s answers to the questionnaire on notecard "+card+".\n"; } responses+="Q"+(string)(pointer+1)+": "+msg+"\n"; //Add their answer to this question to the email. pointer++; if(pointer==(integer)totalq) //Got to last question. { llSay(0, "Thank you for taking this questionnaire. Please wait whilst I send the results before starting."); //Tell them they're done. llSetText("Sending results, please wait.\nThis should take about 20s.", <1.0, 0.0, 0.0>, 1.0); //Tell others they're done too, and to wait a bit llEmail(address, "Questionnaire answers", responses); //Send the email. state ready; //Back to the ready state } else { setQuestions(); //Ask the next question } } no_sensor() //The person's left, so send their partial answers { llSensorRemove(); //Tidy up llEmail(address, "Questionnaire answers", responses); //Send email state ready; //Back to ready state } timer() { llSensorRemove(); //Tidy up - slow sensor repeats aren't THAT laggy, but are a bit llSetTimerEvent(0.0); //Tidies up the timer to stop it firing llEmail(address, "Questionnnaire answers", responses); //Send their answers state ready; //Back to ready state } }
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
03-22-2007 02:51
From: Dennis Birge Hi,
First of all, thanks for showing me that, that is fun but not exactly what I was looking for. Well I didnt actually post it as a solution, more as a stepping stone to give you an idea of how to proceed, and some code that was known to do at least part of what you wanted. From: Dennis Birge Second, the version based on each question in a seperate notecard does not work, it just starts to time out without waiting for user to click it and it shows no menus at all. Hmm, doesnt it, I'm reasonably sure (as sure as I ever am) that it would work when I posted it, I may have to have a quick look see what's broken. From: Dennis Birge What I am looking for, if it is possible, is a way to add a question where the user can use either a dialogue menu to click together a 10 digit phonenumber or where the user is requested to chat a phonenumber or any other open question, is this possible by modifying this script ?
Script in a new post to make it alittle readable. When ever you use a dialog you are actually using chat, The llDialog function routes the answers back from the avatar as chat on the chossen channel. Making it so that someone can enter a 10 digit number would require a 'looped' dialog, i.e. each time you enter a number and it was received in the listen function it would need to concatenate the string and then display the dialog again for the next digit. Not exactly difficult, in fact I think TomFox was after soemthing similar a while ago for lotto numbers.? 10 digit phone number limits your user base but thats probably intentional? The other problem would be that a dialog is limited to 12 buttons at a time so for a standard text answer it would be incredibly clumsy to use.
|
|
Dennis Birge
Registered User
Join date: 17 May 2006
Posts: 4
|
03-22-2007 06:22
From: Newgate Ludd Making it so that someone can enter a 10 digit number would require a 'looped' dialog, i.e. each time you enter a number and it was received in the listen function it would need to concatenate the string and then display the dialog again for the next digit. Not exactly difficult, in fact I think TomFox was after soemthing similar a while ago for lotto numbers.? 10 digit phone number limits your user base but thats probably intentional? The other problem would be that a dialog is limited to 12 buttons at a time so for a standard text answer it would be incredibly clumsy to use. Well I tried getting the dialog example from lsl wiki to work but it refuses to cooperate. The 10 digit phonenr is just something i am using for now, can always change it later if it needs to be changed. I'm now trying to change the script so that it asks to type in the phonenr before the menu comes with the questions but when I try it out it asks for phonenr and immediately shows the menu for the other questions so if I type in a phonenr it doesn't get recorded and my mail is not getting any data from it either. state running //We're actually asking questions { state_entry() { llSetTimerEvent(timePerQuestion * (float)totalq); //This is a timer to clean up people that don't finish but the sensor doesn't catch for some reason. llSetText(llKey2Name(questionnaire)+" is currently using the system, please come back in a minute.", <0.0, 0.0, 1.0>, 1.0); //Tell the world so! listenID=llListen(-1001, "", questionnaire, ""); //Only listen to the answers, stops spamming llSensorRepeat("", questionnaire, AGENT, 60, PI, 30.0); //Keep checking they're still there - they might have got bored and wondered off, crashed etc. pointer=0; //reset the pointer (recycling variables is good) llSay(0, "Please type your phone nr."); llListen(0, "llGetAgentInfo(llDetectedKey(0))", NULL_KEY, phonenr); setQuestions(); //Ask the first question (see function above) } listen(integer chan, string name, key id, string msg) //Listen for the answers. { if(pointer==0) //First answer, so say what's happening. { responses=name+"'s answers to the questionnaire on notecard for phonenr "+phonenr+ card+".\n"; } responses+="Q"+(string)(pointer+1)+": "+msg+"\n"; //Add their answer to this question to the email. pointer++; if(pointer==(integer)totalq) //Got to last question. { llSay(0, "Thank you for using this service. One moment please while we are sending your message."); //Tell them they're done. llSetText("Sending message, one moment please.\nThis takes about 20 seconds.", <1.0, 0.0, 0.0>, 1.0); //Tell others they're done too, and to wait a bit llEmail(address, "Questionnaire answers", responses); //Send the email. state ready; //Back to the ready state } else { setQuestions(); //Ask the next question } } no_sensor() //The person's left, so send their partial answers { llSensorRemove(); //Tidy up llEmail(address, "Questionnaire answers", responses); //Send email state ready; //Back to ready state } timer() { llSensorRemove(); //Tidy up - slow sensor repeats aren't THAT laggy, but are a bit llSetTimerEvent(0.0); //Tidies up the timer to stop it firing llEmail(address, "Questionnnaire answers", responses); //Send their answers state ready; //Back to ready state }
I'm not sure how I can solve this, should I add a wait function somewhere, which might break the entire thing if they don't input a phonenr? Or, and I think this is the best option but I don't know how, should I put it in a new function like the setQuestions() function? It would be easier if I could just use some kind of form tags like in webpages, but that's not an option  Any more pointers would be greatly appreciated.
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
03-22-2007 15:31
From: Dennis Birge Well I tried getting the dialog example from lsl wiki to work but it refuses to cooperate. The 10 digit phonenr is just something i am using for now, can always change it later if it needs to be changed. I'm now trying to change the script so that it asks to type in the phonenr before the menu comes with the questions but when I try it out it asks for phonenr and immediately shows the menu for the other questions so if I type in a phonenr it doesn't get recorded and my mail is not getting any data from it either. state running //We're actually asking questions { state_entry() { llSetTimerEvent(timePerQuestion * (float)totalq); //This is a timer to clean up people that don't finish but the sensor doesn't catch for some reason. llSetText(llKey2Name(questionnaire)+" is currently using the system, please come back in a minute.", <0.0, 0.0, 1.0>, 1.0); //Tell the world so! listenID=llListen(-1001, "", questionnaire, ""); //Only listen to the answers, stops spamming llSensorRepeat("", questionnaire, AGENT, 60, PI, 30.0); //Keep checking they're still there - they might have got bored and wondered off, crashed etc. pointer=0; //reset the pointer (recycling variables is good) llSay(0, "Please type your phone nr."); llListen(0, "llGetAgentInfo(llDetectedKey(0))", NULL_KEY, phonenr); setQuestions(); //Ask the first question (see function above) } listen(integer chan, string name, key id, string msg) //Listen for the answers. { if(pointer==0) //First answer, so say what's happening. { responses=name+"'s answers to the questionnaire on notecard for phonenr "+phonenr+ card+".\n"; } responses+="Q"+(string)(pointer+1)+": "+msg+"\n"; //Add their answer to this question to the email. pointer++; if(pointer==(integer)totalq) //Got to last question. { llSay(0, "Thank you for using this service. One moment please while we are sending your message."); //Tell them they're done. llSetText("Sending message, one moment please.\nThis takes about 20 seconds.", <1.0, 0.0, 0.0>, 1.0); //Tell others they're done too, and to wait a bit llEmail(address, "Questionnaire answers", responses); //Send the email. state ready; //Back to the ready state } else { setQuestions(); //Ask the next question } } no_sensor() //The person's left, so send their partial answers { llSensorRemove(); //Tidy up llEmail(address, "Questionnaire answers", responses); //Send email state ready; //Back to ready state } timer() { llSensorRemove(); //Tidy up - slow sensor repeats aren't THAT laggy, but are a bit llSetTimerEvent(0.0); //Tidies up the timer to stop it firing llEmail(address, "Questionnnaire answers", responses); //Send their answers state ready; //Back to ready state }
I'm not sure how I can solve this, should I add a wait function somewhere, which might break the entire thing if they don't input a phonenr? Or, and I think this is the best option but I don't know how, should I put it in a new function like the setQuestions() function? It would be easier if I could just use some kind of form tags like in webpages, but that's not an option  Any more pointers would be greatly appreciated. Several problems with the code you have posted. Firstly you are setting up two listens to what I expect to be the same person on different channels, one on channel -1001 and also again on 0 is that intentional? The second call to llListen wont actually work, the second parameter should be the key of the avatar you want to listen to not a string. And llGetAgentInfo doesnt work like that anyway. You are also passing in phonenr as a parameter which will make the listen filter for just the text contained in that variable at that time, not what you want at all. The main problem is that you trigger the questionaire immediately when you call SetQuestions, what you need to do is capture the phone number information pior to starting the questionaire. I'd suggest using a seperate state and then only switched to the questionaire running state after you have all the relevant user information.
|