network_control.lsl 5.8 KB

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