description
The avatar wears an invisible item containing the script.
The script contacts a webserver at periodic intervals, hitting the `reportLocation.php` file.
That communication always includes the object's location, position, and velocity.
So, all the script has to do is store that in a database.
Later, going to `joinMe.php` in a browser will retrieve the last known position and forward you to the corresponding slurl ("second life URL").
Note: to use these scripts, you need to fill in the appropriate DATABASE_SERVER, DATABASE_USERNAME, DATABASE_NAME, WEB_SERVER, and OBJECT_NAME.
demo
reportLocation.lsl
key http_request_id;
float gap = 30.0;
integer go()
{
http_request_id = llHTTPRequest("http://WEB_SERVER/reportLocation.php", [], "");
return 0;
}
default
{
state_entry()
{
go();
llSetTimerEvent(gap);
}
timer()
{
go();
llSetTimerEvent(gap);
}
}
reportLocation.php
<?PHP
$headers = apache_request_headers();
$objectName = $headers['X-SecondLife-Object-Name'];
$objectKey = $headers['X-SecondLife-Object-Key'];
$region = $headers['X-SecondLife-Region'];
list($regionName, $coordX, $coordY) = split('[(),]', $region);
$regionName = trim($regionName);
$coordX = trim($coordX);
$coordY = trim($coordY);
$position = $headers['X-SecondLife-Local-Position'];
list($nullA, $posX, $nullB, $posY, $nullC, $posZ, $nullD) = split('[() ,]', $position);
$rotation = $headers['X-SecondLife-Local-Rotation'];
list($nullA, $rotA, $nullB, $rotB, $nullC, $rotC, $nullD, $rotD, $nullE) = split('[() ,]', $rotation);
$velocity = $headers['X-SecondLife-Local-Velocity'];
list($nullA, $velX, $nullB, $velY, $nullC, $velZ, $nullD) = split('[() ,]', $velocity);
$ownerName = $headers['X-SecondLife-Owner-Name'];
$ownerKey = $headers['X-SecondLife-Owner-Key'];
// open
$link = mysql_connect('DATABASE_SERVER', 'DATABASE_USERNAME') or die('Could not connect: ' . mysql_error());
mysql_select_db('DATABASE_NAME') or (die('Could not select database'));
// slAvatar
$query = "SELECT id FROM slAvatar WHERE slKey = '$ownerKey';";
$result = mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$count = mysql_num_rows($result);
if ($count == 0) {
$query = "INSERT INTO slAvatar (slKey,name) VALUES ('$ownerKey','$ownerName');";
mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$avatarId = mysql_insert_id();
} else {
$line = mysql_fetch_array($result, MYSQL_ASSOC);
$avatarId = $line['id'];
}
// slRegion
$query = "SELECT id,name FROM slRegion WHERE coordX = '$coordX' AND coordY = '$coordY';";
$result = mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$count = mysql_num_rows($result);
if ($count == 0) {
$query = "INSERT INTO slRegion (name,coordX,coordY) VALUES ('$regionName','$coordX','$coordY');";
mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$regionId = mysql_insert_id();
} else {
$line = mysql_fetch_array($result, MYSQL_ASSOC);
$regionId = $line['id'];
if ($regionName != $line['name']) {
$query = "UPDATE slRegion SET name = '$regionName' WHERE coordX = '$coordX' AND coordY = '$coordY';";
mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
}
}
// slObject
$query = "SELECT id FROM slObject WHERE name = '$objectName';";
$result = mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$count = mysql_num_rows($result);
if ($count == 0) {
$query = "INSERT INTO slObject (slKey,name,ownerId) VALUES ('$objectKey','$objectName',$avatarId);";
mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$objectId = mysql_insert_id();
} else {
$line = mysql_fetch_array($result, MYSQL_ASSOC);
$objectId = $line['id'];
if ($objectKey != $line['slKey']) {
$query = "UPDATE slObject SET slKey = '$objectKey' WHERE name = '$objectName';";
mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
}
}
// slObjectLocation
$query = "INSERT INTO slObjectLocation (objectId,regionId,posX,posY,posZ,rotA,rotB,rotC,rotD,velX,velY,velZ) VALUES ($objectId,$regionId,'$posX','$posY','$posZ','$rotA','$rotB','$rotC','$rotD','$velX','$velY','$velZ');";
mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$query = "DELETE FROM slObjectLocation WHERE insertDateTime < DATE_SUB(NOW(),INTERVAL 1 HOUR);";
mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
// close
mysql_free_result($result);
mysql_close($link);
print 'ok';
?>
joinMe.php
<?PHP
// open
$link = mysql_connect('DATABASE_SERVER', 'DATABASE_USERNAME') or die('Could not connect: ' . mysql_error());
mysql_select_db('DATABASE_NAME') or (die('Could not select database'));
// slObjectLocation
$query = "SELECT ol.posX,ol.posY,ol.posZ,r.name,a.name AS avatar FROM slObject o JOIN slObjectLocation ol ON ol.objectId = o.id JOIN slRegion r ON r.id = ol.regionId JOIN slAvatar a ON a.id = o.ownerId WHERE o.name = 'OBJECT_NAME' ORDER BY insertDateTime DESC LIMIT 1;";
$result = mysql_query($query) or (die("Query: $query<br/>\nError: " . mysql_error()));
$line = mysql_fetch_array($result, MYSQL_ASSOC);
$location = str_replace(" ", "%20", $line['name']);
list($posX) = split('[.]', $line['posX']);
list($posY) = split('[.]', $line['posY']);
list($posZ) = split('[.]', $line['posZ']);
$avatar = str_replace(" ", "%20", $line['avatar']);
header('Location: http://slurl.com/secondlife/'.$location.'/'.$posX.'/'.$posY.'/'.$posZ.'/?title='.$avatar.'%27s%20last%20known%20position');
// close
mysql_free_result($result);
mysql_close($link);
?>