16d8d4c4-6427-f346-8b5c-554469d623b6_script.lsl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. //
  2. // The line above should be left blank to avoid script errors in OpenSim.
  3. // LoginZone script (for Sloodle 0.3).
  4. // Allows avatar-Moodle identification by teleporting into pre-defined space in-world.
  5. //
  6. // Part of the Sloodle project (www.sloodle.org).
  7. // Copyright (c) 2007-8 Sloodle
  8. // Released under the GNU GPL v3
  9. //
  10. // Contributors:
  11. // Edmund Edgar
  12. // Peter R. Bloomfield
  13. ///// DATA /////
  14. integer SLOODLE_CHANNEL_ERROR_TRANSLATION_REQUEST=-1828374651; // this channel is used to send status codes for translation to the error_messages lsl script
  15. integer SLOODLE_CHANNEL_OBJECT_DIALOG = -3857343;
  16. integer SLOODLE_CHANNEL_AVATAR_DIALOG = 1001;
  17. string SLOODLE_LOGINZONE_LINKER = "/mod/sloodle/mod/loginzone-1.0/linker.php";
  18. string SLOODLE_EOF = "sloodleeof";
  19. string SLOODLE_OBJECT_TYPE = "pwreset-1.0";
  20. string sloodleserverroot = "";
  21. string sloodlepwd = "";
  22. integer sloodlecontrollerid = 0;
  23. string sloodlecoursename_full = "";
  24. integer sloodlerefreshtime = 0; // How often to automatically update
  25. integer isconfigured = FALSE; // Do we have all the configuration data we need?
  26. integer eof = FALSE; // Have we reached the end of the configuration data?
  27. key httpupdate = NULL_KEY; // The request for sending an update
  28. list httpreqs = []; // A list of HTTP requests we're expecting
  29. ///// TRANSLATION /////
  30. // Link message channels
  31. integer SLOODLE_CHANNEL_TRANSLATION_REQUEST = -1928374651;
  32. integer SLOODLE_CHANNEL_TRANSLATION_RESPONSE = -1928374652;
  33. // Translation output methods
  34. string SLOODLE_TRANSLATE_LINK = "link"; // No output parameters - simply returns the translation on SLOODLE_TRANSLATION_RESPONSE link message channel
  35. string SLOODLE_TRANSLATE_SAY = "say"; // 1 output parameter: chat channel number
  36. string SLOODLE_TRANSLATE_WHISPER = "whisper"; // 1 output parameter: chat channel number
  37. string SLOODLE_TRANSLATE_SHOUT = "shout"; // 1 output parameter: chat channel number
  38. string SLOODLE_TRANSLATE_REGION_SAY = "regionsay"; // 1 output parameter: chat channel number
  39. string SLOODLE_TRANSLATE_OWNER_SAY = "ownersay"; // No output parameters
  40. string SLOODLE_TRANSLATE_DIALOG = "dialog"; // Recipient avatar should be identified in link message keyval. At least 2 output parameters: first the channel number for the dialog, and then 1 to 12 button label strings.
  41. string SLOODLE_TRANSLATE_LOAD_URL = "loadurl"; // Recipient avatar should be identified in link message keyval. 1 output parameter giving URL to load.
  42. string SLOODLE_TRANSLATE_HOVER_TEXT = "hovertext"; // 2 output parameters: colour <r,g,b>, and alpha value
  43. string SLOODLE_TRANSLATE_IM = "instantmessage"; // Recipient avatar should be identified in link message keyval. No output parameters.
  44. // Send a translation request link message
  45. sloodle_translation_request(string output_method, list output_params, string string_name, list string_params, key keyval, string batch)
  46. {
  47. llMessageLinked(LINK_THIS, SLOODLE_CHANNEL_TRANSLATION_REQUEST, output_method + "|" + llList2CSV(output_params) + "|" + string_name + "|" + llList2CSV(string_params) + "|" + batch, keyval);
  48. }
  49. ///// ----------- /////
  50. ///// FUNCTIONS /////
  51. /******************************************************************************************************************************
  52. * sloodle_error_code -
  53. * Author: Paul Preibisch
  54. * Description - This function sends a linked message on the SLOODLE_CHANNEL_ERROR_TRANSLATION_REQUEST channel
  55. * The error_messages script hears this, translates the status code and sends an instant message to the avuuid
  56. * Params: method - SLOODLE_TRANSLATE_SAY, SLOODLE_TRANSLATE_IM etc
  57. * Params: avuuid - this is the avatar UUID to that an instant message with the translated error code will be sent to
  58. * Params: status code - the status code of the error as on our wiki: http://slisweb.sjsu.edu/sl/index.php/Sloodle_status_codes
  59. *******************************************************************************************************************************/
  60. sloodle_error_code(string method, key avuuid,integer statuscode){
  61. llMessageLinked(LINK_SET, SLOODLE_CHANNEL_ERROR_TRANSLATION_REQUEST, method+"|"+(string)avuuid+"|"+(string)statuscode, NULL_KEY);
  62. }
  63. // Send debug info
  64. sloodle_debug(string msg)
  65. {
  66. llMessageLinked(LINK_THIS, DEBUG_CHANNEL, msg, NULL_KEY);
  67. }
  68. // Tell Sloodle our position, size and region.
  69. sloodle_update_server()
  70. {
  71. // Construct the data
  72. string body = "sloodlecontrollerid=" + (string)sloodlecontrollerid;
  73. body += "&sloodlepwd=" + sloodlepwd;
  74. body += "&sloodlepos=" + (string)llGetPos();
  75. body += "&sloodlesize=" + (string)llGetScale();
  76. body += "&sloodleregion=" + llEscapeURL(llGetRegionName());
  77. // Send the request to update the server (we don't care about the response)
  78. httpupdate = llHTTPRequest(sloodleserverroot + SLOODLE_LOGINZONE_LINKER, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"], body);
  79. }
  80. // Tell Sloodle about a detected avatar
  81. sloodle_detected_avatar(key id, vector pos)
  82. {
  83. // Construct the data
  84. string body = "sloodlecontrollerid=" + (string)sloodlecontrollerid;
  85. body += "&sloodlepwd=" + sloodlepwd;
  86. body += "&sloodlepos=" + (string)pos;
  87. body += "&sloodleuuid=" + (string)id;
  88. body += "&sloodleavname=" + llEscapeURL(llKey2Name(id));
  89. // Send the request to update the server (we don't care about the response)
  90. key newhttp = llHTTPRequest(sloodleserverroot + SLOODLE_LOGINZONE_LINKER, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"], body);
  91. if (newhttp != NULL_KEY) httpreqs += [newhttp];
  92. }
  93. // Configure by receiving a linked message from another script in the object
  94. // Returns TRUE if the object has all the data it needs
  95. integer sloodle_handle_command(string str)
  96. {
  97. list bits = llParseString2List(str,["|"],[]);
  98. integer numbits = llGetListLength(bits);
  99. string name = llList2String(bits,0);
  100. string value1 = "";
  101. string value2 = "";
  102. if (numbits > 1) value1 = llList2String(bits,1);
  103. if (numbits > 2) value2 = llList2String(bits,2);
  104. if (name == "set:sloodleserverroot") sloodleserverroot = value1;
  105. if (name == "set:sloodlecoursename_full") sloodlecoursename_full = value1;
  106. else if (name == "set:sloodlepwd") {
  107. // The password may be a single prim password, or a UUID and a password
  108. if (value2 != "") sloodlepwd = value1 + "|" + value2;
  109. else sloodlepwd = value1;
  110. } else if (name == "set:sloodlecontrollerid") sloodlecontrollerid = (integer)value1;
  111. else if (name == "set:sloodlerefreshtime") sloodlerefreshtime = (integer)value1;
  112. else if (name == SLOODLE_EOF) eof = TRUE;
  113. return (sloodleserverroot != "" && sloodlepwd != "" && sloodlecontrollerid > 0);
  114. }
  115. default
  116. {
  117. state_entry()
  118. {
  119. // Starting again with a new configuration
  120. llSetText("", <0.0,0.0,0.0>, 0.0);
  121. isconfigured = FALSE;
  122. eof = FALSE;
  123. // Reset our data
  124. sloodleserverroot = "";
  125. sloodlepwd = "";
  126. sloodlecontrollerid = 0;
  127. sloodlecoursename_full = "";
  128. }
  129. link_message(integer sender_num, integer num, string str, key id)
  130. {
  131. // Check the channel
  132. if (num == SLOODLE_CHANNEL_OBJECT_DIALOG) {
  133. // Split the message into lines
  134. list lines = llParseString2List(str, ["\n"], []);
  135. integer numlines = llGetListLength(lines);
  136. integer i = 0;
  137. for (; i < numlines; i++) {
  138. isconfigured = sloodle_handle_command(llList2String(lines, i));
  139. }
  140. // If we've got all our data AND reached the end of the configuration data, then move on
  141. if (eof == TRUE) {
  142. if (isconfigured == TRUE) {
  143. sloodle_translation_request(SLOODLE_TRANSLATE_SAY, [0], "configurationreceived", [], NULL_KEY, "");
  144. state running;
  145. } else {
  146. // Got all configuration but, it's not complete... request reconfiguration
  147. sloodle_translation_request(SLOODLE_TRANSLATE_SAY, [0], "configdatamissing", [], NULL_KEY, "");
  148. llMessageLinked(LINK_THIS, SLOODLE_CHANNEL_OBJECT_DIALOG, "do:reconfigure", NULL_KEY);
  149. eof = FALSE;
  150. }
  151. }
  152. }
  153. }
  154. touch_start(integer num_detected)
  155. {
  156. // Attempt to request a reconfiguration
  157. if (llDetectedKey(0) == llGetOwner()) {
  158. llMessageLinked(LINK_THIS, SLOODLE_CHANNEL_OBJECT_DIALOG, "do:requestconfig", NULL_KEY);
  159. }
  160. }
  161. on_rez(integer par)
  162. {
  163. llResetScript();
  164. }
  165. }
  166. state running
  167. {
  168. on_rez(integer param)
  169. {
  170. state default;
  171. }
  172. state_entry()
  173. {
  174. // Update the server
  175. sloodle_update_server();
  176. // Enable volume detection
  177. llVolumeDetect(TRUE);
  178. // Validate the update timer
  179. if (sloodlerefreshtime < 0) sloodlerefreshtime = 0;
  180. else if (sloodlerefreshtime > 0 && sloodlerefreshtime < 60) sloodlerefreshtime = 60;
  181. // Regularly update the server
  182. llSetTimerEvent((float)sloodlerefreshtime);
  183. }
  184. collision_start(integer num_detected)
  185. {
  186. // Go through each detected avatar
  187. integer i = 0;
  188. for (; i < num_detected; i++)
  189. {
  190. sloodle_detected_avatar(llDetectedKey(i), llDetectedPos(i));
  191. }
  192. }
  193. timer()
  194. {
  195. sloodle_update_server();
  196. }
  197. moving_end()
  198. {
  199. sloodle_update_server();
  200. // We don't need to automatically update right away again
  201. llSetTimerEvent((float)sloodlerefreshtime);
  202. }
  203. http_response(key id, integer status, list meta, string body)
  204. {
  205. integer statuscode; // added for OpenSim
  206. // Was this our update response?
  207. if (id == httpupdate) {
  208. httpupdate = NULL_KEY;
  209. sloodle_debug("HTTP response: " + body);
  210. // Check the HTTP response
  211. if (status != 200) {
  212. sloodle_debug("Update failed with HTTP status " + (string)status);
  213. sloodle_error_code(SLOODLE_TRANSLATE_SAY, NULL_KEY,status); //send message to error_message.lsl
  214. return;
  215. }
  216. // Extract the status code of the response
  217. list bits = llParseString2List(body, ["|"], []);
  218. statuscode = (integer)llList2String(bits, 0); // deleted "integer" for OpenSim
  219. if (statuscode <= 0) {
  220. sloodle_debug("Update failed with Sloodle status " + (string)statuscode);
  221. sloodle_error_code(SLOODLE_TRANSLATE_SAY, NULL_KEY,statuscode); //send message to error_message.lsl
  222. return;
  223. }
  224. return;
  225. }
  226. // Was this an avatar response?
  227. integer listpos = llListFindList(httpreqs, [id]);
  228. if (listpos < 0) return;
  229. httpreqs = llDeleteSubList(httpreqs, listpos, listpos);
  230. sloodle_debug("HTTP response: " + body);
  231. // Check that it was a successful response
  232. if (status != 200) {
  233. sloodle_debug("Avatar notification failed with HTTP status " + (string)status);
  234. sloodle_error_code(SLOODLE_TRANSLATE_SAY, NULL_KEY,status); //send message to error_message.lsl
  235. return;
  236. }
  237. if (body == "") {
  238. sloodle_debug("Empty response body from avatar notification.");
  239. return;
  240. }
  241. // Parse the response
  242. list lines = llParseStringKeepNulls(body, ["\n"], []);
  243. integer numlines = llGetListLength(lines);
  244. list statusfields = llParseStringKeepNulls(llList2String(lines, 0), ["|"], []);
  245. integer numfields = llGetListLength(statusfields);
  246. statuscode = (integer)llList2String(statusfields, 0); // deleted "integer" for OpenSim
  247. key av = NULL_KEY;
  248. if (numfields >= 7) av = (key)llList2String(statusfields, 6);
  249. // Check if it was successful
  250. if (statuscode == 301) {
  251. if (av != NULL_KEY) {
  252. sloodle_translation_request(SLOODLE_TRANSLATE_IM, [], "alreadyauthenticated", [llKey2Name(av)], av, "regenrol");
  253. return;
  254. }
  255. } else if (statuscode > 0) {
  256. if (av != NULL_KEY) {
  257. sloodle_translation_request(SLOODLE_TRANSLATE_IM, [], "userauthenticated", [llKey2Name(av)], av, "regenrol");
  258. return;
  259. }
  260. } else if (statuscode == -301) {
  261. // No user found with the specified position allocated
  262. // Nothing to do...
  263. sloodle_error_code(SLOODLE_TRANSLATE_SAY, NULL_KEY,statuscode); //send message to error_message.lsl
  264. return;
  265. } else {
  266. if (av != NULL_KEY) {
  267. sloodle_translation_request(SLOODLE_TRANSLATE_IM, [], "userauthenticationfailed:code", [llKey2Name(av), statuscode], av, "regenrol");
  268. return;
  269. } else {
  270. sloodle_debug("Authentication of unknown avatar failed with status code " + (string)statuscode);
  271. sloodle_error_code(SLOODLE_TRANSLATE_SAY, NULL_KEY,statuscode); //send message to error_message.lsl
  272. return;
  273. }
  274. }
  275. }
  276. }
  277. // Please leave the following line intact to show where the script lives in Git:
  278. // SLOODLE LSL Script Git Location: mod/loginzone-1.0/objects/default/assets/sloodle_mod_loginzone-1.0.lslp