network_control_region.lsl 5.8 KB

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