Database Teleporter BRIGADOON-0009
An Open Simulator Teleporter using a central database.
Loading...
Searching...
No Matches
brigadoon_teleporter.osl
Go to the documentation of this file.
1*! \file brigadoon_teleporter.osl
2 * \brief SCript to send a Heartbeat signal to the Teleport Database
3 * \version 1.2.0
4 * \date 25-December-2025
5 * \author River Drifter @ little-sense.au:9000
6 * \email river_drifter@aussiebroadband.com.au
7 *
8 *
9 * NOTE: The file extension ".osl" indicates the script uses the Open Simulator Script
10 * language (OSSL) and will not function in the Second Life environment. If the script
11 * will function using just the Linden Scripting Language (LSL), it will have a a file
12 * extension of ".lsl".
13 *
14 */
15
20 string VERSION_STRING = "2.1.0";
21
26string CONFIG_NOTECARD_NAME = "brigadoon_teleporter.config";
27
32string CONFIG_DESTINATIONS_NAME = "teleport_destinations.config";
33
42 integer LOCAL_TELEPORT_FORCE = TRUE;
43
50string COMMENT_PREAMBLE = "//";
51
57
62//string DATABASE_INTERFACE = "DATABASE_INTERFACE";
63
68string LOCATION_NAME = "LOCATION_NAME";
69
77float TIME_TO_DECIDE = 60.0;
78
83float TIMER_OFF = 0.0;
84
97
105
106/* \var list menu_list
107 * \brief This of menu items to be shown
108 *
109 *
110 */
112
119
125
131
137
143
149
156
162
163/* \var integer comms_channel
164 * \brief Communication Channel used for the Menu
165 *
166 */
168
174
175/* \var integer station_base
176 * \brief offset in the destination list to start listing
177 *
178 */
179integer station_base = 0;
180
186
195
201
207integer LOCAL_FLAG = 1;
208
214integer REGION_FLAG = 2;
215
221integer WORLD_FLAG = 4;
222
228integer METAVERSE_FLAG = 8;
229
240integer ANONYMOUS_FLAG = 16;
241
248
259
267string rdLocInfo2String(integer LocationInfo, integer Index)
268{
269 string location_area = "";
270
271 if ((LocationInfo & LOCAL_FLAG) != 0) location_area = destination_group[Index];
272 else if ((LocationInfo & REGION_FLAG) != 0) location_area = destination_region[Index];
273 else if ((LocationInfo & WORLD_FLAG) != 0) location_area = destination_region[Index];
274 else if ((LocationInfo & METAVERSE_FLAG) != 0) location_area = destination_world[Index];
275 return " [" + location_area + "]";
276}
277
286{
287 integer random_value = 0x80000000 | (integer)llFrand(65536) | ((integer)llFrand(65536) << 16);
288 return(random_value);
289}
290
298{
299 list button_list;
300 menu_list = [];
301
302 // Add the back button if necessary
303 if (station_base > 0) button_list += "<<"; else button_list += " ";
304
305 // Add Done Button
306 button_list += "DONE";
307
308 // Add the Forward button, if necessary
309 if (station_list_size > (station_base + DIALOG_STATION_LIMIT)) button_list += ">>"; else button_list += " ";
310
311 // Now select the next (up to) nine (9) locatiions to display on the menu
312 string menu_header = "Destinations Available from " + location_name + "\n";
313 integer index;
314 for (index = 0; index < DIALOG_STATION_LIMIT; ++index)
315 {
316 // Increase the menu number to match the actual number in the destination list, rather than menu number
317 integer station_pos = index + station_base;
318 if (station_pos < station_list_size)
319 {
320 // Get the type of location this destination is
321 integer loc_info = (integer)llList2String(destination_loc_type, station_pos);
322
323 // Get name of the destination and the type of location it is
324 string item_name = llUnescapeURL(llList2String(destination_name, station_pos)) + rdLocInfo2String(loc_info, station_pos);
325 string index_string = (string)(station_pos + 1);
326
327 // Add the Index, Name and location type to the menu header
328 menu_header += "[" + index_string + "] " + item_name + "\n";
329
330 // Add the index to the Buuton List to be displayed
331 button_list += index_string;
332
333 // Add the index to the line that will be scanned to match selections
334 menu_list += index_string;
335 }
336
337 // If there aren't enough destinations to fill the nine (9) spaces use blanks
338 else
339 {
340 // Add to the button list, but not the menu list as we don'r want matches to empty buttons
341 button_list += " ";
342 }
343 }
344
345 // Display the Dialog Menu
346 llDialog(User, menu_header, button_list, comms_channel);
347}
348
356rdDoTeleport(key Agent, integer Index)
357{
358 // Get information about the Destination Location
359 string the_world = llList2String(destination_world, Index);
360 string the_region = llList2String(destination_region, Index);
361 vector the_landing = (vector)llList2String(destination_location, Index);
362 vector the_look_at = (vector)llList2String(destination_look_at, Index);
363
364 // Update the current location of the Teleporter to select correct Teleportation Routine
365 location_region = llGetRegionName();
366 vector location_position = llGetPos();
367
368 // If the Destination is not in this simulator, use a hop command to get there
369 if (location_world != the_world)
370 {
371 osTeleportAgent(Agent, the_world + ":" + the_region, the_landing, the_look_at);
372 }
373
374 // If the Destination is not in this Region, use a Teleport command that specifies the Region
375 else if (location_region != the_region)
376 {
377 osTeleportAgent(Agent, the_region, the_landing, the_look_at);
378 }
379
380 // If the destination is in this region, but not the landing location of this Teleporter us a local Teleport
381 else if (location_position != the_landing)
382 {
383 osTeleportAgent(Agent, the_landing, the_look_at);
384 }
385}
386
392{
393 // Clear the Teleportation Lists
397
398 // Loop though Destination Configuration File
399 integer list_length = osGetNumberOfNotecardLines(CONFIG_DESTINATIONS_NAME);
400 integer index = 0;
401 do
402 {
403 // Get the Line
404 string trimmed_line = llStringTrim(osGetNotecardLine(CONFIG_DESTINATIONS_NAME, index), STRING_TRIM);
405
406 // Skip comment lines and blank lines
407 if ( (llGetSubString(trimmed_line, 0, COMMENT_PREAMBLE_LENGTH - 1) != COMMENT_PREAMBLE) && (trimmed_line != "") )
408 {
409 // Split the Teleportation Destination COmponents out.
410 list destination = llParseString2List(trimmed_line, ["|"], []);
411 destination_name += (string)destination[0];
412 destination_world += (string)destination[1];
413 destination_region += (string)destination[2];
414 destination_location += (string)destination[3];
415 destination_look_at += (string)destination[4];
416 destination_loc_type += (string)destination[5];
417 destination_group += (string)destination[6];
418 }
419 }
420 while (++index < list_length);
421
422 // Set the Size of teh Destination List for the Menu
423 station_list_size = llGetListLength(destination_name);
424}
425
434{
435 // Get the location of the current world
436 location_world = llGetSubString(osGetGridHomeURI(), 7, -1);
437
438 // Get a Communications Channel. This can been overridden in the basic configuration
440
441 // Read the Configuration File into a List of Lines
442 string config = osGetNotecard(CONFIG_NOTECARD_NAME);
443 list config_data = llParseString2List(config, ["\n"], []);
444
445 // Process each line in the Configuration Data
446 integer index = 0;
447 integer list_length = llGetListLength(config_data);
448 for (; index < list_length; ++index)
449 {
450 // Trim line of Leading and Trailing Spaces
451 string trimmed_line = llStringTrim(llList2String(config_data, index), STRING_TRIM);
452
453 // Only Process lines that are not a comment line or blank
454 if ( (llGetSubString(trimmed_line, 0, COMMENT_PREAMBLE_LENGTH - 1) != COMMENT_PREAMBLE) && (trimmed_line != "") )
455 {
456 // Parse Line for a Configuration Field.
457 list key_value = llParseString2List(trimmed_line, ["="], []);
458
459 // Fold the Trimmed Key into upper case, to eliminate errors where the case is wrong in the config file.
460 string key_object = llToUpper(llStringTrim(llList2String(key_value, 0), STRING_TRIM));
461
462 // Trim the Value to remove leading and training spaces
463 string value_object = llStringTrim(llList2String(key_value, 1), STRING_TRIM);
464
465 // Process the Key-Value Pairs to Set Configuration
466 if (key_object == LOCATION_NAME) location_name = value_object;
467 }
468 location_region = llGetRegionName();
469 }
470
471 // Initial Read of the teleportation Destnation List
473}
474
479default
480{
487 state_entry()
488 {
489 // Configure the Teleporter Script
491 }
492
499 touch_start(integer TotalNumber)
500 {
501 // Remove any listen handlw
502 llListenRemove(listen_handle);
503
504 // Find out who touched this
505 key user = llDetectedKey(0);
506
507 // Get a new listener & show the Menu to the User
508 listen_handle = llListen(comms_channel, "", user, "");
510
511 // Set a time to ensure the menu is onolu active for a short time
512 llSetTimerEvent(TIME_TO_DECIDE);
513 }
514
526 listen(integer Channel, string Name, key Id, string Message)
527 {
528 integer found_index = -1;
529
530 // If this was not the same user as before , reset to the start of the list
531 if (Id != last_user)
532 {
533 station_base = 0;
534 last_user = Id;
535 }
536
537 // Resert the Lilst to the start if the user is bombing out of the destionation selection
538 if ((Message == "DONE") || (Message == "OK") || (Message == " ") || (Message == "Ignore"))
539 {
540 station_base = 0;
541 return;
542 }
543
544 // If the selection is go back a page, reduce the base pointer by the number of items on a page
545 if (Message == "<<")
546 {
549 }
550
551 // If the selection is to go forward a page, increase the base pointer by the number of items on a page
552 else if (Message == ">>")
553 {
556 }
557
558 // Othereise this ia s destination selection, so process it
559 else
560 {
561 // Scan the list for a match
562 integer index;
563 for (index = 0; index < station_list_size; index++)
564 {
565 // Check if there is a match in the list of items displayed
566 if (llList2String(menu_list, index) == Message)
567 {
568 // Get the actual index into the entire list
569 found_index = index + station_base;
570
571 // End the loop by going to the end index
572 index = station_list_size;
573 }
574 }
575
576 // If a Match was found, Teleport the user to the Destination & reset Dialog parameters
577 if (found_index != -1) {rdDoTeleport(Id, found_index); station_base = 0; last_user = NULL_KEY;}
578 }
579 }
580
588 changed(integer Change)
589 {
590 // If the Inventory has changed, assume it will be the configuration notecard and/or destination notecard
591 if (Change == CHANGED_INVENTORY)
592 {
593 // A Full Reset can cause a race condition when accessin the destination file controlled by the heartbeat script.
594 // Give a bit of time to stop the script not being able to see the destination file immediately after it is rewritten.
595 llSleep(0.25);
596
597 // Reest script and reload Destinations
599 }
600 }
601
610 timer()
611 {
612 llListenRemove(comms_channel);
613 llSetTimerEvent(TIMER_OFF);
614 station_base = 0;
615 }
616}
integer LOCAL_TELEPORT_FORCE
Flag about whether Local teleport is used for all in-world regions.
integer REGION_FLAG
Number value of REgion Location flag.
integer REMOTE_UPDATE_FLAG
integer COMMENT_PREAMBLE_LENGTH
THe number of characters in the comment preamble.
list destination_look_at
string CONFIG_DESTINATIONS_NAME
The automatically generated list of teleporter destinations.
string location_name
The display name of the current location.
string CONFIG_NOTECARD_NAME
The name of the notecard containing the Teleport's Configuration.
string LOCATION_NAME
THe Key Value for defining hte name of the location in the Config notecard.
integer rdCalcCommsChannel()
find a pseudo random communications channel number
list menu_list
integer ANONYMOUS_FLAG
This flag designates the teleporter as anonymous.
list destination_group
Group to which the Location belongs.
float TIMER_OFF
Settings a Zero Time will turn off the Timer.
list destination_location
integer METAVERSE_FLAG
Number value of Metaverse Location flag.
list destination_region
The list of Teleport region names.
string location_region
Region holding the Teleporter.
integer EXTENDED_LOCAL_FLAG
Flag for Extended Local teleports.
integer comms_channel
float TIME_TO_DECIDE
Time a Menu remains active.
integer station_list_size
The total number of Destinations available.
rdInitialiseTeleporter()
Initialise or re-initialise the Teleporter.
string VERSION_STRING
The Current version of the software.
rdShowStationDialog(key User)
Display the Destination Teelport Menu.
integer WORLD_FLAG
Number value of World Location flag.
list destination_world
The list of Teleport world addresses.
rdReadDestinationList()
Read the list of Teleportation Destinations from the Notecard.
string COMMENT_PREAMBLE
Preamble for a comment line in the configuration file.
list destination_name
The list of Teleport location names.
string rdLocInfo2String(integer LocationInfo, integer Index)
integer LOCAL_FLAG
Number value of Local Location flag.
integer listen_handle
rdDoTeleport(key Agent, integer Index)
Select the Correct Teleportation Routine.
key last_user
the last user of the teleport menu
string location_world
The Teleporter Location's World.
integer station_base
integer DIALOG_STATION_LIMIT
The hard maximum number of Destinations on any menu page.
list destination_loc_type
The list of location types.