Database Signage BRIGADOON-0012
Update Signage in Open Simulator from Database
Loading...
Searching...
No Matches
teleport.php File Reference

Interface between Open Simulator and SQL Database via HTML. More...

Go to the source code of this file.

Functions

 rdConfirmUser ($UseSimDb, $PDO, $PDO1)
 Fucntion to confirm that the object's owner is authorise to run script.
 rdOpenDatabase ($Database, $Host, $Username, $Password)
 Open the Support Database for Use.
 rdProcessTeleport ()
 The public function that does all the work.

Variables

 $parameters = json_encode($_GET)
 $readings = json_decode( $parameters, true )
 $my_teleport = new rdTeleport()

Detailed Description

Interface between Open Simulator and SQL Database via HTML.

Author
River Drifter river.nosp@m.-dri.nosp@m.fter@.nosp@m.auss.nosp@m.iebro.nosp@m.adba.nosp@m.nd.co.nosp@m.m.au
Version
2.2.0
Date
05-January-2026

This script is used to receive commands from the Open Simulator scripts used to control a Teleportation device. The script is triggered by receiving a command from the Open Simulator object running the teleporter(s).

The primary command processed by this script is the "heartbeat" command. This is used to record that the teleporter is still active and should not be remoed as being inoperative. The heartbeat command is also used to update the location and orientation of the teleporter. It will also add new telporters to the database provided that it can be adequately recognised.

Definition in file teleport.php.

Function Documentation

◆ rdConfirmUser()

rdConfirmUser ( $UseSimDb,
$PDO,
$PDO1 )

Fucntion to confirm that the object's owner is authorise to run script.

Parameters
$UseSimDbFlag to indicate if the OpenSim database UserAccounts is to be used
$PDOThe database instance to access the local ls_os_teleport_allowed table
$PDO1The database instance to access the OpenSim UserAccounts table

This routine checks if it is allowed to access the OpenSim database UserAccounts file to determine if the owner of this object is known. If it is, and the user is found, the routine exits.

If the UserAccounts file cannot be used, or the user is not found in that file, the local ls_os_teleport_allowed table is queried. If the owner cannot be found in that table, then the script will abort.

If the user ias found in that table, the routine will set the world where the user exists and whether that user is currently allowed to change the contents of the teleporter table.

Definition at line 42 of file teleport.php.

43 {
44 global $remote_world; global $teleport_allowed; global $readings;
45
46 $not_known = TRUE;
47
48 //============================================================================
49 // If the Simulator Database is available, confirm the teleporter owner is known
50 //============================================================================
51 if ($UseSimDb)
52 {
53 $sql_query = "select PrincipalId from UserAccounts where PrincipalId = :key";
54 $stmt = $PDO1->prepare($sql_query);
55 $stmt->execute(['key' => $readings['owner']]);
56 $is_user = $stmt->fetch(PDO::FETCH_ASSOC);
57 if ($is_user)
58 {
59 $not_known = FALSE;
60 }
61 }
62
63 //============================================================
64 // Check if the User is in the Support Allowed Table
65 //============================================================
66 if ($not_known)
67 {
68 $sql_query = "select * from ls_os_teleport_allowed where teleport_owner = :key and teleport_world = :world";
69 $stmt = $PDO->prepare($sql_query);
70 $stmt->execute(['key' => $readings['owner'], 'world' => $readings['world']]);
71 $is_user = $stmt->fetch(PDO::FETCH_ASSOC);
72 if (!$is_user)
73 {
74 die("FAILURE=BANNED|Teleporter Owner ". $readings['owner']. " is unknown\n");
75 }
76 else
77 {
78 $remote_world = $is_user['teleport_world'];
79 $is_allowed = $is_user['teleport_allowed'];
80 }
81 }
82 }
$readings
Definition teleport.php:472

References $readings.

Referenced by rdProcessTeleport().

Here is the caller graph for this function:

◆ rdOpenDatabase()

rdOpenDatabase ( $Database,
$Host,
$Username,
$Password )

Open the Support Database for Use.

