366 lines
35 KiB
PHP
366 lines
35 KiB
PHP
|
<?php
|
||
|
/***********************************************************************
|
||
|
* Script (c) Kubwa (https://kubwa.de)
|
||
|
*
|
||
|
* This script was release under BSD license.
|
||
|
* You are free to use, share or change this code as you wish. This
|
||
|
* header must be kept intact.
|
||
|
***********************************************************************/
|
||
|
|
||
|
class GridUser
|
||
|
{
|
||
|
//Predfined images
|
||
|
private $ErrorImage = "/9j/4AAQSkZJRgABAQEAYABgAAD/4QBoRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAARAAAATgAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMi4xMAAA/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgBAAEAAwEhAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A+y6KACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACkoAhmvre3VmlnjjCjJLMBgVjy+PvDUDbZNf01G9GukH9aALVn4r0XUmAtdVs7g+kU6t/I1pJKkn3HVvoc0APooAKKACigAooAKKACigAooAKKACigAooAKKACigAqC8vrfT7d57qaO3hQZaSRgoH4mgDxzxl+05o2jtJb6LA2qzrkeafliB/ma8X8SfHTxd4klctqJsYWGPJsxsUfj1/WgDiLvVLy/kMlzdTTuerSSFj+tVtxPU5oAVZGXoxH0NbGk+NNd0Jw1jqt1b46BZTj8qAPTvCP7Tuu6SyRazDHqtv0MgGyUD6jg/lXvPgj4seHvHkYFjeLFdgZa1n+WQfQd/woA7KigAooAKKACigAooAKKACigAooAKKACigAooA5L4hfErSfh5prT30u+6YfubVOXkP9B7mvkvx/wDFTW/iBeM95OYbMH93aQkhFHv6mgDjaKACigAooAKkt7mWzmWWCRopVOVdDgigD3r4U/tFzWbQaX4mczQZ2pffxL/v+o96+kLW6hvbeOeCRZoZBuV0OQR6g0AS0UAFFABRQAUUAFFABRQAUUAFFABRQAVyPxK+IVl8PPDst7OyvdMNtvb55kb/AAHU0AfGHibxNf8Ai3V59R1Gdpp5GzyeFHYAdhWTQA+GGS4lWOJGkkY4CqMk16t4J/Zz8Q+Jo1ub8ro9o3K+cMyN9F7fjQB63on7MfhTTwpvWudScdQ8mxT+C4P610sPwQ8EwLtXQoSP9pmY/qaAKl/+z/4Ivo2A0n7O5GBJDM4I/DOP0rhPEn7KdpIrPomqSQvj5YrobgTj1H+FAHh/i74e674JuDFqtjJEmcLMvzRt9GFc5QAV7H8DvjNN4UvYtG1aYvpEzbUkfnyGPv8A3aAPq2ORZo1dGDowyGU5BFPoAKKACigAooAKKACigAooAKKACigCvfX0Om2U91cOI4IUMjs3QADJNfEnxR8f3PxB8UT3sjMLSMmO2i7IgPH4mgDj61PDXhu+8Waxb6bp0Xm3EzYHoo7knsKAPrf4X/BbSvANrHPMiX2sEfPcsMhPZAen1616PQAtFABSE45PAoA+evj78ZrZoJ/DekGK5dgUurggME9VX396+cqACigD6g/Zv+JZ1rT28O38mbq1Xdbux5eP0+or3OgAooAKKACigAooAKKACigAooAKKAPEP2nPG39k+H4NBt5MXF8d8oHURg/1P8jXy3QBJbwSXU0cMSl5JGCqo6kmvsn4MfC+DwB4fjlnRX1e6UNPJ/d7hB9KAPRqKACigBOleA/HL45ixWbQPD1xm4OUubuM/c9VU+vvQB82MxdizEsxOST3pKALraLfR6SmptayCweTyluCvylsZxmqVAGv4T8RXPhPxDY6patiW3kDY7MO4P1Ffd+i6pDrmk2l/btuhuI1kU/UZoAu0UAFFABRQAUUAFFABRQAUUAFITgZoA+JfjP4kk8TfELVJmdmigk+zxA/wqpxgfjk/jXD0Aew/s1+CU8QeLJNVuU3W2mgOg7GQ/d/Lk/lX1lQAUUAFJ0oA8B+OXxzFiJtA8Pz/wCkcpc3aH7nqqn196+bGYuxZiSxOSTQAlej/CH4RXfxD1FbicGDRoW/eyngv/sr70AfTniv4d6bq/gO58PWtrHbwLF/o6IMBXA+U/nXxFeWkthdzW06GOaFzG6sOQQcEUAQ19Y/sx+Jm1jwTNp0r7pdPm2Ln/nm3I/Xd+VAHsVFABRQAUUAFFABRQAUUAFFABWf4g1JdH0LUL9xuW2geUgHGdqk0AfAN3cPeXU08jF5JHLszdSSc1FQB9f/ALN+gJpPw4t7rH76/keZ+OQAdoH5DP416pQAUUAJXgHxy+OQsRP4f8Pz/wCk8pc3cZ+56qp9fegD5tZi7FmJZicknvSUAekfCP4QXnxEvhcTBrbR4WHmTEH95/sr719faPo9poOnQWNjAlvbQqFVEGP8mgC7Xxf8etFXRfiVqQRQqXG2cAD+8Of1zQB55Xt37K+qG38W6hZZ+We23Y91I/xoA+paKACigAooAKKACigAooAKKACuU+Klw1t8OfELqASbORefdSP60AfC9FAH3X8MIxD8PfD6qAB9jj6f7orqKACk6daAPAPjn8chYrP4f0CbNx9y5u4z9z1VT6+9fNrMXYsxLMTkk96AEr0f4Q/CK7+Imoie4D2+jQt+9mxjzP8AYX3/AJUAfYGkaTa6HpsFjZQrBbQqERFGABVygAr5X/aqhWPxtp8gABeyGffDtQB4pXqn7NczR/E23VekkEit9MZ/pQB9f0UAFFABRQAUUAFFABRQAUUAFcx8Trb7X8PfEMff7FKwx7KT/SgD4TooA+5fhLfR6h8N9AlibcotUjP+8o2n9Qa66gBM45PArwD45/HIWKz+HtAmzcH5Lm8jP3PVVPr6mgD5tZi7FmJZicknvSUAeifCT4R3nxE1ISyh7bSIWHmz4+//ALK+/wDKvsHRtGtNA02CxsYVt7aFdqoooAvUUAFfKH7Ul4lx4+tol6wWaq31LMf5EUAeN16v+zTbtN8SonHSO3kY/kB/WgD68ooAKKACigAooAKKACigAooAKhvLdLq0mhkVXSRCrKwyCCOhoA/P/WtPfSdYvbKTG+3meM46cEiqVAH1T+y74jGoeD7nSnfMljMSik/wNz/PP517STjk8CgDwD45fHIWSz+H9AmDTkbLm7jP3
|
||
|
private $BlockedImage = "/9j/4AAQSkZJRgABAQEAYABgAAD/4QBoRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAARAAAATgAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMi4xMAAA/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgBAAEAAwEhAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A+y6KACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACigAooAKKACig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
|
||
|
private $UpdateImage = "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
|
||
|
|
||
|
private $Uuid;
|
||
|
private $HomeUri;
|
||
|
private $FirstName;
|
||
|
private $LastName;
|
||
|
private $HomeGrid;
|
||
|
private $BirthUnix;
|
||
|
private $ServiceUris;
|
||
|
private $ProfileImageUuid;
|
||
|
private $ProfileImageBlob;
|
||
|
private $ProfileAbout;
|
||
|
private $LastRequest;
|
||
|
private $LastUpdate;
|
||
|
private $UserTitle;
|
||
|
private $HomeRegionUuid;
|
||
|
private $HomeRegionName;
|
||
|
private $HomeRegionUri;
|
||
|
private $HomeRegionPos;
|
||
|
private $OSHeaders = array();
|
||
|
|
||
|
private $MySql;
|
||
|
private $WorkingPath;
|
||
|
private $ImagesPath;
|
||
|
|
||
|
public function __construct($Uuid, $HomeUri, $ImagesPath)
|
||
|
{
|
||
|
if (empty($Uuid) || empty($HomeUri))
|
||
|
{return;}
|
||
|
$this->Uuid = $Uuid;
|
||
|
$this->HomeUri = $HomeUri;
|
||
|
$this->WorkingPath = realpath(dirname(__FILE__));
|
||
|
$this->ImagesPath = $ImagesPath;
|
||
|
$this->MySql = new MySql($GLOBALS["CONFIG"]["mysql"]["user"], $GLOBALS["CONFIG"]["mysql"]["pass"], $GLOBALS["CONFIG"]["mysql"]["db"], $GLOBALS["CONFIG"]["mysql"]["server"]);
|
||
|
|
||
|
//Process OpenSim header fields
|
||
|
foreach ($_SERVER as $k => $v)
|
||
|
{
|
||
|
if (substr($k, 5, 13) == "X_SECONDLIFE_")
|
||
|
{$this->OSHeaders[substr($k, 18)] = $v;}
|
||
|
}
|
||
|
|
||
|
//Remove cached profile images after 60 days but process this cleanup every 5 days only
|
||
|
if ($this->HelpValue("IMAGE.LAST.CLEANTIME") + 86400 * 5 < time())
|
||
|
{
|
||
|
$this->HelpValue("IMAGE.LAST.CLEANTIME", time());
|
||
|
$Files = glob($this->ImagesPath."/UserImage/*.jpg");
|
||
|
foreach ($Files as $File)
|
||
|
{
|
||
|
if (is_file($File) && time() - filemtime($File) >= 86400 * 60)
|
||
|
{unlink($File);}
|
||
|
}
|
||
|
//Also delete the cached metadata
|
||
|
$this->MySql->query("DELETE FROM userdata WHERE lastreq < {0}", array(time() - 86400 * 60));
|
||
|
}
|
||
|
|
||
|
//Process pre defined images
|
||
|
if (!file_exists($this->ImagesPath."/UserImage/00000000-0000-0000-0000-000000000000.jpg"))
|
||
|
{file_put_contents($this->ImagesPath."/UserImage/00000000-0000-0000-0000-000000000000.jpg", base64_decode($this->ErrorImage));}
|
||
|
if (!file_exists($this->ImagesPath."/UserImage/00000000-0000-0000-0000-000000000001.jpg"))
|
||
|
{file_put_contents($this->ImagesPath."/UserImage/00000000-0000-0000-0000-000000000001.jpg", base64_decode($this->BlockedImage));}
|
||
|
if (!file_exists($this->ImagesPath."/UserImage/00000000-0000-0000-0000-000000000002.jpg"))
|
||
|
{file_put_contents($this->ImagesPath."/UserImage/00000000-0000-0000-0000-000000000002.jpg", base64_decode($this->UpdateImage));}
|
||
|
|
||
|
//Do the magic
|
||
|
$this->LastRequest = time();
|
||
|
if ($this->ExistsInCache()) //User exists in cache?
|
||
|
{
|
||
|
$this->GetFromCache(); //Load everything from cache
|
||
|
if ($this->LastUpdate + 3600 * 4 < time())
|
||
|
{
|
||
|
$this->GetFromInternet(); //Get all the data from the users grid
|
||
|
if ($this->HomeGrid == "Unknown" &&
|
||
|
$this->FirstName == "Unknown" &&
|
||
|
$this->LastName == "User")
|
||
|
{$this->GetFromCache();}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{$this->GetFromInternet();}
|
||
|
}
|
||
|
|
||
|
//The user might be unwanted in our system. See mysql table "bans"
|
||
|
private function IsUnwanted($CheckList)
|
||
|
{
|
||
|
$AllBans = $this->MySql->query("SELECT * FROM bans");
|
||
|
while ($Ban = $AllBans->fetch())
|
||
|
{
|
||
|
for ($i = 0; $i < count($CheckList); ++$i)
|
||
|
{
|
||
|
if (stripos($CheckList[$i], $Ban["banvalue"]) !== false)
|
||
|
{
|
||
|
$this->MySql->query("UPDATE bans SET nums = {1}, lastseen = {2} WHERE banvalue = {0} LIMIT 1", array($Ban["banvalue"], $Ban["nums"] + 1, $this->OSHeaders["OBJECT_KEY"]));
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private function ExistsInCache()
|
||
|
{
|
||
|
$InCache = $this->MySql->query("SELECT * FROM userdata WHERE id = {0} LIMIT 1", array($this->Uuid))->fetch();
|
||
|
return !empty($InCache["id"]);
|
||
|
}
|
||
|
|
||
|
private function GetFromCache()
|
||
|
{
|
||
|
$Cache = $this->MySql->query("SELECT * FROM userdata WHERE id = {0} LIMIT 1", array($this->Uuid))->fetch();
|
||
|
$this->FromJson($Cache["userdata"]);
|
||
|
$this->LastUpdate = $Cache["lastreq"];
|
||
|
if (file_exists($this->ImagesPath."/UserImage/".$this->Uuid.".jpg"))
|
||
|
{$this->ProfileImageBlob = file_get_contents($this->ImagesPath."/UserImage/".$this->Uuid.".jpg");}
|
||
|
}
|
||
|
|
||
|
//Magic function
|
||
|
private function GetFromInternet()
|
||
|
{
|
||
|
//First of all, we need to find out what uris the gridservices are having for this user (might be different for each user)
|
||
|
$this->ServiceUris = $this->RequestUserSeviceUris();
|
||
|
if ($this->ServiceUris !== false)
|
||
|
{
|
||
|
//IF this was successfull, we are requesting all required user info from the services
|
||
|
$UserInfo = $this->RequestUserInfo();
|
||
|
if ($UserInfo !== false)
|
||
|
{
|
||
|
$this->FirstName = $UserInfo["user_firstname"];
|
||
|
$this->LastName = $UserInfo["user_lastname"];
|
||
|
|
||
|
/* Ungewollte User in der Auflistung ausschließen */
|
||
|
if ($this->IsUnwanted(array($this->Uuid, $this->HomeUri, $this->FirstName." ".$this->LastName)))
|
||
|
{
|
||
|
$this->BirthUnix = 0;
|
||
|
$this->UserTitle = "Blacklisted";
|
||
|
$this->HomeGrid = "Somewhere";
|
||
|
$this->ProfileImageUuid = "00000000-0000-0000-0000-000000000001";
|
||
|
$this->ProfileAbout = "";
|
||
|
$this->HomeRegionUuid = "00000000-0000-0000-0000-000000000000";
|
||
|
$this->HomeRegionName = "";
|
||
|
$this->HomeRegionUri = "";
|
||
|
$this->HomeRegionPos = "";
|
||
|
$this->HomeRegionUuid = "00000000-0000-0000-0000-000000000000";
|
||
|
$this->HomeRegionName = "Unknown";
|
||
|
$this->HomeRegionUri = "";
|
||
|
$this->HomeRegionPos = "<0, 0, 0>";
|
||
|
$this->ProfileImageBlob = base64_decode($this->BlockedImage);
|
||
|
$this->AddToCache();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//We can do more magic: Request the entire user profile, its image and all other cool stuff
|
||
|
$ProfileData = $this->RequestUserProfile();
|
||
|
$GridInfo = $this->RequestHomeGrid();
|
||
|
$this->BirthUnix = $UserInfo["user_created"];
|
||
|
$this->UserTitle = $UserInfo["user_title"];
|
||
|
if (empty($this->UserTitle))
|
||
|
{$this->UserTitle = "Unknown";}
|
||
|
$this->HomeGrid = $GridInfo["gridname"];
|
||
|
$this->ProfileImageUuid = $ProfileData["result"]["ImageId"];
|
||
|
$this->ProfileAbout = $ProfileData["result"]["AboutText"];
|
||
|
$HomeRegion = $this->RequestHomeRegion();
|
||
|
$this->HomeRegionUuid = $HomeRegion["uuid"];
|
||
|
$this->HomeRegionName = $HomeRegion["region_name"];
|
||
|
$this->HomeRegionUri = $HomeRegion["server_uri"];
|
||
|
$this->HomeRegionPos = $HomeRegion["position"];
|
||
|
$this->ProfileImageBlob = $this->RequestUserImageBlob();
|
||
|
$this->AddToCache();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
$this->FirstName = "Unknown";
|
||
|
$this->LastName = "User";
|
||
|
$this->BirthUnix = 0;
|
||
|
$this->UserTitle = "Wrong configured grid";
|
||
|
$this->HomeGrid = "Unknown";
|
||
|
$this->ProfileImageUuid = "00000000-0000-0000-0000-000000000000";
|
||
|
$this->ProfileAbout = "";
|
||
|
$this->HomeRegionUuid = "00000000-0000-0000-0000-000000000000";
|
||
|
$this->HomeRegionName = "";
|
||
|
$this->HomeRegionUri = "";
|
||
|
$this->HomeRegionPos = "";
|
||
|
$this->HomeRegionUuid = "00000000-0000-0000-0000-000000000000";
|
||
|
$this->HomeRegionName = "Unknown";
|
||
|
$this->HomeRegionUri = "";
|
||
|
$this->HomeRegionPos = "<0, 0, 0>";
|
||
|
if (file_exists($this->ImagesPath."/UserImage/".$this->Uuid.".jpg"))
|
||
|
{$this->ProfileImageBlob = file_get_contents($this->ImagesPath."/UserImage/".$this->Uuid.".jpg");}
|
||
|
else
|
||
|
{$this->ProfileImageBlob = base64_decode($this->ErrorImage);}
|
||
|
}
|
||
|
|
||
|
private function RequestUserSeviceUris()
|
||
|
{
|
||
|
$Res = HttpRequest($this->HomeUri, "<?xml version=\"1.0\" encoding=\"utf-8\"?><methodCall><methodName>get_server_urls</methodName><params><param><value><struct><member><name>userID</name><value><string>".$this->Uuid."</string></value></member></struct></value></param></params></methodCall>", "", 3, "application/xml");
|
||
|
if (strlen($Res) < 200)
|
||
|
{return false;}
|
||
|
$ServiceURLs = ParseXml($Res);
|
||
|
$ServiceURLList = array();
|
||
|
for ($i = 0; $i < count($ServiceURLs["params"]["param"]["value"]["struct"]["member"]); ++$i)
|
||
|
{
|
||
|
$ServiceURL = $ServiceURLs["params"]["param"]["value"]["struct"]["member"][$i];
|
||
|
$ServiceURLList[$ServiceURL["name"]] = $ServiceURL["value"]["string"];
|
||
|
}
|
||
|
if (count($ServiceURLList) < 7)
|
||
|
{return false;}
|
||
|
return $ServiceURLList;
|
||
|
}
|
||
|
|
||
|
private function RequestUserProfile()
|
||
|
{return json_decode(HttpRequest($this->ServiceUris["SRV_ProfileServerURI"], "{\"jsonrpc\":\"2.0\",\"id\":\"00000000-0000-0000-0000-000000000000\",\"method\":\"avatar_properties_request\",\"params\":{\"UserId\":\"".$this->Uuid."\"}}", "", 3, "application/json-rpc"), true);}
|
||
|
|
||
|
private function RequestUserInfo()
|
||
|
{
|
||
|
$UserInfos = ParseXml(HttpRequest($this->HomeUri, "<?xml version=\"1.0\" encoding=\"utf-8\"?><methodCall><methodName>get_user_info</methodName><params><param><value><struct><member><name>userID</name><value><string>".$this->Uuid."</string></value></member></struct></value></param></params></methodCall>", "", 3, "application/xml"));
|
||
|
$UserInfosList = array();
|
||
|
for ($i = 0; $i < count($UserInfos["params"]["param"]["value"]["struct"]["member"]); ++$i)
|
||
|
{
|
||
|
$UserInfo = $UserInfos["params"]["param"]["value"]["struct"]["member"][$i];
|
||
|
$UserInfosList[$UserInfo["name"]] = $UserInfo["value"]["string"]?$UserInfo["value"]["string"]:$UserInfo["value"]["i4"];
|
||
|
}
|
||
|
if (count($UserInfosList) < 6)
|
||
|
{return false;}
|
||
|
return $UserInfosList;
|
||
|
}
|
||
|
|
||
|
private function RequestHomeGrid()
|
||
|
{return ParseXml(HttpRequest($this->HomeUri.((substr($this->HomeUri, -1, 1) == "/")?"":"/")."get_grid_info", "", "", 3), true);}
|
||
|
|
||
|
private function RequestHomeRegion()
|
||
|
{
|
||
|
$HomeInfos = ParseXml(HttpRequest($this->HomeUri, "<?xml version=\"1.0\" encoding=\"utf-8\"?><methodCall><methodName>get_home_region</methodName><params><param><value><struct><member><name>userID</name><value><string>".$this->Uuid."</string></value></member></struct></value></param></params></methodCall>", "", 3, "application/xml"));
|
||
|
$HomeInfosList = array();
|
||
|
for ($i = 0; $i < count($HomeInfos["params"]["param"]["value"]["struct"]["member"]); ++$i)
|
||
|
{
|
||
|
$HomeInfo = $HomeInfos["params"]["param"]["value"]["struct"]["member"][$i];
|
||
|
$HomeInfosList[$HomeInfo["name"]] = $HomeInfo["value"]["string"];
|
||
|
}
|
||
|
if (count($HomeInfosList) < 13)
|
||
|
{return false;}
|
||
|
return $HomeInfosList;
|
||
|
}
|
||
|
|
||
|
private function RequestUserImageBlob()
|
||
|
{
|
||
|
if (!empty($this->ProfileImageUuid) && $this->ProfileImageUuid != "00000000-0000-0000-0000-000000000000")
|
||
|
{
|
||
|
$AssetURI = $this->ServiceUris["SRV_AssetServerURI"].((substr($this->ServiceUris["SRV_AssetServerURI"], -1, 1) == "/")?"":"/")."assets/".$this->ProfileImageUuid."/data";
|
||
|
$AssetImageData = HttpRequest($AssetURI, "", "", 3);
|
||
|
$TempName = $this->MySql->id(8);
|
||
|
file_put_contents("binary_helper/".$TempName.".jp2", $AssetImageData);
|
||
|
//Should be the same for Windows and Unix... If not, only God can help you... or Google (which is the same)
|
||
|
shell_exec("binary_helper".DIRECTORY_SEPARATOR."magick convert binary_helper/".$TempName.".jp2 binary_helper/".$TempName.".jpg");
|
||
|
$AssetImageData = file_get_contents("binary_helper/".$TempName.".jpg");
|
||
|
@unlink("binary_helper/".$TempName.".jp2");
|
||
|
@unlink("binary_helper/".$TempName.".jpg");
|
||
|
if (strlen($AssetImageData) < 512)
|
||
|
{return base64_decode($this->ErrorImage);}
|
||
|
$SrcImg = imagecreatefromstring($AssetImageData);
|
||
|
$DstImg = ImageCreateTrueColor(200, 200);
|
||
|
imagecopyresampled($DstImg, $SrcImg, 0, 0, 0, 0, 200, 200, imageSX($SrcImg), imageSY($SrcImg));
|
||
|
ob_start();
|
||
|
imagejpeg($DstImg, null, 90);
|
||
|
$Res = ob_get_contents();
|
||
|
ob_end_clean();
|
||
|
}
|
||
|
else
|
||
|
{$Res = base64_decode($this->ErrorImage);}
|
||
|
return $Res;
|
||
|
}
|
||
|
|
||
|
private function AddToCache()
|
||
|
{
|
||
|
$this->MySql->query("REPLACE INTO userdata(id, userdata, lastreq)VALUES({0}, {1}, {2})", array($this->Uuid, $this->ToJson(), $this->LastRequest));
|
||
|
file_put_contents($this->ImagesPath."/UserImage/".$this->Uuid.".jpg", $this->ProfileImageBlob);
|
||
|
}
|
||
|
|
||
|
public function ToArray()
|
||
|
{
|
||
|
if (!empty($this->FirstName))
|
||
|
{
|
||
|
return array("uuid" => $this->Uuid,
|
||
|
"firstname" => $this->FirstName,
|
||
|
"lastname" => $this->LastName,
|
||
|
"homegrid" => $this->HomeGrid,
|
||
|
"birthunix" => $this->BirthUnix,
|
||
|
"profileimage" => $this->ProfileImageUuid,
|
||
|
"about" => $this->ProfileAbout,
|
||
|
"title" => $this->UserTitle,
|
||
|
"home" => $this->HomeRegionName,
|
||
|
"homelocation" => $this->HomeRegionPos,
|
||
|
"homeuri" => $this->HomeRegionUri);
|
||
|
}
|
||
|
else
|
||
|
{return false;}
|
||
|
}
|
||
|
|
||
|
public function ToJson()
|
||
|
{
|
||
|
if (!empty($this->FirstName))
|
||
|
{return json_encode($this->ToArray());}
|
||
|
else
|
||
|
{return false;}
|
||
|
}
|
||
|
|
||
|
public function FromJson($Json)
|
||
|
{
|
||
|
$Json = json_decode($Json, true);
|
||
|
$this->Uuid = $Json["uuid"];
|
||
|
$this->FirstName = $Json["firstname"];
|
||
|
$this->LastName = $Json["lastname"];
|
||
|
$this->HomeGrid = $Json["homegrid"];
|
||
|
$this->BirthUnix = $Json["birthunix"];
|
||
|
$this->ProfileImageUuid = $Json["profileimage"];
|
||
|
$this->ProfileAbout = $Json["about"];
|
||
|
$this->UserTitle = $Json["title"];
|
||
|
$this->HomeRegionName = $Json["home"];
|
||
|
$this->HomeRegionPos = $Json["homelocation"];
|
||
|
$this->HomeRegionUri = $Json["homeuri"];
|
||
|
}
|
||
|
|
||
|
public function ToLsl($Glue)
|
||
|
{
|
||
|
if (!empty($this->FirstName))
|
||
|
{
|
||
|
return implode($Glue, array($this->Uuid,
|
||
|
$this->FirstName,
|
||
|
$this->LastName,
|
||
|
($this->HomeGrid==null)?"Unknown":$this->HomeGrid,
|
||
|
($this->BirthUnix==null)?"0":$this->BirthUnix,
|
||
|
($this->ProfileImageUuid==null)?"00000000-0000-0000-0000-000000000000":$this->ProfileImageUuid,
|
||
|
base64_encode($this->ProfileAbout),
|
||
|
($this->UserTitle==null)?"":(is_array($this->UserTitle)?"":$this->UserTitle),
|
||
|
($this->HomeRegionName==null)?"":$this->HomeRegionName,
|
||
|
($this->HomeRegionPos==null)?"<0, 0, 0>":$this->HomeRegionPos,
|
||
|
($this->HomeRegionUri==null)?"":$this->HomeRegionUri));
|
||
|
}
|
||
|
else
|
||
|
{return false;}
|
||
|
}
|
||
|
|
||
|
private function HelpValue($Name, $Value = null)
|
||
|
{
|
||
|
if ($Value === null)
|
||
|
{
|
||
|
$Res = $this->MySql->query("SELECT * FROM helpvals WHERE name = {0} LIMIT 1", array($Name))->fetch();
|
||
|
return $Res["val"];
|
||
|
}
|
||
|
else
|
||
|
{$this->MySql->query("REPLACE INTO helpvals (name, val)VALUES({0}, {1})", array($Name, $Value));}
|
||
|
}
|
||
|
}
|
||
|
?>
|