network_control.lsl 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // :SHOW:1
  2. // :CATEGORY:Light
  3. // :NAME:Rene Free Lighting System
  4. // :AUTHOR:Rene10957 Resident
  5. // :KEYWORDS: light,lamp,lighting light
  6. // :CREATED:2015-06-11 14:41:21
  7. // :EDITED:2016-03-30 20:29:28
  8. // :ID:1079
  9. // :NUM:1774
  10. // :REV:2.3.2
  11. // :WORLD:Opensim
  12. // :DESCRIPTION:
  13. // Drop this in any prim you want to use as a control panel
  14. // :CODE:
  15. // :LICENSE: CC0 (Public Domain)
  16. // Network control for Rene's Free Lighting System
  17. //
  18. // Author: Rene10957 Resident
  19. // Date: 05-10-2014
  20. //
  21. // Drop this in any prim you want to use as a control panel
  22. // License: CC0 (Public Domain).
  23. // To the extent possible under law, Rene10957 has waived all copyright and related or neighboring rights.
  24. // For more information, see http://creativecommons.org/publicdomain/zero/1.0/.
  25. string title = "Network Control"; // title
  26. string version = "2.3.2"; // version
  27. integer linkSet = TRUE; // LINKSET mode
  28. integer silent = TRUE; // silent startup
  29. // Constants
  30. float cDialogTime = 120.0; // dialog timeout = 2 minutes
  31. float cReplyTime = 1.0; // reply timeout = 1 second
  32. integer remoteChannel = -975103; // remote channel (send)
  33. integer replyChannel = -975105; // reply channel (receive)
  34. string separator = ";;"; // separator for link or region messages
  35. // Variables
  36. float time; // timer interval for multiple timers
  37. float vReplyTime; // variable timeout for node discovery, ranging from 1 to 2 sec.
  38. integer dialogChannel; // dialog channel
  39. integer dialogHandle; // handle for dialog listener
  40. integer replyHandle; // handle for reply listener
  41. key owner; // object owner
  42. key user; // key of last avatar to touch object
  43. list networkNodes; // strided list of network nodes (object key, object name)
  44. list menuButtons; // menu buttons (object names)
  45. // Functions
  46. list orderButtons(list buttons)
  47. {
  48. return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7);
  49. }
  50. float setTimer(float sec)
  51. {
  52. llSetTimerEvent(0.0);
  53. llSetTimerEvent(sec);
  54. return sec;
  55. }
  56. discoverNodes(key id)
  57. {
  58. llWhisper(0, "Discovering network nodes...");
  59. networkNodes = [];
  60. llListenRemove(replyHandle);
  61. replyHandle = llListen(replyChannel, "", "", "");
  62. float pctlag = 100.0 * (1.0 - llGetRegionTimeDilation()); // try to work around time dilation
  63. vReplyTime = cReplyTime + cReplyTime / 100.0 * pctlag; // (more lag = longer timeout)
  64. time = setTimer(vReplyTime);
  65. if (linkSet) llMessageLinked(LINK_ALL_OTHERS, remoteChannel, "PING", llGetKey());
  66. else llRegionSay(remoteChannel, "PING");
  67. }
  68. menuDialog (key id)
  69. {
  70. dialogChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
  71. llListenRemove(dialogHandle);
  72. dialogHandle = llListen(dialogChannel, "", "", "");
  73. time = setTimer(cDialogTime);
  74. llDialog(id, title + " " + version, menuButtons, dialogChannel);
  75. }
  76. default
  77. {
  78. state_entry()
  79. {
  80. owner = llGetOwner();
  81. if (linkSet) version += "-LINKSET";
  82. else version += "-REGION";
  83. if (!silent) llWhisper(0, title + " " + version + " ready");
  84. }
  85. on_rez(integer start_param)
  86. {
  87. llResetScript();
  88. }
  89. touch_start(integer total_number)
  90. {
  91. user = llDetectedKey(0);
  92. if (llGetListLength(networkNodes) == 0) discoverNodes(user);
  93. else menuDialog(user);
  94. }
  95. listen(integer channel, string name, key id, string msg)
  96. {
  97. integer length = llGetListLength(networkNodes) / 2;
  98. if (channel == replyChannel) {
  99. if (llGetOwnerKey(id) != owner) return;
  100. if (length > 8) return;
  101. string shortName = llGetSubString(msg, 0, 23);
  102. networkNodes += [id, shortName];
  103. }
  104. else if (channel == dialogChannel) {
  105. llSetTimerEvent(0);
  106. llListenRemove(dialogHandle);
  107. integer i;
  108. integer index;
  109. key target;
  110. list msgList;
  111. string msgData;
  112. if (msg == "On") {
  113. for (i = 0; i < length; ++i) {
  114. target = llList2Key(networkNodes, i * 2);
  115. msgList = [target, "on", id]; // id = user who opened the dialog
  116. msgData = llDumpList2String(msgList, separator);
  117. if (linkSet) llMessageLinked(LINK_ALL_OTHERS, remoteChannel, msgData, "");
  118. else llRegionSayTo(target, remoteChannel, msgData);
  119. }
  120. menuDialog(id);
  121. }
  122. else if (msg == "Off") {
  123. for (i = 0; i < length; ++i) {
  124. target = llList2Key(networkNodes, i * 2);
  125. msgList = [target, "off", id]; // id = user who opened the dialog
  126. msgData = llDumpList2String(msgList, separator);
  127. if (linkSet) llMessageLinked(LINK_ALL_OTHERS, remoteChannel, msgData, "");
  128. else llRegionSayTo(target, remoteChannel, msgData);
  129. }
  130. menuDialog(id);
  131. }
  132. else if (msg == "Discover") {
  133. discoverNodes(id);
  134. }
  135. else {
  136. index = llListFindList(networkNodes, [msg]);
  137. if (index > -1) {
  138. target = llList2Key(networkNodes, index - 1);
  139. msgList = [target, "menu", id]; // id = user who opened the dialog
  140. msgData = llDumpList2String(msgList, separator);
  141. if (linkSet) llMessageLinked(LINK_ALL_OTHERS, remoteChannel, msgData, "");
  142. else llRegionSayTo(target, remoteChannel, msgData);
  143. }
  144. else {
  145. llInstantMessage(id, "Unexpected error during object key lookup");
  146. menuDialog(id);
  147. }
  148. }
  149. }
  150. }
  151. timer()
  152. {
  153. llSetTimerEvent(0);
  154. if (time == cDialogTime) { // dialog timeout
  155. llListenRemove(dialogHandle);
  156. }
  157. else if (time == vReplyTime) { // remote timeout (variable!)
  158. integer length = llGetListLength(networkNodes) / 2;
  159. if (length == 1) llWhisper(0, "Node discovery completed (" + (string)length + " node)");
  160. else llWhisper(0, "Node discovery completed (" + (string)length + " nodes)");
  161. llListenRemove(replyHandle);
  162. if (length > 0) {
  163. menuButtons = llList2ListStrided(networkNodes, 1, -1, 2);
  164. menuButtons = llListSort(menuButtons, 1, TRUE); // sort ascending
  165. menuButtons = orderButtons(menuButtons); // reverse row order
  166. menuButtons = ["On", "Off", "Discover"] + menuButtons;
  167. if (user) menuDialog(user);
  168. }
  169. }
  170. }
  171. }