Parameters
$DatabaseThe Name of the Database to Open
$HostThe name of the computer use to conenct to the Database
$UsernameThe username to access the Database
$PasswordThe password to access the database.

If this routine fails, it will case the program to abort and the heartbeat will neither identify itself as being on-line and it will not update the list of destinations.

Definition at line 99 of file teleport.php.

100 {
101 // Data Source Name (DSN) string
102 $dsn = "mysql:host=$Host;dbname=$Database;charset=utf8mb4";
103
104 // Set PDO options for better error handling and security
105 $options = [
106 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Throw exceptions on errors
107 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // Set default fetch mode to associative array
108 PDO::ATTR_EMULATE_PREPARES => true, // Disable emulated prepares for better security
109 ];
110
111 try
112 {
113 // Create a new PDO connection instance
114 $pdo = new PDO($dsn, $Username, $Password, $options);
115 }
116 catch (PDOException $e)
117 {
118 // Catch the exception and display a user-friendly error message
119 // In a production environment, you might log the specific error
120
121 die("FAILURE=DATABASE:Connection failed " . $e->getMessage());
122 }
123
124 return $pdo;
125 }

Referenced by rdProcessTeleport().

Here is the caller graph for this function:

◆ rdProcessTeleport()

rdProcessTeleport ( )

The public function that does all the work.

The function has three main activities:

(1) Insert new teleporters into the database;
(2) Update existing teleporter entries in the database, including the heartbeat time.
(3) Scan teleporter database for potentially dead teleporters and remove if required.

Definition at line 142 of file teleport.php.

