X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=huffware%2Fhuffotronic_scripts%2FFreeView_v1.8.txt;fp=huffware%2Fhuffotronic_scripts%2FFreeView_v1.8.txt;h=bb809fd4042229c9edaf7b2dc12ff3621711b42e;hb=2ad923922ef5c1e212dd45aa5074f08d54ea9371;hp=0000000000000000000000000000000000000000;hpb=1809c04b7499a188d1c2a7df3ec588bc8591a2e3;p=feisty_meow.git diff --git a/huffware/huffotronic_scripts/FreeView_v1.8.txt b/huffware/huffotronic_scripts/FreeView_v1.8.txt new file mode 100755 index 00000000..bb809fd4 --- /dev/null +++ b/huffware/huffotronic_scripts/FreeView_v1.8.txt @@ -0,0 +1,834 @@ + +// huffware script: freeview modified by fred huffhines (see original license below). +// +// my changes are licensed this way: +// this script is licensed by the GPL v3 which is documented at: http://www.gnu.org/licenses/gpl.html +// do not use it in objects without fully realizing you are implicitly accepting that license. +// +// fred's changes include: +// + assorted tweaks that i have since forgotten the details about. +// + set the freeview to startup as a picture viewer, since that's my most common usage. + +////////////// +// original author info and licensing: +//FreeView 1.2 WebGuide (revision 4) - By CrystalShard Foo +//Multifunctional Picture viewer and Video control script with webguide support +//This script is distributed for free and must stay that way. +// *** If you wish to give/sell a product using this script, *** +// *** THEN THE SCRIPT MUST REMAIN FULL-PERM AND FREE. *** +// *** Failure to do so will REVOKE your right to use it! *** +//Help for using this script can be obtained at: http://www.slguide.com/help +//Feel free to modify this script and post your improvement. Leave the credits intact but feel free to add your name at its bottom. +//Whats new: +//- Now using FULL_BRIGHT instead of PRIM_MATERIAL_LIGHT for the screen display +//- Added an ownership-change code to handle cases where FreeView gets deeded to group post Video Init. +//- Renamed WebGuide to TV-Guide to reflect what this thing does better. +//- Added a 'Fix Scale' button to Picture mode to help against user texture-scale changes. +//- Additional minor help-tips and code improvements +//Enjoy! +////////////// + + +//Constants +integer PICTURE_ROTATION_TIMER = 30; //In whole seconds + +integer DISPLAY_ON_SIDE = ALL_SIDES; //Change this to change where the image will be displayed + +key VIDEO_DEFAULT = "71b8ff26-087d-5f44-285b-d38df2e11a81"; //Test pattern - Used as default video texture when one is missing in parcel media +key BLANK = "5748decc-f629-461c-9a36-a35a221fe21f"; //Blank texture - Used when there are no textures to display in Picture mode +string NOTECARD = "bookmarks"; //Used to host URL bookmarks for video streams + +integer VIDEO_BRIGHT = TRUE; //FULL_BRIGHT status for Video +integer PICTURE_BRIGHT = TRUE; //FULL_BRIGHT status for Picture + +integer REMOTE_CHANNEL = 9238742; + +integer EXTERNAL_TOUCH_CHANNEL = 1327; + // used by other prims to tell the viewer prim that the avatar has clicked on them. + +integer mode = 0; //Freeview mode. + //Mode 0 - Power off + //Mode 1 - Picture viewer + //Mode 2 - Video + +integer listenHandle = -1; //Dialog menu listen handler +integer listenUrl = -1; //listen handler for channel 1 for when a URL is being added +integer listenTimer = -1; //Timer variable for removing all listeners after 2 minutes of listener inactivity +integer listenRemote = -1; //listen handler for the remote during initial setup +integer encryption = 0; +integer numberofnotecardlines = 0; //Stores the current number of detected notecard lines. +integer notecardline = 0; //Current notecard line + +integer loop_image = FALSE; //Are we looping pictures with a timer? (picture mode) +integer current_texture = 0; //Current texture number in inventory being displayed (picture mode) +integer chan; //llDialog listen channel +integer notecardcheck = 0; +key video_texture; //Currently used video display texture for parcel media stream + +string moviename; +string tempmoviename; +key notecardkey = NULL_KEY; +key tempuser; //Temp key storge variable +string tempurl; //Temp string storge variable + +integer isGroup = TRUE; +key groupcheck = NULL_KEY; +key last_owner; +key XML_channel; + +pictures() //Change mode to Picture Viewer +{ + //Initilize variables + + //Change prim to Light material while coloring face 0 black to prevent light-lag generation. + llSetPrimitiveParams([PRIM_BUMP_SHINY, DISPLAY_ON_SIDE, PRIM_SHINY_NONE, PRIM_BUMP_NONE, PRIM_COLOR, DISPLAY_ON_SIDE, <1,1,1>, 1.0, PRIM_MATERIAL, PRIM_MATERIAL_PLASTIC, PRIM_FULLBRIGHT, DISPLAY_ON_SIDE, PICTURE_BRIGHT]); + + integer check = llGetInventoryNumber(INVENTORY_TEXTURE); + + if(check == 0) + { + report("No pictures found."); + llSetTexture(BLANK,DISPLAY_ON_SIDE); + return; + } + else + if(current_texture > check) + //Set to first texture if available + current_texture = 0; + + display_texture(current_texture); +} + +video() //Change mode to Video +{ + //Change prim to Light material while coloring face 0 black to prevent light-lag generation. + llSetPrimitiveParams([PRIM_BUMP_SHINY, DISPLAY_ON_SIDE, PRIM_SHINY_NONE, PRIM_BUMP_NONE, PRIM_COLOR, DISPLAY_ON_SIDE, <1,1,1>, 1.0, PRIM_MATERIAL, PRIM_MATERIAL_PLASTIC, PRIM_FULLBRIGHT, DISPLAY_ON_SIDE, VIDEO_BRIGHT, PRIM_TEXTURE, DISPLAY_ON_SIDE, "62dc73ca-265f-7ca0-0453-e2a6aa60bb6f", llGetTextureScale(DISPLAY_ON_SIDE), llGetTextureOffset(DISPLAY_ON_SIDE), llGetTextureRot(DISPLAY_ON_SIDE)]); + + report("Video mode"+moviename+": Stopped"); + if(finditem(NOTECARD) != -1) + tempuser = llGetNumberOfNotecardLines(NOTECARD); + video_texture = llList2Key(llParcelMediaQuery([PARCEL_MEDIA_COMMAND_TEXTURE]),0); + if(video_texture == NULL_KEY) + { + video_texture = VIDEO_DEFAULT; + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_TEXTURE,VIDEO_DEFAULT]); + llSay(0,"No parcel media texture found. Setting texture to default: "+(string)VIDEO_DEFAULT); + if(llGetLandOwnerAt(llGetPos()) != llGetOwner()) + llSay(0,"Error: Cannot modify parcel media settings. "+llGetObjectName()+" is not owned by parcel owner."); + } + + llSetTexture(video_texture,DISPLAY_ON_SIDE); +} + +off() +{ + report("Click to power on."); + llSetPrimitiveParams([PRIM_BUMP_SHINY, DISPLAY_ON_SIDE, PRIM_SHINY_LOW, PRIM_BUMP_NONE, PRIM_COLOR, DISPLAY_ON_SIDE, <0.1,0.1,0.1>, 1.0,PRIM_MATERIAL, PRIM_MATERIAL_PLASTIC, PRIM_FULLBRIGHT, DISPLAY_ON_SIDE, FALSE, PRIM_TEXTURE, DISPLAY_ON_SIDE, BLANK, llGetTextureScale(DISPLAY_ON_SIDE), llGetTextureOffset(DISPLAY_ON_SIDE), llGetTextureRot(DISPLAY_ON_SIDE)]); +} + +integer finditem(string name) //Finds and returns an item's inventory number +{ + integer i; + for(i=0;i 0) + header = "("+(string)(current_texture+1)+"/"+(string)check+") "+llGetInventoryName(INVENTORY_TEXTURE,current_texture); + else + header = "No pictures found."; + llDialog(id,"** Monitor Control **\n Picture Viewer mode\n- Image browser\n- "+header,["Back","Next","Menu"],chan); + extendtimer(); +} + +report(string str) +{ + llSetObjectDesc(str); +} + +extendtimer() //Add another 2 minute to the Listen Removal timer (use when a Listen event is triggered) +{ + if(listenHandle == -1) + listenHandle = llListen(chan,"","",""); + listenTimer = (integer)llGetTime() + 120; + if(loop_image == FALSE) + llSetTimerEvent(45); +} + +config(key id) //Configuration menu +{ + extendtimer(); + llDialog(id,"Current media URL:\n"+llList2String(llParcelMediaQuery([PARCEL_MEDIA_COMMAND_URL]),0)+"\nTip: If the picture is abit off, try 'Align ON'",["Set URL","Align ON","Align OFF","Menu","Set Remote"],chan); +} + +tell_remote(string str) +{ + llShout(REMOTE_CHANNEL,llXorBase64Strings(llStringToBase64((string)encryption + str), llStringToBase64((string)encryption))); +} + +menu(key id) //Dialog menus for all 3 modes +{ + list buttons = []; + string title = "** Monitor control **"; + + extendtimer(); + + if(mode != 0) + { + if(mode == 1) //Pictures menu + { + title+="\n Picture Viewer mode"; + buttons+=["Browse"]; + if(loop_image == FALSE) + buttons+=["Loop"]; + else + buttons+=["Unloop"]; + buttons+=["Video","Power off","Help","Fix scale"]; + } + else //Video menu + { + title+="\n Video display mode\n"+moviename+"\nTip:\nClick 'TV Guide' to view the Online bookmarks."; + buttons+=["Pictures","Configure","Power off","Loop","Unload","Help","Play","Stop","Pause","TV Guide","Bookmarks","Set URL"]; + } + } + else + buttons += ["Pictures","Video","Help"]; + + llDialog(id,title,buttons,chan); +} + +display_texture(integer check) //Display texture and set name in description (picture mode) +{ //"Check" holds the number of textures in contents. The function uses "current_texture" to display. + string name = llGetInventoryName(INVENTORY_TEXTURE,current_texture); + llSetTexture(name,DISPLAY_ON_SIDE); + report("Showing picture: "+name+" ("+(string)(current_texture+1)+"/"+(string)check+")"); +} + + +next() //Change to next texture (picture mode) +{ //This function is used twice - by the menu and timer. Therefor, it is a dedicated function. + current_texture++; + integer check = llGetInventoryNumber(INVENTORY_TEXTURE); + if(check == 0) + { + llSetTexture(BLANK,DISPLAY_ON_SIDE); + current_texture = 0; + report("No pictures found."); + return; + } + if(check == current_texture) + current_texture = 0; + + display_texture(check); + return; +} + +////////////// +// from hufflets... + +// returns the index of the first occurrence of "pattern" inside +// the "full_string". if it is not found, then a negative number is returned. +integer find_substring(string full_string, string pattern) +{ return llSubStringIndex(llToLower(full_string), llToLower(pattern)); } + +// returns TRUE if the "prefix" string is the first part of "compare_with". +integer is_prefix(string compare_with, string prefix) +{ return find_substring(compare_with, prefix) == 0; } + +////////////// +// huffware script: auto-retire, by fred huffhines, version 2.8. +// distributed under BSD-like license. +// !! keep in mind that this code must be *copied* into another +// !! script that you wish to add auto-retirement capability to. +// when a script has auto_retire in it, it can be dropped into an +// object and the most recent version of the script will destroy +// all older versions. +// +// the version numbers are embedded into the script names themselves. +// the notation for versions uses a letter 'v', followed by two numbers +// in the form "major.minor". +// major and minor versions are implicitly considered as a floating point +// number that increases with each newer version of the script. thus, +// "hazmap v0.1" might be the first script in the "hazmap" script continuum, +// and "hazmap v3.2" is a more recent version. +// +// example usage of the auto-retirement script: +// default { +// state_entry() { +// auto_retire(); // make sure newest addition is only version of script. +// } +// } +// this script is partly based on the self-upgrading scripts from markov brodsky +// and jippen faddoul. +////////////// +auto_retire() { + string self = llGetScriptName(); // the name of this script. + list split = compute_basename_and_version(self); + if (llGetListLength(split) != 2) return; // nothing to do for this script. + string basename = llList2String(split, 0); // script name with no version attached. + string version_string = llList2String(split, 1); // the version found. + integer posn; + // find any scripts that match the basename. they are variants of this script. + for (posn = llGetInventoryNumber(INVENTORY_SCRIPT) - 1; posn >= 0; posn--) { + string curr_script = llGetInventoryName(INVENTORY_SCRIPT, posn); + if ( (curr_script != self) && (llSubStringIndex(curr_script, basename) == 0) ) { + // found a basic match at least. + list inv_split = compute_basename_and_version(curr_script); + if (llGetListLength(inv_split) == 2) { + // see if this script is more ancient. + string inv_version_string = llList2String(inv_split, 1); // the version found. + // must make sure that the retiring script is completely the identical basename; + // just matching in the front doesn't make it a relative. + if ( (llList2String(inv_split, 0) == basename) + && ((float)inv_version_string < (float)version_string) ) { + // remove script with same name from inventory that has inferior version. + llRemoveInventory(curr_script); + } + } + } + } +} +// +// separates the base script name and version number. used by auto_retire. +list compute_basename_and_version(string to_chop_up) +{ + // minimum script name is 2 characters plus a version. + integer space_v_posn; + // find the last useful space and 'v' combo. + for (space_v_posn = llStringLength(to_chop_up) - 3; + (space_v_posn >= 2) && (llGetSubString(to_chop_up, space_v_posn, space_v_posn + 1) != " v"); + space_v_posn--) { + // look for space and v but do nothing else. + } + if (space_v_posn < 2) return []; // no space found. + // now we zoom through the stuff after our beloved v character and find any evil + // space characters, which are most likely from SL having found a duplicate item + // name and not so helpfully renamed it for us. + integer indy; + for (indy = llStringLength(to_chop_up) - 1; indy > space_v_posn; indy--) { + if (llGetSubString(to_chop_up, indy, indy) == " ") { + // found one; zap it. since we're going backwards we don't need to + // adjust the loop at all. + to_chop_up = llDeleteSubString(to_chop_up, indy, indy); + } + } + string full_suffix = llGetSubString(to_chop_up, space_v_posn, -1); + // ditch the space character for our numerical check. + string chop_suffix = llGetSubString(full_suffix, 1, llStringLength(full_suffix) - 1); + // strip out a 'v' if there is one. + if (llGetSubString(chop_suffix, 0, 0) == "v") + chop_suffix = llGetSubString(chop_suffix, 1, llStringLength(chop_suffix) - 1); + // if valid floating point number and greater than zero, that works for our version. + string basename = to_chop_up; // script name with no version attached. + if ((float)chop_suffix > 0.0) { + // this is a big success right here. + basename = llGetSubString(to_chop_up, 0, -llStringLength(full_suffix) - 1); + return [ basename, chop_suffix ]; + } + // seems like we found nothing useful. + return []; +} +// +////////////// + +default { + state_entry() { if (llSubStringIndex(llGetObjectName(), "huffotronic") < 0) state real_default; } + on_rez(integer parm) { state rerun; } +} +state rerun { state_entry() { state default; } } + +state real_default +{ + state_entry() + { + auto_retire(); + llListen(EXTERNAL_TOUCH_CHANNEL, "", NULL_KEY, ""); + // we listen on our touch channel in all cases and in all states. this allows us + // to always pass along the user's touch from other prims to run the menus. + chan = (integer)llFrand(1000) + 1000; //Pick a random listen channel for the listener + if(PICTURE_ROTATION_TIMER <= 0) //Ensure the value is no less or equal 0 + PICTURE_ROTATION_TIMER = 1; + llListenRemove(listenHandle); + listenHandle = -1; + last_owner = llGetOwner(); + groupcheck = llRequestAgentData(llGetOwner(),DATA_NAME); + off(); + llOpenRemoteDataChannel(); + // fred's changes to start up in picture viewing looper. + mode = 1; // picture viewing. + pictures(); // show the pictures. + loop_image = TRUE; + llSetTimerEvent(PICTURE_ROTATION_TIMER); // keep showing new pics. + } + + on_rez(integer i) + { + llSay(0,"Welcome to FreeView - your free, open-source television!"); + llResetScript(); + } + + touch_start(integer total_number) + { + //------------------------------------------------------------------------------- + //Listen only to owner or group member. Edit this code to change access controls. + if(llDetectedKey(0) != llGetOwner() && llDetectedGroup(0) == FALSE) + return; + //------------------------------------------------------------------------------- + + menu(llDetectedKey(0)); + } + + changed(integer change) + { + if(change == CHANGED_INVENTORY) //If inventory change + { + if(mode == 1) //If picture mode + { + integer check = llGetInventoryNumber(INVENTORY_TEXTURE); + if(check != 0) + { + current_texture = 0; + display_texture(check); + } + else + { + llSetTexture(BLANK,DISPLAY_ON_SIDE); + report("No pictures found."); + } + } + else + if(mode == 2) //If video mode + if(finditem(NOTECARD) != -1) //And bookmarks notecard present + if(notecardkey != llGetInventoryKey(NOTECARD)) + tempuser = llGetNumberOfNotecardLines(NOTECARD); //Reload number of lines + } + else if(change == CHANGED_OWNER) + { + isGroup = TRUE; + last_owner = llGetOwner(); + groupcheck = llRequestAgentData(llGetOwner(),DATA_NAME); + + if(mode == 2) + { + llSay(0,"Detected change in ownership. Attempting to obtain current parcel media texture..."); + video(); + } + } + } + + listen(integer channel, string name, key id, string message) + { + if ( (channel == EXTERNAL_TOUCH_CHANNEL) && is_prefix(message, "touched")) { + // pretend we got touched by the av. + message = llDeleteSubString(message, 0, 6); + menu((key)message); + return; + } + if(message == "Pictures") + { + if(mode == 2) + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_STOP]); + pictures(); + mode = 1; + menu(id); + return; + } + if(message == "Video") + { + video(); + mode = 2; + menu(id); + return; + } + if(message == "Power off") + { + if(mode == 2) + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_UNLOAD]); + off(); + mode = 0; + return; + } + if(message == "Help") + { + llSay(0,"Help documentation is available at: http://www.slguide.com/help"); + if(isGroup) + { + if(id == NULL_KEY) + { + llSay(0,"FreeView cannot load help pages while set to group without the remote."); + llSay(0,"For further assistance, please consult: http://slguide.com/help"); + } + else + tell_remote("HELP"+(string)id+(string)XML_channel); + } + else + llLoadURL(id,"Help pages for FreeView","http://www.slguide.com?c="+(string)XML_channel+"&help=1"); + } + if(mode == 1) + { + if(message == "Browse") + { + loop_image = FALSE; + browse(id); + return; + } + if(message == "Next") + { + extendtimer(); + next(); + browse(id); + } + if(message == "Back") + { + extendtimer(); + current_texture--; + integer check = llGetInventoryNumber(INVENTORY_TEXTURE); + if(check == 0) + { + llSetTexture(BLANK,DISPLAY_ON_SIDE); + current_texture = 0; + report("No pictures found."); + return; + } + if(current_texture < 0) + current_texture = check - 1; + + display_texture(check); + + browse(id); + return; + } + if(message == "Menu") + { + menu(id); + return; + } + if(message == "Loop") + { + llSetTimerEvent(PICTURE_ROTATION_TIMER); + loop_image = TRUE; + llOwnerSay("Picture will change every "+(string)PICTURE_ROTATION_TIMER+" seconds."); + return; + } + if(message == "Unloop") + { + loop_image = FALSE; + llOwnerSay("Picture loop disabled."); + return; + } + if(message == "Fix scale") + { + llSay(0,"Setting display texture to 1,1 repeats and 0,0 offset."); + llScaleTexture(1, 1, DISPLAY_ON_SIDE); + llOffsetTexture(0, 0, DISPLAY_ON_SIDE); + return; + } + } + if(mode == 2) + { + if(channel == REMOTE_CHANNEL) + { + if(encryption == 0) + encryption = (integer)message; + llListenRemove(listenRemote); + listenRemote = -1; + llSay(0,"Remote configured ("+(string)id+")"); + } + + if(message == "TV Guide") + { + if(isGroup) + { + if(!encryption) + { + llSay(0,"** Error - This FreeView object has been deeded to group. You must use a Remote control to open the TV Guide."); + llSay(0,"You can set up the remote control from the Video -> Configuration menu. Please refer to the notecard for further assistance."); + return; + } + tell_remote((string)id+(string)XML_channel+(string)llGetOwner()); + } + else + llLoadURL(id, "Come to the Guide to Start Your Viewer Playing!", "http://slguide.com/index.php?v=" + (string)llGetKey() + "&c=" + (string)XML_channel + "&o=" + (string)llGetOwner() + "&"); + return; + } + + string header = "Video mode"+moviename+": "; + + if(message == "<< Prev") + { + notecardline--; + if(notecardline < 0) + notecardline = numberofnotecardlines - 1; + tempuser = id; + llGetNotecardLine(NOTECARD,notecardline); + return; + } + if(message == "Next >>") + { + notecardline++; + if(notecardline >= numberofnotecardlines) + notecardline = 0; + tempuser = id; + llGetNotecardLine(NOTECARD,notecardline); + return; + } + if(message == "Use") + { + if(tempurl == "** No URL specified! **") + tempurl = ""; + seturl(tempurl,id); + return; + } + + if(message == "Menu") + { + menu(id); + return; + } + if(message == "Configure") + { + config(id); + return; + } + if(message == "Bookmarks") + { + if(notecardcheck != -1) + { + llDialog(id,"Error: No valid bookmark data found in notecard '"+NOTECARD+"'.",["Menu"],chan); + return; + } + if(finditem(NOTECARD) != -1) + { + tempuser = id; + if(numberofnotecardlines < notecardline) + notecardline = 0; + llGetNotecardLine(NOTECARD,notecardline); + } + else + llDialog(id,"Error: No notecard named "+NOTECARD+" found in contents.",["Menu"],chan); + return; + } + + if(llGetLandOwnerAt(llGetPos()) != llGetOwner()) //If we do not have permissions to actually do the following functions + { + llSay(0,"Error: Cannot modify parcel media settings. "+llGetObjectName()+" is not owned by parcel owner."); + menu(id); + return; //Abort + } + + if(listenUrl != -1 && channel == 1) //Incoming data from "Set URL" command (user spoke on channel 1) + { + llListenRemove(listenUrl); + listenUrl = -1; + tempmoviename = ""; + seturl(message,id); + } + if(message == "Play") + { + report(header+"Playing"); + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_PLAY]); + return; + } + if(message == "Stop") + { + report(header+"Stopped"); + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_STOP]); + return; + } + if(message == "Pause") + { + report(header+"Paused"); + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_PAUSE]); + return; + } + if(message == "Unload") + { + report(header+"Stopped"); + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_UNLOAD]); + return; + } + if(message == "Loop") + { + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_LOOP]); + return; + } + //URL , Auto-Scale, + if(message == "Set URL") + { + report(header+"Stopped"); + listenUrl = llListen(1,"",id,""); + llDialog(id,"Please type the URL of your choice with /1 in thebegining. For example, /1 www.google.com",["Ok"],938); + return; + } + if(message == "Align ON") + { + report(header+"Stopped"); + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_AUTO_ALIGN,TRUE]); + menu(id); + return; + } + if(message == "Align OFF") + { + report(header+"Stopped"); + llParcelMediaCommandList([PARCEL_MEDIA_COMMAND_AUTO_ALIGN,FALSE]); + menu(id); + return; + } + if(message == "Set Remote") + { + llSay(0,"Configuring remote..."); + encryption = 0; + llListenRemove(listenRemote); + listenRemote = llListen(REMOTE_CHANNEL,"","",""); + llSay(REMOTE_CHANNEL,"SETUP"); + } + } + } + + dataserver(key queryid, string data) + { + if(queryid == groupcheck) //Test if object is deeded to group + { + groupcheck = NULL_KEY; + isGroup = FALSE; + return; + } + + if(queryid == tempuser) //If just checking number of notecard lines + { + numberofnotecardlines = (integer)data; + notecardkey = llGetInventoryKey(NOTECARD); + notecardcheck = 0; + llGetNotecardLine(NOTECARD,notecardcheck); + return; + } + if(notecardcheck != -1) + { + if(data != EOF) + { + if(data == "") + { + notecardcheck++; + llGetNotecardLine(NOTECARD,notecardcheck); + } + else + { + notecardcheck = -1; + return; + } + } + else + return; + } + + if(data == "" && notecardline < numberofnotecardlines) //If user just pressed "enter" in bookmarks, skip + { + notecardline++; + llGetNotecardLine(NOTECARD,notecardline); + return; + } + + if(data == EOF) + { + notecardline = 0; + llGetNotecardLine(NOTECARD,notecardline); + return; + } + list parsed = llParseString2List(data,["|","| "," |"," | "],[]); //Ensure no blank spaces before "http://". + string name = llList2String(parsed,0); + tempurl = llList2String(parsed,1); + if(tempurl == "") + tempurl = "** No URL specified! **"; + + tempmoviename = name; + + llDialog(tempuser,"Bookmarks notecard ("+(string)(notecardline+1)+"/"+(string)numberofnotecardlines+")\n"+name+" ("+mediatype(llList2String(llParseString2List(tempurl,["."],[]),-1))+")\n"+tempurl,["<< Prev","Use","Next >>","Menu"],chan); + } + + remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval) + { + if (type == REMOTE_DATA_CHANNEL) + { + XML_channel = channel; + } + else if(type == REMOTE_DATA_REQUEST) + { + list media_info = llParseString2List(sval, ["|"], []); + tempmoviename = llList2String(media_info,0); + seturl(llList2String(media_info,1),NULL_KEY); + llRemoteDataReply(channel, message_id, sval, 1); + } + } + + timer() + { + if(llGetTime() > listenTimer) //If listener time expired... + { + llListenRemove(listenHandle); //Remove listeneres. + llListenRemove(listenUrl); + llListenRemove(listenRemote); + listenHandle = -1; + listenUrl = -1; + listenRemote = -1; + listenTimer = -1; + if(loop_image == FALSE || mode != 1) //If we're not looping pictures or are in picture mode at all + llSetTimerEvent(0.0); //Remove timer + } + + if(loop_image == TRUE && mode == 1) //If we're looping pictures and and we're in picture mode... + next(); //Next picture + } +} +