Jump to content

Cookie Bertone

Resident
  • Posts

    17
  • Joined

  • Last visited

Reputation

20 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I want to display the height of the sun so I can get a light to switch on and off automatically. I can get the light to work fine and it switches on when it gets dark but I want it to tell me what the sun height is each time the timer expires and for some probably silly reason it tells me there is a type mismatch. I have defined: vector sun_position; float sun_height; I then get the height by doing this: sun_position = llGetSunDirection(); sun_height = sun_position.z; And then I try to get it to tell me the height: llOwnerSay("Sun height is: "+sun_height); Sorry for asking what I consider to be a noob question but I have spent a long time not using LSL and the answer to this question has escaped me.
  2. I am sure I set some sort of rule to the items that they could not be resold or transferred further. I would have to log back in to see what settings I actually specified though.
  3. Hello. When you select update on the radio it queries the server with the radio model and version number. The server checks the details it received against what is listed as the current version in the server notecard. If the version in the server notecard is newer than the radio that sent the query then it sends the radio owner the latest version of the radio stored in it the server contents. I had a version in alpha that just updated the script in the radio but I never seemed to get the time to finish it.
  4. Good question. I am sure I had some notes about that somewhere. I will try to dig it out.
  5. Some time ago (2007) I developed a radio script for Second Life that I sold in my own store. When I closed the store in 2010 (since reopened) I decided to give away the script for reuse by any resident and it was posted in the old forums. To make it easier to find I am now posting it again here, although slightly updated to fix an glitch caused by recent (June 2017) changes to the llHTTPRequest command. I don't ask for any L$ in return but if you use it, and especially sell it, please credit me. Thanks. Below is the radio script, a copy of the notecard, a copy of the server script and a copy of the server notecard. RADIO SCRIPT // Bertone Audio Parcel Music Player by Cookie Bertone // last modified 22 July 2017 // previous minor revision 28 february 2016 // previous major revision 17 May 2010 // if instructions are renamed make change in this script also!! string version = "165A"; // Version number of this item string gName = "channels"; // name of the notecard that holds the channel list integer gLine = 0; // current line number, set to 0 so it starts at the beginning key gQueryID; // id used to identify dataserver queries list GenreElementList = []; integer populating_list = TRUE; string nPlaying = "Unknown"; integer FloatText = TRUE; integer ShowURL = FALSE; // start 150 extras list trackpulllist = []; float gap = 5.0; float counter = 0.0; string nPlayingURL = "NOT_SET"; string TrackElementHold = ""; integer nPlayingSHOW = TRUE; // end 150 extras // start 160 extras key gkOwner; key serverID = "d48e17c5-e8f6-1588-b57f-9d28423de917@lsl.secondlife.com"; integer InstalledTextures = 0; // end 160 extras key menuitem; // id used to get menu selection list MainMenu = ["tuner", "options", "off"]; list OptionsMenu = ["instructions", "texton", "textoff", "show url", "playing", "list", "reset", "update", "main menu"]; string tuner_dialog = "\nBAS Parcel Music Player\nBertone Audio Systems, Bilogorac (23, 196, 68)\n\nMake a selection or press 'ignore' to close this dialog box."; string chatline = "------------------------------------------------------"; list first_menu; list second_menu; list third_menu; list fourth_menu; list fifth_menu; list sixth_menu; list seventh_menu; list eigth_menu; list ninth_menu; string lastpage = "Page 9"; default { // when device is first rezzed it will reset the script on_rez(integer start_param) { llSay(0, "Player installed. Setting defaults."); llResetScript(); llSay(0, "Defaults set."); } // when script is started or restarted it will display some details about the device, // tell it to read the data file, start the listen and set the text on the device state_entry() { llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); llSay(978, "reset"); llSay(0, "\n\n" +chatline+ "\nBAS PMP (Parcel Music Player) " +version+ "\nScript written by Cookie Bertone\nBertone Audio Systems, Bilogorac (23, 196, 68)\n" +chatline+ "\n\nLoading channels.\nPlease wait for 'Ready'.\n\n"); llSetParcelMusicURL(""); gQueryID = llGetNotecardLine(gName, gLine); // request first line llListen(87, "", NULL_KEY, ""); // listen for request on channel 87 llSetText("Bertone Audio System " +version, <0.0,1.0,1.0>, .5); llSetTimerEvent(gap); // Activate the timer listener every X seconds } // when the device is touched it will display the main menu touch_start(integer touchNumber) { llDialog(llDetectedKey(0), tuner_dialog, MainMenu, 87); } listen(integer channel, string name, key id, string message) { integer index = llListFindList(GenreElementList, [message]); if (index != -1) { llSay(0, "Found "+message+" in channel list. Setting channel."); llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); gQueryID = llGetNotecardLine(gName, index); } else if (message=="list") { llSay(0, "Listing possible genres:"); integer x; integer length=llGetListLength(GenreElementList); for (x=0; x<length; x++) { llSay(0,llList2String(GenreElementList,x)); } } else if (message=="playing") { llSay(0, "Now playing: "+nPlaying); } else if (message=="texton") { FloatText = TRUE; nPlayingSHOW = TRUE; llSetText("Now playing: "+nPlaying+".", <0.0,1.0,1.0>, .5); } else if (message=="textoff") { FloatText = FALSE; nPlayingSHOW = FALSE; llSetText(" ", <0.0,1.0,1.0>, .5); } else if (message=="show url") { ShowURL = TRUE; } else if (message=="XXpictureXX") { integer InstalledTextures = llGetInventoryNumber(INVENTORY_TEXTURE); if (InstalledTextures == 1) { string TextureName = llGetInventoryName(INVENTORY_TEXTURE, 0); llSay (0,"Texture found: " +TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures > 1) { float RandTexture = llFrand(InstalledTextures); integer TextureChoice = (integer)RandTexture; string TextureName = llGetInventoryName(INVENTORY_TEXTURE, TextureChoice); llSay (0,"Choosing a random texture: "+TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures < 1) { llSay(0,"There are no textures installed."); } } else if (message=="instructions") { llGiveInventory(id, "radio instructions (16)"); } else if (message=="reset") { llSay(0, "Resetting."); llResetScript(); } else if (message=="options") { llDialog(id, tuner_dialog, OptionsMenu, 87); } else if (message=="update") { llOwnerSay("Contacting update server."); llEmail(serverID,"Update Request",llGetObjectName() + ":" + version + "|" + (string)llGetOwner()); } else if (message=="off") { llSay(0, "System Off"); llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(978, "red"); llSetParcelMusicURL(""); //next two lines new for v1.5, these reset variables to stop it displaying track names when switched off nPlayingURL = "NOT_SET"; TrackElementHold = ""; if (FloatText = TRUE) { llSetText("Bertone Audio System " +version+ " OFF", <0.0,1.0,1.0>, .5); } } else if (message=="tuner") { if(llGetListLength(GenreElementList) > 80) { llSay(0, "Only the first 80 channels will be displayed in the menu."); } if(llGetListLength(GenreElementList) > 12) { // remember that a list starts at 0, not 1 // all the menus except the first one are set here so the following if statements can change them if necessary second_menu = ["Page 1", "main menu", "Page 3"] + llList2List(GenreElementList, 9, 17); third_menu = ["Page 2", "main menu", "Page 4"] + llList2List(GenreElementList, 18, 26); fourth_menu = ["Page 3", "main menu", "Page 5"] + llList2List(GenreElementList, 27, 35); fifth_menu = ["Page 4", "main menu", "Page 6"] + llList2List(GenreElementList, 36, 44); sixth_menu = ["Page 5", "main menu", "Page 7"] + llList2List(GenreElementList, 45, 53); seventh_menu = ["Page 6", "main menu", "Page 8"] + llList2List(GenreElementList, 54, 62); eigth_menu = ["Page 7", "main menu", "Page 9"] + llList2List(GenreElementList, 63, 71); ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); // this bit sets which page will be the last so no empty menus are displayed if(llGetListLength(GenreElementList) < 81) { ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); lastpage = "Page 9"; } if(llGetListLength(GenreElementList) < 72) { eigth_menu = ["Page 7", "main menu", "Page 1"] + llList2List(GenreElementList, 63, 71); lastpage = "Page 8"; } if(llGetListLength(GenreElementList) < 63) { seventh_menu = ["Page 6", "main menu", "Page 1"] + llList2List(GenreElementList, 54, 62); lastpage = "Page 7"; } if(llGetListLength(GenreElementList) < 54) { sixth_menu = ["Page 5", "main menu", "Page 1"] + llList2List(GenreElementList, 45, 53); lastpage = "Page 6"; } if(llGetListLength(GenreElementList) < 45) { fifth_menu = ["Page 4", "main menu", "Page 1"] + llList2List(GenreElementList, 36, 44); lastpage = "Page 5"; } if(llGetListLength(GenreElementList) < 36) { fourth_menu = ["Page 3", "main menu", "Page 1"] + llList2List(GenreElementList, 27, 35); lastpage = "Page 4"; } if(llGetListLength(GenreElementList) < 27) { third_menu = ["Page 2", "main menu", "Page 1"] + llList2List(GenreElementList, 18, 26); lastpage = "Page 3"; } if(llGetListLength(GenreElementList) < 18) { second_menu = ["Page 1", "main menu", "Page 1"] + llList2List(GenreElementList, 9, 17); lastpage = "Page 2"; } // the first menu is set here 'after' the last page has been defined (above) then the first dialog is displayed first_menu = [lastpage, "main menu", "Page 2"] + llList2List(GenreElementList, 0, 8); llDialog(id, tuner_dialog, first_menu, 87); } else { // if there are less than 12 items in the menu it displays this dialog that doesn't need the page buttons llDialog(id, tuner_dialog, GenreElementList, 87); } } else if(message=="Page 1") { llDialog(id, tuner_dialog, first_menu, 87); } else if(message=="Page 2") { llDialog(id, tuner_dialog, second_menu, 87); } else if(message=="Page 3") { llDialog(id, tuner_dialog, third_menu, 87); } else if(message=="Page 4") { llDialog(id, tuner_dialog, fourth_menu, 87); } else if(message=="Page 5") { llDialog(id, tuner_dialog, fifth_menu, 87); } else if(message=="Page 6") { llDialog(id, tuner_dialog, sixth_menu, 87); } else if(message=="Page 7") { llDialog(id, tuner_dialog, seventh_menu, 87); } else if(message=="Page 8") { llDialog(id, tuner_dialog, eigth_menu, 87); } else if(message=="Page 9") { llDialog(id, tuner_dialog, ninth_menu, 87); } else if(message=="main menu") { llDialog(id, tuner_dialog, MainMenu, 87); } else { llSay(0, "Sorry. I couldn't find a station or command with the ID: "+message); } } // timer section is new for version 1.5 timer() { //llHTTPRequest(nPlayingURL+"/7.html HTTP/1.0\nUser-Agent: XML Getter (Mozilla Compatible)\n\n",[],""); //llHTTPRequest(nPlayingURL+"/7.html HTTP/1.1\nUser-Agent:Mozilla\n\n",[],""); if (nPlayingURL != "NOT_SET") { llHTTPRequest(nPlayingURL+"/7.html", [HTTP_USER_AGENT, "BAS_"+version+" (Mozilla Compatible)"],""); } } // http_response section is new for version 1.5 http_response(key trackid, integer status, list metadata, string trackbody) { list TrackPullList = llParseString2List(trackbody,[","],[]); // takes the http result and turns it into a list string TrackElement = llList2String(TrackPullList,6); // takes the sixth item out of the http result list TrackElement = llDeleteSubString(TrackElement, -14, -1); // strips off the html junk text at the end if (nPlayingSHOW == TRUE) { if (TrackElementHold != TrackElement) { llSay(0, "Now playing: " + TrackElement + "."); // displays the result TrackElementHold = TrackElement; } } } dataserver(key query_id, string data) { if (populating_list == TRUE) // first pass through is to build up a list of Genre Names { if (data != EOF) { list StationList = llParseString2List(data,[","],[]); string GenreElement = llList2String(StationList,2); GenreElementList = GenreElementList + [llList2String(StationList,2)]; ++gLine; // increase line count by 1 gQueryID = llGetNotecardLine(gName, gLine); // request next line } else { populating_list = FALSE; llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(0, "\n\nReady.\nTouch player to begin...\n\n"); } } else { list StationList = llParseString2List(data,[","],[]); // converts the line taken into a list string URLElement = llList2String(StationList,0); // grab the URL llSetParcelMusicURL(URLElement); llSetLinkColor(2, <0.9, 0.9, 0.9>, ALL_SIDES); llSay(978, "blue"); string StationElement = llList2String(StationList,1); if (ShowURL == TRUE) { llSay(0, "\n\nNow playing: "+StationElement+". ("+URLElement+"\n)"); } else { llSay(0, "\n\nNow playing: "+StationElement+".\n"); } if (FloatText == TRUE) { //llSay(0,"DIAGNOSTIC: FloatText is true"); llSetText("Now playing: "+StationElement+".", <0.0,1.0,1.0>, .5); } nPlaying = StationElement; // this holds the station name for use in other sections nPlayingURL = URLElement; // this holds the station URL for use in other sections } } } RADIO 'CHANNELS' NOTE CARD I have left a load of channels here for reference. They can be replaced with any compatible stream. http://ice1.somafm.com/groovesalad-128-mp3,Groove Salad ~ Soma FM,Groove Salad, ~ A nicely chilled plate of ambient downtempo beats and grooves http://ice1.somafm.com/dronezone-128-mp3,Drone Zone ~ Soma FM,Drone Zone, ~ Served best chilled and safe with most medications. Atmospheric textures with minimal beats http://ice1.somafm.com/indiepop-128-mp3,Indie Pop Rocks ~ Soma FM,Indie Pop, ~ New and classic favorite indie pop tracks http://ice1.somafm.com/lush-128-mp3,Lush ~ Soma FM,Lush, ~ Sensuous and mellow vocals with an electronic influence http://ice1.somafm.com/secretagent-128-mp3,Secret Agent ~ Soma FM,Secret Agent, ~ The soundtrack for your stylish mysterious dangerous life. For Spies and PIs too! http://ice1.somafm.com/spacestation-128-mp3,Space Station Soma ~ Soma FM,Space Station Soma, ~ Tune in turn on space out. Spaced-out ambient and mid-tempo electronica http://ice1.somafm.com/u80s-128-mp3,Underground 80s ~ Soma FM,Underground 80s, ~ Early 80s UK Synthpop and a bit of New Wave http://ice1.somafm.com/deepspaceone-128-mp3,Deep Spare One ~ Soma FM,Deep Space One, ~ Deep ambient electronic experimental and space music. For inner and outer space exploration http://ice1.somafm.com/beatblender-128-mp3,Beat Blender ~ Soma FM,Beat Blender, ~ A late night blend of deep-house and downtempo chill http://ice1.somafm.com/suburbsofgoa-128-mp3,Suburbs of Goa ~ Soma FM,Suburbs of Goa, ~ Desi-influenced Asian world beats and beyond http://ice1.somafm.com/bootliquor-128-mp3,Boot Liquor ~ Soma FM,Boot Liquor, ~ Americana Roots music for Cowhands Cowpokes and Cowtippers http://ice1.somafm.com/sonicuniverse-128-mp3,Sonic Universe ~ Soma FM,Sonic Universe, ~ Transcending the world of jazz with eclectic avant-garde takes on traditionhttp://ice1.somafm.com/poptron-128-mp3,PopTron ~ Soma FM,PopTron, ~ Electropop and indie dance rock with sparkle and pop http://ice1.somafm.com/folkfwd-128-mp3,Folk Forward ~ Soma FM,Folk Forward, ~ Indie Folk, Alt-folk and the occasional folk classics http://ice1.somafm.com/defcon-128-mp3,DEF CON Radio ~ Soma FM,DEF CON Radio, ~ Music for Hacking. The DEF CON Year-Round Channel http://ice1.somafm.com/seventies-128-mp3,Left Coast 70s ~ Soma FM,Left Coaast 70s, ~ Mellow album rock from the Seventies. Yacht friendly http://ice1.somafm.com/bagel-128-mp3,BAGeL Radio ~ Soma FM,BAGeL Radio, ~ What alternative rock radio should sound like http://ice1.somafm.com/thetrip-128-mp3,The Trip ~ Soma FM,The Trip, ~ Progressive house / trance. Tip top tunes http://ice1.somafm.com/fluid-128-mp3,Fluid ~ Soma FM,Fluid, ~ Drown in the electronic sound of instrumental hiphop future soul and liquid trap http://ice1.somafm.com/thistle-128-mp3,Thistle Radio ~ Soma FM,Thistle Radio, ~ Exploring music from Celtic roots and branches http://ice1.somafm.com/illstreet-128-mp3,Illinois Street Lounge ~ Soma FM,Illinois Street Lounge, ~ Classic bachelor pad playful exotica and vintage music of tomorrow http://ice1.somafm.com/7soul-128-mp3,Seven Inch Soul ~ Soma FM,Seven Inch Soul, ~ Vintage soul tracks from the original 45 RPM vinyl http://ice1.somafm.com/cliqhop-128-mp3,cliqhop idm ~ Soma FM,cliqhop idm, ~ Blips'n'beeps backed mostly w/beats. Intelligent Dance Music http://ice1.somafm.com/digitalis-128-mp3,Digitalis ~ Soma FM,Digitalis, Digitally affected analog rock to calm the agitated heart http://ice1.somafm.com/missioncontrol-128-mp3,Mission Control ~ Soma FM,Mission Control, ~ Celebrating NASA and Space Explorers everywhere http://ice1.somafm.com/dubstep-128-mp3,Dub Step Beyond ~ Soma FM,Dub Step Beyond, ~ Dubstep Dub and Deep Bass. May damage speakers at high volume http://ice1.somafm.com/doomed-128-mp3,Doomed ~ Soma FM,Doomed, ~ Dark industrial/ambient music for tortured souls http://ice1.somafm.com/brfm-128-mp3,Black Rock FM ~ Soma FM,Black Rock FM, ~ From the Playa to the world, back for the 2015 Burning Man festival http://ice1.somafm.com/covers-128-mp3,Covers ~ Soma FM,Covers, ~ Just covers. Songs you know by artists you don't. We've got you covered http://ice1.somafm.com/sf1033-128-mp3,SF 10-33 ~ Soma FM,SF 10-33, ~ Ambient music mixed with the sounds of San Francisco public safety radio traffic http://ice1.somafm.com/earwaves-128-mp3,Earwaves ~ Soma FM,Earwaves, ~ Spanning the history of electronic and experimental music from the early pioneers to the latest innovators http://ice1.somafm.com/metal-128-mp3,Metal Detector ~ Soma FM,Metal Detector, ~ From black to doom / prog to sludge / thrash to post / stoner to crossover / punk to industrial UPDATE SERVER SCRIPT Note, this is maybe only 10% my own work and is based on another script for which I have long since lost the details where I got it from. If you find the original author please let me know so I can credit them. // CTD Updater Script // Server UUID:debccf52-3ec9-0428-4f4f-dcc533199b30 // NOTE: This is an area to keep the UUID in the notes for reference. key serverID; string cardName = "Updates"; // Name of the Notecard with all of the Item:Version info string company = "Bertone Audio"; // Name of the company key lineTotalID; key locateID; integer lineCurrent = 0; // Line Offset integer lineTotal; // Line Offset string noteLine; string noteFront; string noteBack; string item; string version; key user; float watchdog = 10.0; integer InUse = FALSE; default { state_entry() { llWhisper(0,llGetKey()); llSetTimerEvent(5.0); lineTotalID = llGetNumberOfNotecardLines(cardName); } touch_start(integer total_number) { llResetScript(); } timer() { llGetNextEmail("",""); } email(string time, string address, string subject, string body, integer remaining) { llWhisper(0,"Received Request..."); if (InUse == FALSE) { InUse = TRUE; llSetText("In Use...",<1,1,1>,1.0); string message = llDeleteSubString(body, 0, llSubStringIndex(body, "\n\n") + 1); integer itemMark = llSubStringIndex(message,":"); integer verMark = llSubStringIndex(message,"|"); item = llGetSubString(message,0,(itemMark - 1)); version = llGetSubString(message,(itemMark + 1),(verMark - 1)); user = (key)llGetSubString(message,(verMark + 1), -1); llWhisper(0,"Item: " + item); llWhisper(0,"Version: " + version); llWhisper(0,"User: " + llKey2Name(user)); lineCurrent = 0; locateID = llGetNotecardLine(cardName,0); } } dataserver(key queryID, string data) { if (queryID == lineTotalID) { lineTotal = (integer)data; llInstantMessage(llGetOwner(),"Found " + (string)lineTotal + " items on update server."); } if (locateID == queryID) { if (data != EOF) { noteLine = data; integer marker = llSubStringIndex(noteLine,":"); if (marker != -1) { lineCurrent += 1; noteFront = llGetSubString(noteLine,0,( marker - 1 )); noteBack = llGetSubString(noteLine,( marker + 1 ), -1); } if (marker == -1) { llInstantMessage(llGetOwner(),"Error with Update Server Inventory line: " + (string)lineCurrent); } if (noteFront != item) locateID = llGetNotecardLine(cardName,lineCurrent); if (noteFront == item) { if ((float)noteBack > (float)version) { llGiveInventory(user,item); llInstantMessage(user,"Sending you the updated version of: " + item); } if ((float)noteBack < (float)version) llInstantMessage(user,"There was an error with the update of your " + item + ", please contact " + llKey2Name(llGetOwner())); if ((float)noteBack == (float)version) llInstantMessage(user,"Your " + item + " by " + company + " is up to date."); InUse = FALSE; llSetText("",<1,1,1>,0.0); } } } if (data == EOF) { InUse = FALSE; llSetText("",<1,1,1>,0.0); llInstantMessage(llGetOwner(),"Update Server Hit EOF on Update List"); } } } UPDATE SERVER NOTE CARD Bertone Audio - Classic Radio:165A Bertone Audio - Hidden Radio:165A Bertone Audio - Tube Radio:165A Bertone Audio - Pyramid Radio:165A Bertone Audio - Cube Radio:165A INSTRUCTIONS NOTE CARD
  6. Some time ago (2007) I developed a radio script for Second Life that I sold in my own store. When I closed the store in 2010 (since reopened) I decided to give away the script for reuse by any resident and it was posted in the old forums. To make it easier to find I am now posting it again here, although slightly updated to fix an glitch caused by recent (June 2017) changes to the llHTTPRequest command. I don't ask for any L$ in return but if you use it, and especially sell it, please credit me. Thanks. Below is the radio script, a copy of the notecard, a copy of the server script and a copy of the server notecard. RADIO SCRIPT // Bertone Audio Parcel Music Player by Cookie Bertone // last modified 22 July 2017 // previous minor revision 28 february 2016 // previous major revision 17 May 2010 // if instructions are renamed make change in this script also!! string version = "165A"; // Version number of this item string gName = "channels"; // name of the notecard that holds the channel list integer gLine = 0; // current line number, set to 0 so it starts at the beginning key gQueryID; // id used to identify dataserver queries list GenreElementList = []; integer populating_list = TRUE; string nPlaying = "Unknown"; integer FloatText = TRUE; integer ShowURL = FALSE; // start 150 extras list trackpulllist = []; float gap = 5.0; float counter = 0.0; string nPlayingURL = "NOT_SET"; string TrackElementHold = ""; integer nPlayingSHOW = TRUE; // end 150 extras // start 160 extras key gkOwner; key serverID = "d48e17c5-e8f6-1588-b57f-9d28423de917@lsl.secondlife.com"; integer InstalledTextures = 0; // end 160 extras key menuitem; // id used to get menu selection list MainMenu = ["tuner", "options", "off"]; list OptionsMenu = ["instructions", "texton", "textoff", "show url", "playing", "list", "reset", "update", "main menu"]; string tuner_dialog = "\nBAS Parcel Music Player\nBertone Audio Systems, Bilogorac (23, 196, 68)\n\nMake a selection or press 'ignore' to close this dialog box."; string chatline = "------------------------------------------------------"; list first_menu; list second_menu; list third_menu; list fourth_menu; list fifth_menu; list sixth_menu; list seventh_menu; list eigth_menu; list ninth_menu; string lastpage = "Page 9"; default { // when device is first rezzed it will reset the script on_rez(integer start_param) { llSay(0, "Player installed. Setting defaults."); llResetScript(); llSay(0, "Defaults set."); } // when script is started or restarted it will display some details about the device, // tell it to read the data file, start the listen and set the text on the device state_entry() { llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); llSay(978, "reset"); llSay(0, "\n\n" +chatline+ "\nBAS PMP (Parcel Music Player) " +version+ "\nScript written by Cookie Bertone\nBertone Audio Systems, Bilogorac (23, 196, 68)\n" +chatline+ "\n\nLoading channels.\nPlease wait for 'Ready'.\n\n"); llSetParcelMusicURL(""); gQueryID = llGetNotecardLine(gName, gLine); // request first line llListen(87, "", NULL_KEY, ""); // listen for request on channel 87 llSetText("Bertone Audio System " +version, <0.0,1.0,1.0>, .5); llSetTimerEvent(gap); // Activate the timer listener every X seconds } // when the device is touched it will display the main menu touch_start(integer touchNumber) { llDialog(llDetectedKey(0), tuner_dialog, MainMenu, 87); } listen(integer channel, string name, key id, string message) { integer index = llListFindList(GenreElementList, [message]); if (index != -1) { llSay(0, "Found "+message+" in channel list. Setting channel."); llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); gQueryID = llGetNotecardLine(gName, index); } else if (message=="list") { llSay(0, "Listing possible genres:"); integer x; integer length=llGetListLength(GenreElementList); for (x=0; x<length; x++) { llSay(0,llList2String(GenreElementList,x)); } } else if (message=="playing") { llSay(0, "Now playing: "+nPlaying); } else if (message=="texton") { FloatText = TRUE; nPlayingSHOW = TRUE; llSetText("Now playing: "+nPlaying+".", <0.0,1.0,1.0>, .5); } else if (message=="textoff") { FloatText = FALSE; nPlayingSHOW = FALSE; llSetText(" ", <0.0,1.0,1.0>, .5); } else if (message=="show url") { ShowURL = TRUE; } else if (message=="XXpictureXX") { integer InstalledTextures = llGetInventoryNumber(INVENTORY_TEXTURE); if (InstalledTextures == 1) { string TextureName = llGetInventoryName(INVENTORY_TEXTURE, 0); llSay (0,"Texture found: " +TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures > 1) { float RandTexture = llFrand(InstalledTextures); integer TextureChoice = (integer)RandTexture; string TextureName = llGetInventoryName(INVENTORY_TEXTURE, TextureChoice); llSay (0,"Choosing a random texture: "+TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures < 1) { llSay(0,"There are no textures installed."); } } else if (message=="instructions") { llGiveInventory(id, "radio instructions (16)"); } else if (message=="reset") { llSay(0, "Resetting."); llResetScript(); } else if (message=="options") { llDialog(id, tuner_dialog, OptionsMenu, 87); } else if (message=="update") { llOwnerSay("Contacting update server."); llEmail(serverID,"Update Request",llGetObjectName() + ":" + version + "|" + (string)llGetOwner()); } else if (message=="off") { llSay(0, "System Off"); llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(978, "red"); llSetParcelMusicURL(""); //next two lines new for v1.5, these reset variables to stop it displaying track names when switched off nPlayingURL = "NOT_SET"; TrackElementHold = ""; if (FloatText = TRUE) { llSetText("Bertone Audio System " +version+ " OFF", <0.0,1.0,1.0>, .5); } } else if (message=="tuner") { if(llGetListLength(GenreElementList) > 80) { llSay(0, "Only the first 80 channels will be displayed in the menu."); } if(llGetListLength(GenreElementList) > 12) { // remember that a list starts at 0, not 1 // all the menus except the first one are set here so the following if statements can change them if necessary second_menu = ["Page 1", "main menu", "Page 3"] + llList2List(GenreElementList, 9, 17); third_menu = ["Page 2", "main menu", "Page 4"] + llList2List(GenreElementList, 18, 26); fourth_menu = ["Page 3", "main menu", "Page 5"] + llList2List(GenreElementList, 27, 35); fifth_menu = ["Page 4", "main menu", "Page 6"] + llList2List(GenreElementList, 36, 44); sixth_menu = ["Page 5", "main menu", "Page 7"] + llList2List(GenreElementList, 45, 53); seventh_menu = ["Page 6", "main menu", "Page 8"] + llList2List(GenreElementList, 54, 62); eigth_menu = ["Page 7", "main menu", "Page 9"] + llList2List(GenreElementList, 63, 71); ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); // this bit sets which page will be the last so no empty menus are displayed if(llGetListLength(GenreElementList) < 81) { ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); lastpage = "Page 9"; } if(llGetListLength(GenreElementList) < 72) { eigth_menu = ["Page 7", "main menu", "Page 1"] + llList2List(GenreElementList, 63, 71); lastpage = "Page 8"; } if(llGetListLength(GenreElementList) < 63) { seventh_menu = ["Page 6", "main menu", "Page 1"] + llList2List(GenreElementList, 54, 62); lastpage = "Page 7"; } if(llGetListLength(GenreElementList) < 54) { sixth_menu = ["Page 5", "main menu", "Page 1"] + llList2List(GenreElementList, 45, 53); lastpage = "Page 6"; } if(llGetListLength(GenreElementList) < 45) { fifth_menu = ["Page 4", "main menu", "Page 1"] + llList2List(GenreElementList, 36, 44); lastpage = "Page 5"; } if(llGetListLength(GenreElementList) < 36) { fourth_menu = ["Page 3", "main menu", "Page 1"] + llList2List(GenreElementList, 27, 35); lastpage = "Page 4"; } if(llGetListLength(GenreElementList) < 27) { third_menu = ["Page 2", "main menu", "Page 1"] + llList2List(GenreElementList, 18, 26); lastpage = "Page 3"; } if(llGetListLength(GenreElementList) < 18) { second_menu = ["Page 1", "main menu", "Page 1"] + llList2List(GenreElementList, 9, 17); lastpage = "Page 2"; } // the first menu is set here 'after' the last page has been defined (above) then the first dialog is displayed first_menu = [lastpage, "main menu", "Page 2"] + llList2List(GenreElementList, 0, 8); llDialog(id, tuner_dialog, first_menu, 87); } else { // if there are less than 12 items in the menu it displays this dialog that doesn't need the page buttons llDialog(id, tuner_dialog, GenreElementList, 87); } } else if(message=="Page 1") { llDialog(id, tuner_dialog, first_menu, 87); } else if(message=="Page 2") { llDialog(id, tuner_dialog, second_menu, 87); } else if(message=="Page 3") { llDialog(id, tuner_dialog, third_menu, 87); } else if(message=="Page 4") { llDialog(id, tuner_dialog, fourth_menu, 87); } else if(message=="Page 5") { llDialog(id, tuner_dialog, fifth_menu, 87); } else if(message=="Page 6") { llDialog(id, tuner_dialog, sixth_menu, 87); } else if(message=="Page 7") { llDialog(id, tuner_dialog, seventh_menu, 87); } else if(message=="Page 8") { llDialog(id, tuner_dialog, eigth_menu, 87); } else if(message=="Page 9") { llDialog(id, tuner_dialog, ninth_menu, 87); } else if(message=="main menu") { llDialog(id, tuner_dialog, MainMenu, 87); } else { llSay(0, "Sorry. I couldn't find a station or command with the ID: "+message); } } // timer section is new for version 1.5 timer() { //llHTTPRequest(nPlayingURL+"/7.html HTTP/1.0\nUser-Agent: XML Getter (Mozilla Compatible)\n\n",[],""); //llHTTPRequest(nPlayingURL+"/7.html HTTP/1.1\nUser-Agent:Mozilla\n\n",[],""); if (nPlayingURL != "NOT_SET") { llHTTPRequest(nPlayingURL+"/7.html", [HTTP_USER_AGENT, "BAS_"+version+" (Mozilla Compatible)"],""); } } // http_response section is new for version 1.5 http_response(key trackid, integer status, list metadata, string trackbody) { list TrackPullList = llParseString2List(trackbody,[","],[]); // takes the http result and turns it into a list string TrackElement = llList2String(TrackPullList,6); // takes the sixth item out of the http result list TrackElement = llDeleteSubString(TrackElement, -14, -1); // strips off the html junk text at the end if (nPlayingSHOW == TRUE) { if (TrackElementHold != TrackElement) { llSay(0, "Now playing: " + TrackElement + "."); // displays the result TrackElementHold = TrackElement; } } } dataserver(key query_id, string data) { if (populating_list == TRUE) // first pass through is to build up a list of Genre Names { if (data != EOF) { list StationList = llParseString2List(data,[","],[]); string GenreElement = llList2String(StationList,2); GenreElementList = GenreElementList + [llList2String(StationList,2)]; ++gLine; // increase line count by 1 gQueryID = llGetNotecardLine(gName, gLine); // request next line } else { populating_list = FALSE; llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(0, "\n\nReady.\nTouch player to begin...\n\n"); } } else { list StationList = llParseString2List(data,[","],[]); // converts the line taken into a list string URLElement = llList2String(StationList,0); // grab the URL llSetParcelMusicURL(URLElement); llSetLinkColor(2, <0.9, 0.9, 0.9>, ALL_SIDES); llSay(978, "blue"); string StationElement = llList2String(StationList,1); if (ShowURL == TRUE) { llSay(0, "\n\nNow playing: "+StationElement+". ("+URLElement+"\n)"); } else { llSay(0, "\n\nNow playing: "+StationElement+".\n"); } if (FloatText == TRUE) { //llSay(0,"DIAGNOSTIC: FloatText is true"); llSetText("Now playing: "+StationElement+".", <0.0,1.0,1.0>, .5); } nPlaying = StationElement; // this holds the station name for use in other sections nPlayingURL = URLElement; // this holds the station URL for use in other sections } } } RADIO 'CHANNELS' NOTE CARD I have left a load of channels here for reference. They can be replaced with any compatible stream. http://ice1.somafm.com/groovesalad-128-mp3,Groove Salad ~ Soma FM,Groove Salad, ~ A nicely chilled plate of ambient downtempo beats and grooves http://ice1.somafm.com/dronezone-128-mp3,Drone Zone ~ Soma FM,Drone Zone, ~ Served best chilled and safe with most medications. Atmospheric textures with minimal beats http://ice1.somafm.com/indiepop-128-mp3,Indie Pop Rocks ~ Soma FM,Indie Pop, ~ New and classic favorite indie pop tracks http://ice1.somafm.com/lush-128-mp3,Lush ~ Soma FM,Lush, ~ Sensuous and mellow vocals with an electronic influence http://ice1.somafm.com/secretagent-128-mp3,Secret Agent ~ Soma FM,Secret Agent, ~ The soundtrack for your stylish mysterious dangerous life. For Spies and PIs too! http://ice1.somafm.com/spacestation-128-mp3,Space Station Soma ~ Soma FM,Space Station Soma, ~ Tune in turn on space out. Spaced-out ambient and mid-tempo electronica http://ice1.somafm.com/u80s-128-mp3,Underground 80s ~ Soma FM,Underground 80s, ~ Early 80s UK Synthpop and a bit of New Wave http://ice1.somafm.com/deepspaceone-128-mp3,Deep Spare One ~ Soma FM,Deep Space One, ~ Deep ambient electronic experimental and space music. For inner and outer space exploration http://ice1.somafm.com/beatblender-128-mp3,Beat Blender ~ Soma FM,Beat Blender, ~ A late night blend of deep-house and downtempo chill http://ice1.somafm.com/suburbsofgoa-128-mp3,Suburbs of Goa ~ Soma FM,Suburbs of Goa, ~ Desi-influenced Asian world beats and beyond http://ice1.somafm.com/bootliquor-128-mp3,Boot Liquor ~ Soma FM,Boot Liquor, ~ Americana Roots music for Cowhands Cowpokes and Cowtippers http://ice1.somafm.com/sonicuniverse-128-mp3,Sonic Universe ~ Soma FM,Sonic Universe, ~ Transcending the world of jazz with eclectic avant-garde takes on traditionhttp://ice1.somafm.com/poptron-128-mp3,PopTron ~ Soma FM,PopTron, ~ Electropop and indie dance rock with sparkle and pop http://ice1.somafm.com/folkfwd-128-mp3,Folk Forward ~ Soma FM,Folk Forward, ~ Indie Folk, Alt-folk and the occasional folk classics http://ice1.somafm.com/defcon-128-mp3,DEF CON Radio ~ Soma FM,DEF CON Radio, ~ Music for Hacking. The DEF CON Year-Round Channel http://ice1.somafm.com/seventies-128-mp3,Left Coast 70s ~ Soma FM,Left Coaast 70s, ~ Mellow album rock from the Seventies. Yacht friendly http://ice1.somafm.com/bagel-128-mp3,BAGeL Radio ~ Soma FM,BAGeL Radio, ~ What alternative rock radio should sound like http://ice1.somafm.com/thetrip-128-mp3,The Trip ~ Soma FM,The Trip, ~ Progressive house / trance. Tip top tunes http://ice1.somafm.com/fluid-128-mp3,Fluid ~ Soma FM,Fluid, ~ Drown in the electronic sound of instrumental hiphop future soul and liquid trap http://ice1.somafm.com/thistle-128-mp3,Thistle Radio ~ Soma FM,Thistle Radio, ~ Exploring music from Celtic roots and branches http://ice1.somafm.com/illstreet-128-mp3,Illinois Street Lounge ~ Soma FM,Illinois Street Lounge, ~ Classic bachelor pad playful exotica and vintage music of tomorrow http://ice1.somafm.com/7soul-128-mp3,Seven Inch Soul ~ Soma FM,Seven Inch Soul, ~ Vintage soul tracks from the original 45 RPM vinyl http://ice1.somafm.com/cliqhop-128-mp3,cliqhop idm ~ Soma FM,cliqhop idm, ~ Blips'n'beeps backed mostly w/beats. Intelligent Dance Music http://ice1.somafm.com/digitalis-128-mp3,Digitalis ~ Soma FM,Digitalis, Digitally affected analog rock to calm the agitated heart http://ice1.somafm.com/missioncontrol-128-mp3,Mission Control ~ Soma FM,Mission Control, ~ Celebrating NASA and Space Explorers everywhere http://ice1.somafm.com/dubstep-128-mp3,Dub Step Beyond ~ Soma FM,Dub Step Beyond, ~ Dubstep Dub and Deep Bass. May damage speakers at high volume http://ice1.somafm.com/doomed-128-mp3,Doomed ~ Soma FM,Doomed, ~ Dark industrial/ambient music for tortured souls http://ice1.somafm.com/brfm-128-mp3,Black Rock FM ~ Soma FM,Black Rock FM, ~ From the Playa to the world, back for the 2015 Burning Man festival http://ice1.somafm.com/covers-128-mp3,Covers ~ Soma FM,Covers, ~ Just covers. Songs you know by artists you don't. We've got you covered http://ice1.somafm.com/sf1033-128-mp3,SF 10-33 ~ Soma FM,SF 10-33, ~ Ambient music mixed with the sounds of San Francisco public safety radio traffic http://ice1.somafm.com/earwaves-128-mp3,Earwaves ~ Soma FM,Earwaves, ~ Spanning the history of electronic and experimental music from the early pioneers to the latest innovators http://ice1.somafm.com/metal-128-mp3,Metal Detector ~ Soma FM,Metal Detector, ~ From black to doom / prog to sludge / thrash to post / stoner to crossover / punk to industrial UPDATE SERVER SCRIPT Note, this is maybe only 10% my own work and is based on another script for which I have long since lost the details where I got it from. If you find the original author please let me know so I can credit them. // CTD Updater Script // Server UUID:debccf52-3ec9-0428-4f4f-dcc533199b30 // NOTE: This is an area to keep the UUID in the notes for reference. key serverID; string cardName = "Updates"; // Name of the Notecard with all of the Item:Version info string company = "Bertone Audio"; // Name of the company key lineTotalID; key locateID; integer lineCurrent = 0; // Line Offset integer lineTotal; // Line Offset string noteLine; string noteFront; string noteBack; string item; string version; key user; float watchdog = 10.0; integer InUse = FALSE; default { state_entry() { llWhisper(0,llGetKey()); llSetTimerEvent(5.0); lineTotalID = llGetNumberOfNotecardLines(cardName); } touch_start(integer total_number) { llResetScript(); } timer() { llGetNextEmail("",""); } email(string time, string address, string subject, string body, integer remaining) { llWhisper(0,"Received Request..."); if (InUse == FALSE) { InUse = TRUE; llSetText("In Use...",<1,1,1>,1.0); string message = llDeleteSubString(body, 0, llSubStringIndex(body, "\n\n") + 1); integer itemMark = llSubStringIndex(message,":"); integer verMark = llSubStringIndex(message,"|"); item = llGetSubString(message,0,(itemMark - 1)); version = llGetSubString(message,(itemMark + 1),(verMark - 1)); user = (key)llGetSubString(message,(verMark + 1), -1); llWhisper(0,"Item: " + item); llWhisper(0,"Version: " + version); llWhisper(0,"User: " + llKey2Name(user)); lineCurrent = 0; locateID = llGetNotecardLine(cardName,0); } } dataserver(key queryID, string data) { if (queryID == lineTotalID) { lineTotal = (integer)data; llInstantMessage(llGetOwner(),"Found " + (string)lineTotal + " items on update server."); } if (locateID == queryID) { if (data != EOF) { noteLine = data; integer marker = llSubStringIndex(noteLine,":"); if (marker != -1) { lineCurrent += 1; noteFront = llGetSubString(noteLine,0,( marker - 1 )); noteBack = llGetSubString(noteLine,( marker + 1 ), -1); } if (marker == -1) { llInstantMessage(llGetOwner(),"Error with Update Server Inventory line: " + (string)lineCurrent); } if (noteFront != item) locateID = llGetNotecardLine(cardName,lineCurrent); if (noteFront == item) { if ((float)noteBack > (float)version) { llGiveInventory(user,item); llInstantMessage(user,"Sending you the updated version of: " + item); } if ((float)noteBack < (float)version) llInstantMessage(user,"There was an error with the update of your " + item + ", please contact " + llKey2Name(llGetOwner())); if ((float)noteBack == (float)version) llInstantMessage(user,"Your " + item + " by " + company + " is up to date."); InUse = FALSE; llSetText("",<1,1,1>,0.0); } } } if (data == EOF) { InUse = FALSE; llSetText("",<1,1,1>,0.0); llInstantMessage(llGetOwner(),"Update Server Hit EOF on Update List"); } } } UPDATE SERVER NOTE CARD Bertone Audio - Classic Radio:165A Bertone Audio - Hidden Radio:165A Bertone Audio - Tube Radio:165A Bertone Audio - Pyramid Radio:165A Bertone Audio - Cube Radio:165A INSTRUCTIONS NOTE CARD
  7. There have been some recent LSL scripting changes regarding the llHTTPRequest command and my old script now gives errors. The fixed script is as follows. // BAS PmP // last modified 22 July 2017 // previous minor revision 28 february 2016 // previous major revision 17 May 2010 // if instructions are renamed make change in this script also!! string version = "165A"; // Version number of this item string gName = "channels"; // name of the notecard that holds the channel list integer gLine = 0; // current line number, set to 0 so it starts at the beginning key gQueryID; // id used to identify dataserver queries list GenreElementList = []; integer populating_list = TRUE; string nPlaying = "Unknown"; integer FloatText = TRUE; integer ShowURL = FALSE; // start 1.5 extras list trackpulllist = []; float gap = 5.0; float counter = 0.0; // string nPlayingURL = "http://"; string nPlayingURL = "NOT_SET"; string TrackElementHold = ""; integer nPlayingSHOW = TRUE; // end 1.5 extras // start 1.6 extras key gkOwner; key serverID = "d48e17c5-e8f6-1588-b57f-9d28423de917@lsl.secondlife.com"; integer InstalledTextures = 0; // end 1.6 extras key menuitem; // id used to get menu selection list MainMenu = ["tuner", "options", "off"]; list OptionsMenu = ["instructions", "texton", "textoff", "show url", "playing", "list", "reset", "update", "main menu"]; string tuner_dialog = "\nBAS Parcel Music Player\nBertone Audio Systems, Bilogorac (23, 196, 68)\n\nMake a selection or press 'ignore' to close this dialog box."; string chatline = "------------------------------------------------------"; list first_menu; list second_menu; list third_menu; list fourth_menu; list fifth_menu; list sixth_menu; list seventh_menu; list eigth_menu; list ninth_menu; string lastpage = "Page 9"; default { // when device is first rezzed it will reset the script on_rez(integer start_param) { llSay(0, "Player installed. Setting defaults."); llResetScript(); llSay(0, "Defaults set."); } // when script is started or restarted it will display some details about the device, // tell it to read the data file, start the listen and set the text on the device state_entry() { llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); llSay(978, "reset"); llSay(0, "\n\n" +chatline+ "\nBAS PMP (Parcel Music Player) " +version+ "\nScript written by Cookie Bertone\nBertone Audio Systems, Bilogorac (23, 196, 68)\n" +chatline+ "\n\nLoading channels.\nPlease wait for 'Ready'.\n\n"); llSetParcelMusicURL(""); gQueryID = llGetNotecardLine(gName, gLine); // request first line llListen(87, "", NULL_KEY, ""); // listen for request on channel 87 llSetText("Bertone Audio System " +version, <0.0,1.0,1.0>, .5); llSetTimerEvent(gap); // Activate the timer listener every X seconds } // when the device is touched it will display the main menu touch_start(integer touchNumber) { llDialog(llDetectedKey(0), tuner_dialog, MainMenu, 87); } listen(integer channel, string name, key id, string message) { integer index = llListFindList(GenreElementList, [message]); if (index != -1) { llSay(0, "Found "+message+" in channel list. Setting channel."); llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); gQueryID = llGetNotecardLine(gName, index); } else if (message=="list") { llSay(0, "Listing possible genres:"); integer x; integer length=llGetListLength(GenreElementList); for (x=0; x<length; x++) { llSay(0,llList2String(GenreElementList,x)); } } else if (message=="playing") { llSay(0, "Now playing: "+nPlaying); } else if (message=="texton") { FloatText = TRUE; nPlayingSHOW = TRUE; llSetText("Now playing: "+nPlaying+".", <0.0,1.0,1.0>, .5); } else if (message=="textoff") { FloatText = FALSE; nPlayingSHOW = FALSE; llSetText(" ", <0.0,1.0,1.0>, .5); } else if (message=="show url") { ShowURL = TRUE; } else if (message=="XXpictureXX") { integer InstalledTextures = llGetInventoryNumber(INVENTORY_TEXTURE); if (InstalledTextures == 1) { string TextureName = llGetInventoryName(INVENTORY_TEXTURE, 0); llSay (0,"Texture found: " +TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures > 1) { float RandTexture = llFrand(InstalledTextures); integer TextureChoice = (integer)RandTexture; string TextureName = llGetInventoryName(INVENTORY_TEXTURE, TextureChoice); llSay (0,"Choosing a random texture: "+TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures < 1) { llSay(0,"There are no textures installed."); } } else if (message=="instructions") { llGiveInventory(id, "radio instructions (16)"); } else if (message=="reset") { llSay(0, "Resetting."); llResetScript(); } else if (message=="options") { llDialog(id, tuner_dialog, OptionsMenu, 87); } else if (message=="update") { llOwnerSay("Contacting update server."); llEmail(serverID,"Update Request",llGetObjectName() + ":" + version + "|" + (string)llGetOwner()); } else if (message=="off") { llSay(0, "System Off"); llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(978, "red"); llSetParcelMusicURL(""); //next two lines new for v1.5, these reset variables to stop it displaying track names when switched off nPlayingURL = "NOT_SET"; TrackElementHold = ""; if (FloatText = TRUE) { llSetText("Bertone Audio System " +version+ " OFF", <0.0,1.0,1.0>, .5); } } else if (message=="tuner") { if(llGetListLength(GenreElementList) > 80) { llSay(0, "Only the first 80 channels will be displayed in the menu."); } if(llGetListLength(GenreElementList) > 12) { // remember that a list starts at 0, not 1 // all the menus except the first one are set here so the following if statements can change them if necessary second_menu = ["Page 1", "main menu", "Page 3"] + llList2List(GenreElementList, 9, 17); third_menu = ["Page 2", "main menu", "Page 4"] + llList2List(GenreElementList, 18, 26); fourth_menu = ["Page 3", "main menu", "Page 5"] + llList2List(GenreElementList, 27, 35); fifth_menu = ["Page 4", "main menu", "Page 6"] + llList2List(GenreElementList, 36, 44); sixth_menu = ["Page 5", "main menu", "Page 7"] + llList2List(GenreElementList, 45, 53); seventh_menu = ["Page 6", "main menu", "Page 8"] + llList2List(GenreElementList, 54, 62); eigth_menu = ["Page 7", "main menu", "Page 9"] + llList2List(GenreElementList, 63, 71); ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); // this bit sets which page will be the last so no empty menus are displayed if(llGetListLength(GenreElementList) < 81) { ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); lastpage = "Page 9"; } if(llGetListLength(GenreElementList) < 72) { eigth_menu = ["Page 7", "main menu", "Page 1"] + llList2List(GenreElementList, 63, 71); lastpage = "Page 8"; } if(llGetListLength(GenreElementList) < 63) { seventh_menu = ["Page 6", "main menu", "Page 1"] + llList2List(GenreElementList, 54, 62); lastpage = "Page 7"; } if(llGetListLength(GenreElementList) < 54) { sixth_menu = ["Page 5", "main menu", "Page 1"] + llList2List(GenreElementList, 45, 53); lastpage = "Page 6"; } if(llGetListLength(GenreElementList) < 45) { fifth_menu = ["Page 4", "main menu", "Page 1"] + llList2List(GenreElementList, 36, 44); lastpage = "Page 5"; } if(llGetListLength(GenreElementList) < 36) { fourth_menu = ["Page 3", "main menu", "Page 1"] + llList2List(GenreElementList, 27, 35); lastpage = "Page 4"; } if(llGetListLength(GenreElementList) < 27) { third_menu = ["Page 2", "main menu", "Page 1"] + llList2List(GenreElementList, 18, 26); lastpage = "Page 3"; } if(llGetListLength(GenreElementList) < 18) { second_menu = ["Page 1", "main menu", "Page 1"] + llList2List(GenreElementList, 9, 17); lastpage = "Page 2"; } // the first menu is set here 'after' the last page has been defined (above) then the first dialog is displayed first_menu = [lastpage, "main menu", "Page 2"] + llList2List(GenreElementList, 0, 8); llDialog(id, tuner_dialog, first_menu, 87); } else { // if there are less than 12 items in the menu it displays this dialog that doesn't need the page buttons llDialog(id, tuner_dialog, GenreElementList, 87); } } else if(message=="Page 1") { llDialog(id, tuner_dialog, first_menu, 87); } else if(message=="Page 2") { llDialog(id, tuner_dialog, second_menu, 87); } else if(message=="Page 3") { llDialog(id, tuner_dialog, third_menu, 87); } else if(message=="Page 4") { llDialog(id, tuner_dialog, fourth_menu, 87); } else if(message=="Page 5") { llDialog(id, tuner_dialog, fifth_menu, 87); } else if(message=="Page 6") { llDialog(id, tuner_dialog, sixth_menu, 87); } else if(message=="Page 7") { llDialog(id, tuner_dialog, seventh_menu, 87); } else if(message=="Page 8") { llDialog(id, tuner_dialog, eigth_menu, 87); } else if(message=="Page 9") { llDialog(id, tuner_dialog, ninth_menu, 87); } else if(message=="main menu") { llDialog(id, tuner_dialog, MainMenu, 87); } else { llSay(0, "Sorry. I couldn't find a station or command with the ID: "+message); } } // timer section is new for version 1.5 timer() { //llHTTPRequest(nPlayingURL+"/7.html HTTP/1.0\nUser-Agent: XML Getter (Mozilla Compatible)\n\n",[],""); //llHTTPRequest(nPlayingURL+"/7.html HTTP/1.1\nUser-Agent:Mozilla\n\n",[],""); if (nPlayingURL != "NOT_SET") { llHTTPRequest(nPlayingURL+"/7.html", [HTTP_USER_AGENT, "BAS_"+version+" (Mozilla Compatible)"],""); } } // http_response section is new for version 1.5 http_response(key trackid, integer status, list metadata, string trackbody) { list TrackPullList = llParseString2List(trackbody,[","],[]); // takes the http result and turns it into a list string TrackElement = llList2String(TrackPullList,6); // takes the sixth item out of the http result list TrackElement = llDeleteSubString(TrackElement, -14, -1); // strips off the html junk text at the end if (nPlayingSHOW == TRUE) { if (TrackElementHold != TrackElement) { llSay(0, "Now playing: " + TrackElement + "."); // displays the result TrackElementHold = TrackElement; } } } dataserver(key query_id, string data) { if (populating_list == TRUE) // first pass through is to build up a list of Genre Names { if (data != EOF) { list StationList = llParseString2List(data,[","],[]); string GenreElement = llList2String(StationList,2); GenreElementList = GenreElementList + [llList2String(StationList,2)]; ++gLine; // increase line count by 1 gQueryID = llGetNotecardLine(gName, gLine); // request next line } else { populating_list = FALSE; llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(0, "\n\nReady.\nTouch player to begin...\n\n"); } } else { list StationList = llParseString2List(data,[","],[]); // converts the line taken into a list string URLElement = llList2String(StationList,0); // grab the URL llSetParcelMusicURL(URLElement); llSetLinkColor(2, <0.9, 0.9, 0.9>, ALL_SIDES); llSay(978, "blue"); string StationElement = llList2String(StationList,1); if (ShowURL == TRUE) { llSay(0, "\n\nNow playing: "+StationElement+". ("+URLElement+"\n)"); } else { llSay(0, "\n\nNow playing: "+StationElement+".\n"); } if (FloatText == TRUE) { //llSay(0,"DIAGNOSTIC: FloatText is true"); llSetText("Now playing: "+StationElement+".", <0.0,1.0,1.0>, .5); } nPlaying = StationElement; // this holds the station name for use in other sections nPlayingURL = URLElement; // this holds the station URL for use in other sections } } }
  8. Oops, silly me for not posting that information. But, this morning I go back to check and change the script and it is working fine. Weird. So yes it did look right because it was. I cannot explain it as I even restarted my viewer and replaced the item to make sure it was reset last night. So, thank you all for your help. :-)
  9. Sorry to post this but I took a long break from SL and my skills with LSL seem to have vanished. My own script had the following command with the nPlayingURL being the stream URL. llHTTPRequest(nPlayingURL+"/7.html HTTP/1.1\nUser-Agent:Mozilla\n\n",[],""); I thought that the following would work as it was very close to Fox's code, but it doesn't. If somebody could point me in the right direction I would be super grateful. llHTTPRequest(nPlayingURL + "/7.html", [HTTP_USER_AGENT, "BAS_PMP (Mozilla Compatible)"],"");
  10. I worked hard on my avi and I was a holdout for a long while before I went full mesh with only the hair being adopted as a 'must have'. I still love my original avi and load her up every now and again.
  11. If anybody is still looking for this I decided to reopen my store in SL and start working on an updated version. The latest code is below. This works as it should but it is still a work in progress. // BAS PmP// last modified 28 February 2016// previous major revision 17 May 2010// if instructions are renamed make change in this script also!!string version = "1.64c"; // Version number of this itemstring gName = "channels"; // name of the notecard that holds the channel listinteger gLine = 0; // current line number, set to 0 so it starts at the beginningkey gQueryID; // id used to identify dataserver querieslist GenreElementList = [];integer populating_list = TRUE;string nPlaying = "Unknown";integer FloatText = TRUE;integer ShowURL = FALSE;// start 1.5 extraslist trackpulllist = [];float gap = 5.0;float counter = 0.0;string nPlayingURL = "http://";string'>http://";string TrackElementHold = "";integer nPlayingSHOW = TRUE;// end 1.5 extras// start 1.6 extraskey gkOwner;key serverID = "d48e17c5-e8f6-1588-b57f-9d28423de917@lsl.secondlife.com";integer InstalledTextures = 0;// end 1.6 extraskey menuitem; // id used to get menu selectionlist MainMenu = ["tuner", "options", "off"];list OptionsMenu = ["instructions", "texton", "textoff", "show url", "playing", "list", "reset", "update", "main menu"];string tuner_dialog = "\nBAS Parcel Music Player\nBertone Audio Systems, Bilogorac (23, 196, 68)\n\nMake a selection or press 'ignore' to close this dialog box.";string chatline = "------------------------------------------------------";list first_menu;list second_menu;list third_menu;list fourth_menu;list fifth_menu;list sixth_menu;list seventh_menu;list eigth_menu;list ninth_menu;string lastpage = "Page 9";default{ // when device is first rezzed it will reset the script on_rez(integer start_param) { llSay(0, "Player installed. Setting defaults."); llResetScript(); llSay(0, "Defaults set."); } // when script is started or restarted it will display some details about the device, // tell it to read the data file, start the listen and set the text on the device state_entry() { llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); llSay(978, "reset"); llSay(0, "\n\n" +chatline+ "\nBAS PMP (Parcel Music Player) " +version+ "\nScript written by Cookie Bertone\nBertone Audio Systems, Bilogorac (23, 196, 68)\n" +chatline+ "\n\nLoading channels.\nPlease wait for 'Ready'.\n\n"); llSetParcelMusicURL(""); gQueryID = llGetNotecardLine(gName, gLine); // request first line llListen(97, "", NULL_KEY, ""); // listen for request on channel 97 llSetText("Bertone Audio System " +version, <0.0,1.0,1.0>, .5); llSetTimerEvent(gap); // Activate the timer listener every X seconds } // when the device is touched it will display the main menu touch_start(integer touchNumber) { llDialog(llDetectedKey(0), tuner_dialog, MainMenu, 97); } listen(integer channel, string name, key id, string message) { integer index = llListFindList(GenreElementList, [message]); if (index != -1) { llSay(0, "Found "+message+" in channel list. Setting channel."); llSetLinkColor(2, <0.0, 0.9, 0.0>, ALL_SIDES); gQueryID = llGetNotecardLine(gName, index); } else if (message=="list") { llSay(0, "Listing possible genres:"); integer x; integer length=llGetListLength(GenreElementList); for (x=0; x<length; x++) { llSay(0,llList2String(GenreElementList,x)); } } else if (message=="playing") { llSay(0, "Now playing: "+nPlaying); } else if (message=="texton") { FloatText = TRUE; nPlayingSHOW = TRUE; llSetText("Now playing: "+nPlaying+".", <0.0,1.0,1.0>, .5); } else if (message=="textoff") { FloatText = FALSE; nPlayingSHOW = FALSE; llSetText(" ", <0.0,1.0,1.0>, .5); } else if (message=="show url") { ShowURL = TRUE; } else if (message=="XXpictureXX") { integer InstalledTextures = llGetInventoryNumber(INVENTORY_TEXTURE); if (InstalledTextures == 1) { string TextureName = llGetInventoryName(INVENTORY_TEXTURE, 0); llSay (0,"Texture found: " +TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures > 1) { float RandTexture = llFrand(InstalledTextures); integer TextureChoice = (integer)RandTexture; string TextureName = llGetInventoryName(INVENTORY_TEXTURE, TextureChoice); llSay (0,"Choosing a random texture: "+TextureName); if (name != "") llSetTexture(TextureName, 5); } if (InstalledTextures < 1) { llSay(0,"There are no textures installed."); } } else if (message=="instructions") { llGiveInventory(id, "radio instructions (16)"); } else if (message=="reset") { llSay(0, "Resetting."); llResetScript(); } else if (message=="options") { llDialog(id, tuner_dialog, OptionsMenu, 97); } else if (message=="update") { llOwnerSay("Contacting update server."); llEmail(serverID,"Update Request",llGetObjectName() + ":" + version + "|" + (string)llGetOwner()); } else if (message=="off") { llSay(0, "System Off"); llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(978, "red"); llSetParcelMusicURL(""); //next two lines new for v1.5, these reset variables to stop it displaying track names when switched off nPlayingURL = "http://"; TrackElementHold = ""; if (FloatText = TRUE) { llSetText("Bertone Audio System " +version+ " OFF", <0.0,1.0,1.0>, .5); } } else if (message=="tuner") { if(llGetListLength(GenreElementList) > 80) { llSay(0, "Only the first 80 channels will be displayed in the menu."); } if(llGetListLength(GenreElementList) > 12) { // remember that a list starts at 0, not 1 // all the menus except the first one are set here so the following if statements can change them if necessary second_menu = ["Page 1", "main menu", "Page 3"] + llList2List(GenreElementList, 9, 17); third_menu = ["Page 2", "main menu", "Page 4"] + llList2List(GenreElementList, 18, 26); fourth_menu = ["Page 3", "main menu", "Page 5"] + llList2List(GenreElementList, 27, 35); fifth_menu = ["Page 4", "main menu", "Page 6"] + llList2List(GenreElementList, 36, 44); sixth_menu = ["Page 5", "main menu", "Page 7"] + llList2List(GenreElementList, 45, 53); seventh_menu = ["Page 6", "main menu", "Page 8"] + llList2List(GenreElementList, 54, 62); eigth_menu = ["Page 7", "main menu", "Page 9"] + llList2List(GenreElementList, 63, 71); ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); // this bit sets which page will be the last so no empty menus are displayed if(llGetListLength(GenreElementList) < 81) { ninth_menu = ["Page 8", "main menu", "Page 1"] + llList2List(GenreElementList, 72, 80); lastpage = "Page 9"; } if(llGetListLength(GenreElementList) < 72) { eigth_menu = ["Page 7", "main menu", "Page 1"] + llList2List(GenreElementList, 63, 71); lastpage = "Page 8"; } if(llGetListLength(GenreElementList) < 63) { seventh_menu = ["Page 6", "main menu", "Page 1"] + llList2List(GenreElementList, 54, 62); lastpage = "Page 7"; } if(llGetListLength(GenreElementList) < 54) { sixth_menu = ["Page 5", "main menu", "Page 1"] + llList2List(GenreElementList, 45, 53); lastpage = "Page 6"; } if(llGetListLength(GenreElementList) < 45) { fifth_menu = ["Page 4", "main menu", "Page 1"] + llList2List(GenreElementList, 36, 44); lastpage = "Page 5"; } if(llGetListLength(GenreElementList) < 36) { fourth_menu = ["Page 3", "main menu", "Page 1"] + llList2List(GenreElementList, 27, 35); lastpage = "Page 4"; } if(llGetListLength(GenreElementList) < 27) { third_menu = ["Page 2", "main menu", "Page 1"] + llList2List(GenreElementList, 18, 26); lastpage = "Page 3"; } if(llGetListLength(GenreElementList) < 18) { second_menu = ["Page 1", "main menu", "Page 1"] + llList2List(GenreElementList, 9, 17); lastpage = "Page 2"; } // the first menu is set here 'after' the last page has been defined (above) then the first dialog is displayed first_menu = [lastpage, "main menu", "Page 2"] + llList2List(GenreElementList, 0, 8); llDialog(id, tuner_dialog, first_menu, 97); } else { // if there are less than 12 items in the menu it displays this dialog that doesn't need the page buttons llDialog(id, tuner_dialog, GenreElementList, 97); } } else if(message=="Page 1") { llDialog(id, tuner_dialog, first_menu, 97); } else if(message=="Page 2") { llDialog(id, tuner_dialog, second_menu, 97); } else if(message=="Page 3") { llDialog(id, tuner_dialog, third_menu, 97); } else if(message=="Page 4") { llDialog(id, tuner_dialog, fourth_menu, 97); } else if(message=="Page 5") { llDialog(id, tuner_dialog, fifth_menu, 97); } else if(message=="Page 6") { llDialog(id, tuner_dialog, sixth_menu, 97); } else if(message=="Page 7") { llDialog(id, tuner_dialog, seventh_menu, 97); } else if(message=="Page 8") { llDialog(id, tuner_dialog, eigth_menu, 97); } else if(message=="Page 9") { llDialog(id, tuner_dialog, ninth_menu, 97); } else if(message=="main menu") { llDialog(id, tuner_dialog, MainMenu, 97); } else { llSay(0, "Sorry. I couldn't find a station or command with the ID: "+message); } }// timer section is new for version 1.5 timer() { //llHTTPRequest(nPlayingURL+"/7.html HTTP/1.0\nUser-Agent: XML Getter (Mozilla Compatible)\n\n",[],""); llHTTPRequest(nPlayingURL+"/7.html HTTP/1.1\nUser-Agent:Mozilla\n\n",[],""); } // http_response section is new for version 1.5 http_response(key trackid, integer status, list metadata, string trackbody) { list TrackPullList = llParseString2List(trackbody,[","],[]); // takes the http result and turns it into a list string TrackElement = llList2String(TrackPullList,6); // takes the sixth item out of the http result list TrackElement = llDeleteSubString(TrackElement, -14, -1); // strips off the html junk text at the end if (nPlayingSHOW == TRUE) { if (TrackElementHold != TrackElement) { llSay(0, "Now playing: " + TrackElement + "."); // displays the result TrackElementHold = TrackElement; } } } dataserver(key query_id, string data) { if (populating_list == TRUE) // first pass through is to build up a list of Genre Names { if (data != EOF) { list StationList = llParseString2List(data,[","],[]); string GenreElement = llList2String(StationList,2); GenreElementList = GenreElementList + [llList2String(StationList,2)]; ++gLine; // increase line count by 1 gQueryID = llGetNotecardLine(gName, gLine); // request next line } else { populating_list = FALSE; llSetLinkColor(2, <1.0, 0.0, 0.0>, ALL_SIDES); llSay(0, "\n\nReady.\nTouch player to begin...\n\n"); } } else { list StationList = llParseString2List(data,[","],[]); // converts the line taken into a list string URLElement = llList2String(StationList,0); // grab the URL llSetParcelMusicURL(URLElement); llSetLinkColor(2, <0.9, 0.9, 0.9>, ALL_SIDES); llSay(978, "blue"); string StationElement = llList2String(StationList,1); if (ShowURL == TRUE) { llSay(0, "\n\nNow playing: "+StationElement+". ("+URLElement+"\n)"); } else { llSay(0, "\n\nNow playing: "+StationElement+".\n"); } if (FloatText == TRUE) { //llSay(0,"DIAGNOSTIC: FloatText is true"); llSetText("Now playing: "+StationElement+".", <0.0,1.0,1.0>, .5); } nPlaying = StationElement; // this holds the station name for use in other sections nPlayingURL = URLElement; // this holds the station URL for use in other sections } }} And the latest channels notecard. http://ice1.somafm.com/groovesalad-128-mp3,Groove Salad ~ Soma FM,Groove Salad, ~ A nicely chilled plate of ambient downtempo beats and grooveshttp://ice1.somafm.com/dronezone-128-mp3,Drone Zone ~ Soma FM,Drone Zone, ~ Served best chilled and safe with most medications. Atmospheric textures with minimal beatshttp://ice1.somafm.com/indiepop-128-mp3,Indie Pop Rocks ~ Soma FM,Indie Pop, ~ New and classic favorite indie pop trackshttp://ice1.somafm.com/lush-128-mp3,Lush ~ Soma FM,Lush, ~ Sensuous and mellow vocals with an electronic influencehttp://ice1.somafm.com/secretagent-128-mp3,Secret Agent ~ Soma FM,Secret Agent, ~ The soundtrack for your stylish mysterious dangerous life. For Spies and PIs too!http://ice1.somafm.com/spacestation-128-mp3,Space Station Soma ~ Soma FM,Space Station Soma, ~ Tune in turn on space out. Spaced-out ambient and mid-tempo electronicahttp://ice1.somafm.com/u80s-128-mp3,Underground 80s ~ Soma FM,Underground 80s, ~ Early 80s UK Synthpop and a bit of New Wavehttp://ice1.somafm.com/deepspaceone-128-mp3,Deep Spare One ~ Soma FM,Deep Space One, ~ Deep ambient electronic experimental and space music. For inner and outer space explorationhttp://ice1.somafm.com/beatblender-128-mp3,Beat Blender ~ Soma FM,Beat Blender, ~ A late night blend of deep-house and downtempo chillhttp://ice1.somafm.com/suburbsofgoa-128-mp3,Suburbs of Goa ~ Soma FM,Suburbs of Goa, ~ Desi-influenced Asian world beats and beyondhttp://ice1.somafm.com/bootliquor-128-mp3,Boot Liquor ~ Soma FM,Boot Liquor, ~ Americana Roots music for Cowhands Cowpokes and Cowtippershttp://ice1.somafm.com/sonicuniverse-128-mp3,Sonic Universe ~ Soma FM,Sonic Universe, ~ Transcending the world of jazz with eclectic avant-garde takes on traditionhttp://ice1.somafm.com/poptron-128-mp3,PopTron ~ Soma FM,PopTron, ~ Electropop and indie dance rock with sparkle and pophttp://ice1.somafm.com/folkfwd-128-mp3,Folk Forward ~ Soma FM,Folk Forward, ~ Indie Folk, Alt-folk and the occasional folk classicshttp://ice1.somafm.com/defcon-128-mp3,DEF CON Radio ~ Soma FM,DEF CON Radio, ~ Music for Hacking. The DEF CON Year-Round Channelhttp://ice1.somafm.com/seventies-128-mp3,Left Coast 70s ~ Soma FM,Left Coaast 70s, ~ Mellow album rock from the Seventies. Yacht friendlyhttp://ice1.somafm.com/bagel-128-mp3,BAGeL Radio ~ Soma FM,BAGeL Radio, ~ What alternative rock radio should sound likehttp://ice1.somafm.com/thetrip-128-mp3,The Trip ~ Soma FM,The Trip, ~ Progressive house / trance. Tip top tuneshttp://ice1.somafm.com/fluid-128-mp3,Fluid ~ Soma FM,Fluid, ~ Drown in the electronic sound of instrumental hiphop future soul and liquid traphttp://ice1.somafm.com/thistle-128-mp3,Thistle Radio ~ Soma FM,Thistle Radio, ~ Exploring music from Celtic roots and brancheshttp://ice1.somafm.com/illstreet-128-mp3,Illinois Street Lounge ~ Soma FM,Illinois Street Lounge, ~ Classic bachelor pad playful exotica and vintage music of tomorrowhttp://ice1.somafm.com/7soul-128-mp3,Seven Inch Soul ~ Soma FM,Seven Inch Soul, ~ Vintage soul tracks from the original 45 RPM vinylhttp://ice1.somafm.com/cliqhop-128-mp3,cliqhop idm ~ Soma FM,cliqhop idm, ~ Blips'n'beeps backed mostly w/beats. Intelligent Dance Musichttp://ice1.somafm.com/digitalis-128-mp3,Digitalis ~ Soma FM,Digitalis, Digitally affected analog rock to calm the agitated hearthttp://ice1.somafm.com/missioncontrol-128-mp3,Mission Control ~ Soma FM,Mission Control, ~ Celebrating NASA and Space Explorers everywherehttp://ice1.somafm.com/dubstep-128-mp3,Dub Step Beyond ~ Soma FM,Dub Step Beyond, ~ Dubstep Dub and Deep Bass. May damage speakers at high volumehttp://ice1.somafm.com/doomed-128-mp3,Doomed ~ Soma FM,Doomed, ~ Dark industrial/ambient music for tortured soulshttp://ice1.somafm.com/brfm-128-mp3,Black Rock FM ~ Soma FM,Black Rock FM, ~ From the Playa to the world, back for the 2015 Burning Man festivalhttp://ice1.somafm.com/covers-128-mp3,Covers ~ Soma FM,Covers, ~ Just covers. Songs you know by artists you don't. We've got you coveredhttp://ice1.somafm.com/sf1033-128-mp3,SF 10-33 ~ Soma FM,SF 10-33, ~ Ambient music mixed with the sounds of San Francisco public safety radio traffichttp://ice1.somafm.com/earwaves-128-mp3,Earwaves ~ Soma FM,Earwaves, ~ Spanning the history of electronic and experimental music from the early pioneers to the latest innovatorshttp://ice1.somafm.com/metal-128-mp3,Metal Detector ~ Soma FM,Metal Detector, ~ From black to doom / prog to sludge / thrash to post / stoner to crossover / punk to industrial
  12. Wow, people are still looking at my old script? :womansurprised: I've been away from SL for quite some time but I popped back a couple of weeks ago and for some reason decided to check out the forums today. I'll try to get back in-world over the coming week (or two) and give my code a once over to see if it is still working as I intended and get it back out there for people to make use of.
×
×
  • Create New...