DoctorGibbs' Perl Toolkit for Interacting with the There World

Part 7. Examining Objects Around You

Start up localhost:9999 and point your browser to the URL defined in TherePerlGlobals.pl as
$URLdobs = "http://localhost:9999/ihost";
You get back a long page with lots of information about the objects and avatars around you. Evidently, this page is meant to be read by humans, not parsed as XML. Nevertheless, it is about the most convenient starting point available for sensing the environment around you from a Perl script.

The following subroutine "mines" the page for the localhost:9999 URLs that in turn link to a page of details about every thob (There Object) in your local vicinity.

sub GetThobDetailURLs {
    my @tmp = ();
    $req = HTTP::Request->new('GET', $URLdobs );
    $res = $ua->request($req);
    my $output = $res->content;
    while ($output =~ m/details\?doid=([0-9]+)/g) {
	push @tmp, $URLdetails . $1 ;}
    return @tmp;
}
What does "your local vicinity" mean? This is not entirely clear -- it seems to depend on how busy the There server is as well as other factors. It is almost always farther than you can actually see, and it does not seem to depend on which way you are facing. The number 700 meters occurs in some of the localhost:9999 pages, but that does not seem to be any kind of fixed radius; you can often get details about things farther away. Also, it can take a while -- up to a minute or so -- for more distant objects to "come in" to the ihost table. So, if you are doing a search of any kind, it is a good idea to sleep for a minute at any new location before calling GetThobDetailURLs().

After you call GetThobDetailURLs(), you can send the array that it returns to various other kinds of "data mining" routines. Here's one that looks for objects that can be teleported to, and prints out some relevant information about each (essentially the information shown in the tables of teleport links at http://www.therefan.com).

sub PrintTeleportableDOIDs {
    my @refs = @_;
    my ($ref,$doid,$loc,$tag,$descr,$owner);
    foreach $ref (@refs) {
        $ref =~ m/doid=([0-9]+)$/ ;
        $doid = $1;
        $req = HTTP::Request->new('GET', $ref);
        $res = $ua->request($req);
        $loc = "";
        if ($res->content =~ m/Position<\/td><td>(\([^)]+\))/ ) {$loc = $1;}
        if ($loc) {
    	    $loc =~ m/\(([0-9-]+)\..+,([0-9-]+)\..+,([0-9-]+)\./ ;
	    $loc = "($1,$2,$3)";
        }
        $tag = "";
        $descr = "";
        $owner = "";
        if ($res->content =~ m/signScript=/) {
	    $tag = "Sign";
            if ($res->content =~ m/ownerDoid=([0-9]+)/) {$owner=$1;}
	}
        if ($res->content =~ m/zoneHouseName=\"([^"]+)\"/) {
           if ($1 ne "None") {$tag = "$1";}
           if ($res->content =~ m/code=52 textSlot=\{text=\"([^\"]+)\"/)
             {$tag = $1;}
           if ($res->content =~ m/code=50 textSlot=\{text=\"([^\"]+)\"/)
             {$descr = $1;}
        }
        if ($res->content =~ m/PortaZone/) {
            $tag = "PortaZone";
            if ($res->content =~ m/ownerDoid=([0-9]+)/) {$owner=$1;}
        }
        if ($tag) {  print "$doid $loc <$tag> <$descr> <$owner>\n";}
    }
}
So what's going on here? We're snarfing up all the detail information about each thob, then examining it for indications that the thob is a house, a portazone (PAZ), or a sign. If it's a house, we "read" the first two lines of the sign out in front of it, generally containing its address and it's owner's description of the property (forgettable strings like "Bliss and Tony's Love Nest"). If it's a PAZ, about all we can snarf is its owner's doid number. If it's a sign, we could read its text, but we don't bother!

Well, I admit that PrintTeleportableDOIDs is actually a kludge. The right way to do this would be to parse out the structured data that is in the returned string, and then mine it more systematically. But it's in some Therean format, not XML, and I was too lazy to write a real parser. Exercise for the reader: Either write a parser, or else write a converter to XML so that XML::Simple::XMLin() can then be used. Then clean up the above routine!

It's also fun to examine all the avatars in your vicinity. Here's a routine that takes the array returned by GetThobDetailURLs as an argument, and looks at each thob. If it's an "Avatar3" (I've never seen any other kind of avatar!) it goes out to the WPTC server and retrieves that person's profile. In this case, the information does come back as a big XML string, and we can parse it with XMLin(). Then we pull out the avatar's name, gender, marital status, age, and country, and print them.

sub PrintDOIDdetails {
    my @refs = @_;;
    my ($ref,$doid,$profile,$name,$married,$gender,$age,$response,$country);
    foreach $ref (@refs) {
        $ref =~ m/doid=([0-9]+)$/ ;
        $doid = $1;
        $req = HTTP::Request->new('GET', $ref);
        $res = $ua->request($req);
	if ($res->content =~ m/Clide<\/td><td>Avatar3<\/td>/ ) {
	    $response = GetWebappsURL($URLprofileDoid . $doid,
		$myavname,$mypassword);
	    $profile = XMLin($response, ForceArray => 0);
	    $name = $profile->{profile}->{attrib}->{AvatarName}->{value};
	    $gender = $profile->{profile}->{attrib}->{gender}->{value};
	    $married = $profile->{profile}->{attrib}->{maritalstatus}->{value};
	    $age = $profile->{profile}->{attrib}->{age}->{value};
	    $country = $profile->{profile}->{attrib}->{country}->{value};
	    $lout = "$name $gender $age $married $country\n";
	    if ($lout =~ m/\S/) {print $lout;}
	}
    }
}
If you put GetThobDetailURLs and the above routine in an endless loop (put a 15 second sleep between iterations, please!), then you can have a window going that gives you the basic info about everyone you meet, even before you meet them (because they usually are detected well before you can see them). Good for conversation starters. If you like to be alone on some isolated island, the routine is a good intrusion alarm, since avatars in vehicles show up while they are still far away. Then you can IM them and tell them to get lost.

By the way, take a look sometime at all the XML that is returned by the above calls to WPTC. It has a lot more stuff than displays in the HTML version, things like what membership plan the person is on, and how much they are paying. (No, it doesn't have their real-life identity, or email address!)