143 {
144 global $readings;
145
146 //=================================================================================
147 // Initialise Constants and Pre-set Variables
148 //=================================================================================
149
150 // Define what a NULL KEY actually is.
151 $NULL_KEY = (string)'00000000-0000-0000-0000-000000000000';
152
153 $pdo; $pdo1;
154 $remote_world = "";
155 $teleport_allowed = FALSE;
156
157 //=================================================================================
158 //= Define if the Simulator's working databse will be accessed
159 //=================================================================================
160 $use_sim_db = TRUE;
161
162 //=================================================================================
163 // Set whether addresses outside of the home world of this program are allowed
164 //=================================================================================
165 // If this value is set to FALSE, teleporters out side of the home world of this
166 // simulator are not allowed to access the database.
167 //=================================================================================
168 $allow_outsiders = FALSE;
169
170 //=================================================================================
171 // Connect to the Required Databases
172 //=================================================================================
173
174 global $db; global $host; global $db_username; global $db_password;
175 global $db1; global $host1; global $db1_username; global $db1_password;
176 global $pdo; global $pdo1; global $remote_world; global $readings;
177
178 // Connect to the Support Database
179 $pdo = $this->rdOpenDatabase($db, $host, $db_username, $db_password);
180
181 // Connect to the Simulator's database if it is to be used
182
183 if ($use_sim_db) $pdo1 = $this->rdOpenDatabase($db1, $host1, $db1_username, $db1_password);
184
185
186 //==================================================================================
187 // Confirnm the User & Get World and Permission
188 //==================================================================================
189
190 $this->rdConfirmUser($use_sim_db, $pdo, $pdo1);
191
192 //=================================================================================
193 // Check if this is a Heartbeat Command
194 //=================================================================================
195
196 // Process the Parameters if the Command is "heartbeat"
197 if ($readings['command'] == "heartbeat")
198 {
199 //##############################################################################
200 //# Determine if External Worlds are Allowed to Access the Teleporter Dataabse #
201 //##############################################################################
202 if ($remote_world != "" && (!is_allowed || !$allow_outsiders))
203 {
204 die("FAILURE=BANNED|Teleporter Owner ". $readings['owner']. "@".$readings['world']." is not authorised\n");
205 }
206
207 //############################################################################
208 //# Decode the Array Information that has been pass in. #
209 //############################################################################
210
211 // Decode the Position array into the $position array. 0->x, 1->y, 2->z
212 $position_string = substr($readings['position'], 1, -1); // Remove leading and trailing angle brackets
213 $pos = explode(",", $position_string);
214 $position = array_slice($pos, 0, 3);
215
216 // Decode the Rotation into the rotation array. 0->x, 1->y, 2->z, 3->s
217 $rotation_string = substr($readings['rotation'], 1, -1); // Remove leading and trailing angle breackets
218 $rot = explode(",", $rotation_string);
219 $rotation = array_slice($rot, 0, 4);
220
221 //###################################################################
222 //# Determine if this teleporter is already known #
223 //###################################################################
224
225 // Determine if this heartbeat is from an already known Teleporter
226 $sql_query = "select * from ls_os_teleport where teleport_key = :key";
227 try
228 {
229 $stmt = $pdo->prepare($sql_query);
230 $stmt->execute(['key' => $readings['key']]);
231 $exists = $stmt->fetch(PDO::FETCH_ASSOC);
232 }
233 catch (Exception $e)
234 {
235 echo "FAILURE=IDENTIFY:".$e->getMessage()."\n";
236 }
237
238 //###################################################################
239 //# If this entry is found, then this just an update #
240 //###################################################################
241 if ($exists)
242 {
243 // Get the Substitution Fields
244 $data =
245 [
246 $readings['name'], $readings['owner'], $readings['world'], $readings['region'],
247 $position[0], $position[1], $position[2],
248 $rotation[0], $rotation[1], $rotation[2], $rotation[3],
249 $readings['offset'], $readings['group'], $readings['offsetangle'],
250 $readings['locationinfo'], $readings['vernum'], $readings['localitygroup'],
251 $readings['key']
252 ];
253
254 // Create the command to run to make the update
255 $sql_query = "update ls_os_teleport set ";
256 $sql_query .= "teleport_name = ?, teleport_owner_key = ?, teleport_world = ?, teleport_region = ?, ";
257 $sql_query .= "teleport_region_x = ?, teleport_region_y = ?, teleport_region_z = ?, ";
258 $sql_query .= "teleport_rotation_x = ?, teleport_rotation_y = ?, teleport_rotation_z = ?, teleport_rotation_s = ?, ";
259 $sql_query .= "teleport_offset = ?, teleport_group_key = ?, teleport_front_offset_angle = ?, ";
260 $sql_query .= "teleport_location_info = ?, teleport_version_number = ?, teleport_locality_group = ?, ";
261 $sql_query .= "teleport_heartbeat = CURRENT_TIMESTAMP()";
262 $sql_query .= "where teleport_key = ?";
263
264 // Attempt to Update the Database Entry for this Teleporter
265 try
266 {
267 $stmt = $pdo->prepare($sql_query);
268 $stmt->execute($data);
269 }
270 catch (Exception $e)
271 {
272 echo "FAILURE=UPDATE:".$e->getMessage()."\n";
273 }
274 }
275
276 //###################################################################
277 //# If it wasn't Found, It is a new Teleporter #
278 //###################################################################
279 else
280 {
281 // Test to see if this new item has an name that already exists in the database.
282 // Duplicate name are not permitted to prevent tue users becoming confused. If it
283 // is a duplicate, send a warning that there is a name violation to the owner of
284 // this new teleporter.
285
286 $sql_query = "select * from ls_os_teleport where teleport_name = :name";
287 try
288 {
289 $stmt = $pdo->prepare($sql_query);
290 $stmt->execute(['name' => $readings['name']]);
291 $same_name = $stmt->fetch(PDO::FETCH_ASSOC);
292 }
293 catch (Exception $e)
294 {
295 echo "FAILURE=NAME_MATCH: ".$readings['name'].":Failed with".$e->getMessage()."\n";
296 }
297 if ($same_name)
298 {
299 echo "FAILURE=NAME_MATCH: Existing teleporter data - ";
300 echo $row['teleport_world']."/".$row['teleport_region']."/";
301 echo "<".$row['teleport_region_x'].",".$row['teleport_region_y'].",".$row['teleport_region_z'].">\n";
302 }
303 else
304 {
305 // Get the Substitution Fields
306 $data =
307 [
308 $readings['key'], $readings['name'], $readings['owner'], $readings['world'], $readings['region'],
309 $position[0], $position[1], $position[2],
310 $rotation[0], $rotation[1], $rotation[2], $rotation[3],
311 $readings['offset'], $readings['group'], $readings['offsetangle'],
312 $readings['locationinfo'], $readings['vernum'], $readings['localitygroup']
313 ];
314
315 // Create the command to run to make the insert
316 $sql_query = "insert into ls_os_teleport(";
317 $sql_query .= "teleport_key, teleport_name, teleport_owner_key, teleport_world, teleport_region, ";
318 $sql_query .= "teleport_region_x, teleport_region_y, teleport_region_z, ";
319 $sql_query .= "teleport_rotation_x, teleport_rotation_y, teleport_rotation_z, teleport_rotation_s, ";
320 $sql_query .= "teleport_offset, teleport_group_key, teleport_front_offset_angle,";
321 $sql_query .= "teleport_location_info, teleport_version_number, teleport_locality_group";
322 $sql_query .= ")VALUES(";
323 $sql_query .= "?, ?, ?, ?, ?, ";
324 $sql_query .= "?, ?, ?, ";
325 $sql_query .= "?, ?, ?, ?, ";
326 $sql_query .= "?, ?, ?, ";
327 $sql_query .= "?, ?, ?";
328 $sql_query .= ")";
329
330 // Attempt to Update the Database Entry for this Teleporter
331 try
332 {
333 $stmt = $pdo->prepare($sql_query);
334 $stmt->execute($data);
335 }
336 catch (Exception $e)
337 {
338 echo "FAILURE=INSERT:".$e->getMessage()."\n";
339 }
340 }
341 }
342
343 // Send the Message Preamble
344 echo "EXTRACT_LIST=START\n";
345
346 // Isolate the Individual Flags from the location information
347 $this_group_flag = $readings['locationinfo'] & $GROUP_FLAG;
348 $this_region_flag = $readings['locationinfo'] & $REGION_FLAG;
349 $this_world_flag = $readings['locationinfo'] & $WORLD_FLAG;
350 $this_metaverse_flag = $readings['locationinfo'] & $METAVERSE_FLAG;
351
352 $sql_query = "";
353
354 // Depending on the options selected in the LOCATION_TYPES in the configuration file, this query will
355 // make a selection destinations in the region holding the Teleporter. LOCAL will select all destinations
356 // that have a LOCALITY_GROUP that matches the LOCALITY_GROUP value.
357 $sql_query .= "select * from ls_os_teleport";
358 $sql_query .= " where teleport_key != :key";
359 $sql_query .= " and ((teleport_location_info & :group_flag = :this_group_flag and teleport_locality_group = :group) or teleport_location_info & :region_flag = :this_region_flag)";
360 $sql_query .= " and teleport_location_info & :anon_flag = 0";
361 $sql_query .= " and teleport_region = :region";
362 $sql_query .= " and teleport_world = :world";
363 $sql_query .= " and teleport_version_number != 0";
364
365 $sql_query .= " UNION ";
366
367 // Check if this s a World or Meteverse Location
368 $sql_query .= "select * from ls_os_teleport ";
369 $sql_query .= " where teleport_key != :key";
370 $sql_query .= " and ((teleport_location_info & :world_flag = :this_world_flag and teleport_world = :world)";
371 $sql_query .= " and teleport_location_info & :anon_flag = 0";
372 $sql_query .= " or (teleport_location_info & :metaverse_flag = :this_metaverse_flag and teleport_world != :world))";
373 $sql_query .= " and teleport_version_number != 0";
374
375 // Sort the Responses into Alphbetical Order
376 $sql_query .= " order by teleport_name";
377
378 $parameters = [
379 'key' => $readings['key'],
380 'group_flag' => $GROUP_FLAG,
381 'region_flag' => $REGION_FLAG,
382 'world_flag' => $WORLD_FLAG,
383 'metaverse_flag' => $METAVERSE_FLAG,
384 'anon_flag' => $ANONYMOUS_FLAG,
385 'this_group_flag' => $this_group_flag,
386 'this_region_flag' => $this_region_flag,
387 'this_world_flag' => $this_world_flag,
388 'this_metaverse_flag' => $this_metaverse_flag,
389 'group' => $readings['localitygroup'],
390 'region'=> $readings['region'],
391 'world' => $readings['world']
392 ];
393
394 $this->rdSelectDestinations($sql_query, $parameters, $pdo, $readings['world'], $readings['region']);
395
396 // Send the Message Postamble
397 sleep(1);
398 echo "EXTRACT_LIST=END\n";
399 }
400
401 // If the Command is a Scan, Process the Destination Entries in the Support Database
402 if ($readings['command'] == "scan")
403 {
404
405 //#############################################################################
406 //## Scan the Contents of the Destinations for recent Heartbeats ##
407 //#############################################################################
408 // Remove the Teleporter if they havw exceeded their lifetime without sending
409 // a heartbeat message. Destinations that did not come from a Teleporter, that
410 // manually entered are not affected by this process, but are identified as
411 //being past End Of Life (EOL).
412
413 $world = $readings['world'];
414
415 $SqlQuery = "select * from ls_os_teleport";
416 $SqlQuery .= "where DATE_ADD(teleport_heartbeat, INTERVAL :lifetime HOUR) < CURRENT_TIMESTAMP()";
417 $SqlQuery .= " and teleport_version_number != 0 ";
418 if ($world != '###') $SqlQuery .= " and teleport_world = :world";
419 $SqlQuery .= " order by teleport_name;";
420
421 $Parameters = ['lifetime' => $readings['lifetime'] ];
422 if ($world != '###') $Parameters['world'] = $world;
423
424 try
425 {
426 $stmt = $pdo->prepare($SqlQuery);
427 $stmt->execute($Parameters);
428 $results = $stmt->fetchAll(PDO::FETCH_DEFAULT);
429 }
430 catch (Exception $e)
431 {
432 echo "FAILURE=SCAN:".$e->getMessage()."\n";
433 }
434
435 //#########################################################################################
436 //# Process Each Line #
437 //#########################################################################################
438
439 echo "SCAN_LIST=START\n";
440 echo "//=========================== Date: ".date("Y-m-d H:i:s")."==================\n";
441
442 foreach ($results as $row)
443 {
444 $action_string = "SCANNED";
445 $teleport_name = $row['teleport_name'];
446 $teleport_version = $row['teleport_version_number'];
447
448 // If OnlyScn is FALSE, delete the teleporter from the teleporter table
449 if ($readings['onlyscan'] == 0)
450 {
451 $sql_query1 = "delete from ls_os_teleport where teleport_key = :key";
452 $parameters1 = ['key' => $row['teleport_key'] ];
453 $stmt1 = $pdo->prepare($sql_query1);
454 $stmt1->execute($parameters1);
455 $results1 = $stmt1->fetchAll(PDO::FETCH_DEFAULT);
456 $action_string = "DELETED";
457 }
458 echo $row['teleport_name']."|".$action_string."|";
459 echo "hop://".$row['teleport_world']."/".$row['teleport_region']."/".$row['teleport_region_x']."/".$row['teleport_region_y']."/".$row['teleport_region_z']."\n";
460 }
461 echo "SCAN_LIST=END\n";
462 }
463 }
rdOpenDatabase($Database, $Host, $Username, $Password)
Open the Support Database for Use.
Definition teleport.php:99
$parameters
Definition teleport.php:471
rdConfirmUser($UseSimDb, $PDO, $PDO1)
Fucntion to confirm that the object's owner is authorise to run script.
Definition teleport.php:42

References $parameters, $readings, rdConfirmUser(), and rdOpenDatabase().

Here is the call graph for this function:

Variable Documentation

◆ $my_teleport

$my_teleport = new rdTeleport()

Definition at line 474 of file teleport.php.

◆ $parameters

$parameters = json_encode($_GET)

Definition at line 471 of file teleport.php.

Referenced by rdProcessTeleport().

◆ $readings

$readings = json_decode( $parameters, true )

Definition at line 472 of file teleport.php.

Referenced by rdConfirmUser(), and rdProcessTeleport().