HTTPRadio.lsl 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // :SHOW:
  2. // :CATEGORY:Fire
  3. // :NAME:MOAP Top 2000 Radio Stations Player
  4. // :AUTHOR:Ferd Frederix
  5. // :KEYWORDS:
  6. // :CREATED:2015-06-11 14:36:40
  7. // :EDITED:2015-06-11 13:36:40
  8. // :ID:902
  9. // :NUM:1753
  10. // :REV:1
  11. // :WORLD:Second Life
  12. // :DESCRIPTION:
  13. // Media-On-A-Prim Radio station with several thousand stations.
  14. // You must deed this to a group if you are on group-owned Land.
  15. // :CODE:
  16. // :License: CC-BY-NC-SA - Not to be sold in any form, Copyright 2015 Ferd Frederix
  17. // :Worlds: Opensim, Second Life
  18. // Please do not change the timeouts or URLS - this script is server dependent.
  19. integer debug = TRUE;
  20. float version = 1.1;
  21. string requestURL; // HTTP-IN URL
  22. key http_request_id; // the key we search for
  23. key selfCheckRequestId;// the key we search for
  24. string mediaURI ; // saved URI for radio
  25. string Description ; // saved URI for radio
  26. float newTimer = 0; // how long to play a piece of music
  27. string url = "http://www.outworldz.com";
  28. string HTTPIN;
  29. DEBUG(string str)
  30. {
  31. if (debug) llSay(0,str);
  32. }
  33. // ###############################################
  34. // Routine to parse a string sent through the
  35. // http server via post.
  36. // parsePostData(theMessage)
  37. // Returns a strided list with stride length 2.
  38. // Each set has the key and then its value.
  39. list parsePostData(string message) {
  40. list postData = []; // The list with the data that was passed in.
  41. list parsedMessage = llParseString2List(message,["&"],[]); // The key/value pairs parsed into one list.
  42. integer len = ~llGetListLength(parsedMessage);
  43. while(++len) {
  44. string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string.
  45. integer split = llSubStringIndex(currentField,"="); // Find the "=" sign
  46. if(split == -1) { // There is only one field in this part of the message.
  47. postData += [llUnescapeURL(currentField),""];
  48. } else {
  49. postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];
  50. }
  51. }
  52. // Return the strided list.
  53. return postData ;
  54. }
  55. // get from list the value of the name
  56. string Get( string name, list data)
  57. {
  58. integer index =llListFindList(data,[name]);
  59. if (index == -1)
  60. return "Nothing";
  61. return llList2String(data,index+1);
  62. }
  63. DoWebPage(integer onOff)
  64. {
  65. if (! onOff)
  66. {
  67. llClearPrimMedia(1);
  68. llOwnerSay("Touch power button to activate");
  69. }
  70. else
  71. {
  72. string lURL = url + "/radio?URI=" + llEscapeURL(HTTPIN);
  73. DEBUG("lSetting Media URL to : " + lURL);
  74. llOwnerSay("Touch screen to view. Shared media must be enabled in the Setup Menu (Ctrl-P)");
  75. llSetPrimMediaParams(1,[PRIM_MEDIA_CONTROLS,PRIM_MEDIA_CONTROLS_STANDARD,
  76. PRIM_MEDIA_HOME_URL,lURL,
  77. PRIM_MEDIA_CURRENT_URL ,lURL,
  78. PRIM_MEDIA_AUTO_PLAY , TRUE,
  79. PRIM_MEDIA_AUTO_ZOOM, TRUE,
  80. PRIM_MEDIA_WIDTH_PIXELS, 838,
  81. PRIM_MEDIA_HEIGHT_PIXELS ,1088
  82. // PRIM_MEDIA_WHITELIST_ENABLE ,TRUE
  83. // PRIM_MEDIA_WHITELIST, llEscapeURL(url),
  84. // PRIM_MEDIA_PERMS_INTERACT ,PRIM_MEDIA_PERM_GROUP
  85. // PRIM_MEDIA_PERMS_CONTROL ,PRIM_MEDIA_PERM_GROUP
  86. ]);
  87. }
  88. }
  89. string strReplace(string str, string search, string replace) {
  90. return llDumpList2String(llParseStringKeepNulls((str = "") + str, [search], []), replace);
  91. }
  92. request_url()
  93. {
  94. llReleaseURL(HTTPIN);
  95. HTTPIN = "";
  96. http_request_id = llRequestURL(); // Request that an URL be assigned to me.
  97. DEBUG("http_request_id:" + http_request_id);
  98. }
  99. SaveToServer()
  100. {
  101. string newurl = url + "cgi/shoutcast2.plx?description="
  102. + llEscapeURL(Description)
  103. + "&mediaURI=" + llEscapeURL(mediaURI)
  104. + "&version=" + llEscapeURL((string) version);
  105. DEBUG("NewURL:" + newurl);
  106. http_request_id = llHTTPRequest(newurl, [], "");
  107. }
  108. default {
  109. state_entry() {
  110. request_url();
  111. llSetTimerEvent(1);
  112. }
  113. timer()
  114. {
  115. llSetTimerEvent(3600); // hourly
  116. if (newTimer)
  117. {
  118. DEBUG("Timer set to regular channel");
  119. llSetParcelMusicURL(mediaURI);
  120. newTimer = FALSE;
  121. return;
  122. }
  123. if (llStringLength(requestURL))
  124. {
  125. DEBUG("timer:" + (string) requestURL);
  126. selfCheckRequestId = llHTTPRequest(requestURL,[],"");
  127. }
  128. }
  129. touch_start(integer n)
  130. {
  131. key id = llDetectedKey(0);
  132. integer sameGroup = llSameGroup(id);
  133. if (sameGroup) {
  134. DoWebPage(TRUE);
  135. }
  136. }
  137. http_response(key id, integer status, list metaData, string body)
  138. {
  139. DEBUG("ID:" + (string) id);
  140. DEBUG("selfCheckRequestId:" + (string) selfCheckRequestId);
  141. if (id == selfCheckRequestId)
  142. {
  143. // If you're not usually doing this,
  144. // now is a good time to get used to doing it!
  145. selfCheckRequestId = NULL_KEY;
  146. if (status != 200)
  147. request_url();
  148. }
  149. else if (id == NULL_KEY)
  150. llOwnerSay("Too many HTTP requests too fast!");
  151. }
  152. http_request(key id, string method, string body) {
  153. DEBUG("http_request:" + body);
  154. list incomingMessage;
  155. if ((method == URL_REQUEST_GRANTED) && (id == http_request_id) ){
  156. // A URL has been assigned to me.
  157. HTTPIN = body;
  158. DEBUG("Obtained URL: " + body);
  159. DoWebPage(TRUE);
  160. }
  161. else if ((method == URL_REQUEST_DENIED) && (id == http_request_id)) {
  162. // I could not obtain a URL
  163. llOwnerSay("The following error occurred while attempting to get a free URL for this device: " + body);
  164. llSleep(60);
  165. llOwnerSay("Retrying in one minute");
  166. llResetScript();
  167. }
  168. else if (method == "POST") {
  169. // An incoming message was received.
  170. DEBUG("Received information from the outside: " + body);
  171. incomingMessage = parsePostData(body);
  172. DEBUG(llDumpList2String(incomingMessage,"\n"));
  173. // see if we forced a switch
  174. string change = Get("change",incomingMessage);
  175. string goback = Get("goback",incomingMessage);
  176. // forced a change in URI with "change"
  177. if (llStringLength(change)) {
  178. string newURI = Get("id",incomingMessage);
  179. float newTimer = (float) Get("timer",incomingMessage);
  180. llSetParcelMusicURL(newURI);
  181. llSetTimerEvent(newTimer);
  182. DEBUG("Add " + newURI + " running for " + (string) newTimer + " seconds ");
  183. }
  184. else if (llStringLength(goback)) {
  185. DEBUG("Commanded to go back");
  186. llSetParcelMusicURL(mediaURI);
  187. } else {
  188. mediaURI = Get("id",incomingMessage);
  189. Description = Get("name",incomingMessage);
  190. Description = strReplace(Description,"+"," ");
  191. llOwnerSay("Station changed to " + Description +"\n" + llUnescapeURL(mediaURI));
  192. SaveToServer();
  193. }
  194. DEBUG("Set Media URL on land to " + mediaURI);
  195. llSetParcelMusicURL(mediaURI);
  196. if (llList2String(incomingMessage,0) == "power")
  197. DoWebPage(FALSE);
  198. llHTTPResponse(id,200,"OK:" + llDumpList2String(incomingMessage,"\n"));
  199. }
  200. else {
  201. // An incoming message has come in using a method that has
  202. // not been anticipated.
  203. llHTTPResponse(id,405,"Unsupported Method");
  204. }
  205. }
  206. changed(integer change)
  207. {
  208. if (change & CHANGED_REGION_START)
  209. request_url();
  210. }
  211. }