Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Keyless Product Update Server

Dragon Keen
Registered User
Join date: 24 Apr 2006
Posts: 245
03-11-2007 12:00
Finally open-sourced. This product is an update server, but lets it be keyless, utilizing a mySQL backend system. System requirements to run are to be able to run PHP and have a mySQL database

I'll answer questions, but dont have the time for full support of this product.

DISCLAIMER - Dont sell this code. This is provided for free, not for use in a product you intend to sell. I will file DMCA complaints for any product I feel violates my source code. There are already products on the market for this (mine and hippotechs) if you wish to simply use the update server. This is provided free and open source so you can customize it for your own specific need, not for resale.


Server Object (In World)
CODE

/////////////////////////////////
//// UPDATE SERVER VARIABLES ///
/////////////////////////////////

string AVName = "Dragon Keen"; // Replace this with YOUR AVs name
string Product = "[-DK-] Update Server"; // Replace this with your products EXACT NAME (case counts)
string Pasword = "xxx"; // Replace this with your password on the update server
string Version = "2.1"; // Version Number
string updateData;
string ServerName = "[-DK-] Update Server 1"; // Your server name the product is in



///////////////////////////////////////
///// DO NOT EDIT BELOW THIS LINE ///
///////////////////////////////////////

// CONTANTS
string OBJKEY;
string OWNERKEY;
string OWNERNAME;
string SIM;
string XPOS;
string YPOS;
string SERVERNAME;
// STAGES
integer setup = FALSE;
integer created = FALSE;
integer update = FALSE;
integer active = FALSE;
integer display = TRUE;
integer upgrade = FALSE;
// VARIABLES
key requestid;
integer done;
integer line;
string notecard;
integer timecount = 0;
//string product_current;
//string product_update;
integer rand_chan;
list menu = ["Upgrade", "Display", "Set Online", "Memory", "Update", "Reset Stats"];
integer numProducts;
integer itemSent = 0;
integer reqTaken = 0;
integer invalid = 0;
string last = "n/a";
//FUNCTIONS
serverSetup()
{
OBJKEY = (string)llGetKey();
OWNERKEY = (string)llGetOwner();
OWNERNAME = llEscapeURL(llKey2Name(OWNERKEY));
SIM = llGetRegionName();
vector coord = llGetPos();
XPOS = (string)llRound( coord.x );
YPOS = (string)llRound( coord.y );
SERVERNAME = llGetObjectName();
setup = TRUE;
//notecard = "_server_config_";
//read_config();
updateData = (string)llGetOwner() + ";" + AVName + ";" + Product + ";" + Pasword + ";" + Version + ";" + ServerName;

requestid = llHTTPRequest("http:///parse.php?step=SETUP&objkey=" + OBJKEY + "&ownerkey=" + OWNERKEY + "&ownername=" + OWNERNAME + "&sim=" + llEscapeURL(SIM) + "&xpos=" + XPOS + "&ypos=" + YPOS + "&servername=" + llEscapeURL(SERVERNAME) + "&active=" + (string)active,[HTTP_METHOD,"GET"],"");


}

serverUpdate()
{
// update stuff
}

read_config() {
llOwnerSay("Reading configuration...");
done = FALSE;
line = 0;
llGetNotecardLine(notecard, line);
}

setDisplay()
{
vector color;
if (active) color = <0,1,0>;
else if (!active) color = <1,0,0>;

if (display)
{
if (active) llSetText("Server: ACTIVE\nProducts: " + (string)numProducts
+ "\nItems Sent: " + (string)itemSent
+ "\nRequests Taken: " + (string)reqTaken
+ "\nInvalid: " + (string)invalid
+ "\nLast: " + last, color, 1);
else if (!active) llSetText("Server: OFF", color, 1);
}
else if (!display)
llSetText("", color, 1);
}


default
{
on_rez(integer start_param)
{
llResetScript();
}

state_entry()
{
updateData = (string)llGetOwner() + ";" + AVName + ";" + Product + ";" + Pasword + ";" + Version + ";" + ServerName;
upgrade = TRUE;
requestid = llHTTPRequest("http:///parse.php?step=CHECKPRODUCT&data=" + llEscapeURL(updateData),[HTTP_METHOD,"GET"],"");
llSetText("Step 1: Rename the object to a unique name\nStep 2: Touch to register server", <1.0,0.0,0.0>, 1.0 );
}

timer()
{
timecount++;
if (timecount == 17280)
{
upgrade = TRUE;
timecount = 0;
//updateData = (string)llGetOwner() + ";" + updateData;
requestid = llHTTPRequest("http://parse.php?step=CHECKPRODUCT&data=" + llEscapeURL(updateData),[HTTP_METHOD,"GET"],"");
}
llGetNextEmail();
}

touch_start(integer total_number)
{
if (llDetectedKey(0) == llGetOwner())
{
if (llGetObjectName() != "[-DK-] Update Server v2.1")
{
if (!created) serverSetup();
else llDialog(llGetOwner(),"Please Choose:", menu,rand_chan);
} else llOwnerSay("Step 1 - Change the servers name");
}
}

http_response(key request_id, integer status, list metadata, string body)
{
if (request_id == requestid)
{
if (setup == TRUE)
{
llOwnerSay(body);
created = TRUE;
rand_chan = (integer)llFrand(10000000);
llListen(rand_chan,"",llGetOwner(),"");
setup = FALSE;
setDisplay();
}
else if (upgrade == TRUE)
{
llOwnerSay(body);
upgrade = FALSE;
}
}
} // end http_response

dataserver(key query, string data)
{
if (notecard == "_product_config_")
{
if (data == EOF)
{
if (done == FALSE)
{
llOwnerSay("Finished reading notecards... " + (string)line + " products added");
numProducts = line;
done = TRUE;
data = "";
setDisplay();
return;
}
}
else
{
list raw = llParseStringKeepNulls(data, [";"], []);
string productName = llList2String(raw,0);
string productObj = llList2String(raw,1);
string productNote = llList2String(raw,2);
string productVer = llList2String(raw,3);
string productPass = llList2String(raw,4);
requestid = llHTTPRequest("http:///parse.php?step=PRODUCT&objkey=" + OBJKEY + "&ownerkey=" + OWNERKEY + "&ownername=" + OWNERNAME + "&productname=" + llEscapeURL(productName) + "&productnote=" + llEscapeURL(productNote) + "&version=" + productVer + "&password=" + productPass + "&servername=" + llEscapeURL(llGetObjectName()) + "&productobj=" + llEscapeURL(productObj),[HTTP_METHOD,"GET"],"");
line = line + 1;
llGetNotecardLine(notecard, line);
}
}
} // end dataserver

listen(integer channel, string name, key id, string message)
{
if (message == "Memory") llOwnerSay("Free Memory: " + (string)llGetFreeMemory());
else if (message == "Set Online")
{
requestid = llHTTPRequest("http:///parse.php?step=ONLINE&objkey=" + OBJKEY,[HTTP_METHOD,"GET"],"");
llOwnerSay("Server set ONLINE");
menu = ["Upgrade", "Display", "Set Offline", "Memory", "Update", "Reset Stats"];
active = TRUE;
llSetTimerEvent(5);
setDisplay();
}
else if (message == "Reset Stats")
{
itemSent = 0;
reqTaken = 0;
invalid = 0;
last = "n/a";
llOwnerSay("Stats cleared");
setDisplay();
}
else if (message == "Set Offline")
{
requestid = llHTTPRequest("http:///parse.php?step=OFFLINE&objkey=" + OBJKEY,[HTTP_METHOD,"GET"],"");
llOwnerSay("Server set OFFLINE");
menu = ["Upgrade", "Display", "Set Online", "Memory", "Update", "Reset Stats"];
active = FALSE;
llSetTimerEvent(0);
setDisplay();
}
else if (message == "Update")
{
notecard = "_product_config_";
read_config();
}
else if (message == "Upgrade")
{
upgrade = TRUE;
//updateData = (string)llGetOwner() + ";" + updateData;
requestid = llHTTPRequest("http:///parse.php?step=CHECKPRODUCT&data=" + llEscapeURL(updateData),[HTTP_METHOD,"GET"],"");
}
else if (message == "Display")
{
if (display)
{
llOwnerSay("Turning display off");
display = FALSE;
setDisplay();
}
else if (!display)
{
llOwnerSay("Turning display on");
display = TRUE;
setDisplay();
}
}
}

email(string time, string address, string subject, string message, integer num_remaining)
{
list header = llCSV2List(message);
key av = llList2Key(header, 0);
string pName = llList2String(header, 1);
string pNote = llList2String(header, 2);

if (subject == "xxx")
{
llGiveInventory(av, pName);
if (pNote != "") llGiveInventory(av, pNote);
}
else if (subject == "SENT")
{
itemSent += 1;
last = message + "SL";
setDisplay();
}
else if (subject == "CURRENT")
{
reqTaken += 1;
last = message + "SL";
setDisplay();
}
else if (subject == "INVALID")
{
invalid += 1;
last = message + "SL";
setDisplay();
}



if (num_remaining) llGetNextEmail();
}
}


Update Script (goes in each object to check for updates)
CODE

/////////////////////////////////
//// UPDATE SERVER VARIABLES ///
/////////////////////////////////

string AVName = ""; // Replace this with YOUR AVs name
string Product = ""; // Replace this with your products EXACT NAME (case counts)
string Pasword = ""; // Replace this with your password on the update server
string Version = ""; // Version Number
string ServerName = ""; // Your server name the product is in

///////////////////////////////////////
///// DO NOT EDIT BELOW THIS LINE ///
///////////////////////////////////////

key requestid;

default
{
on_rez(integer num)
{
llOwnerSay("Checking for new version... Please Wait");
string data = AVName + ";" + Product + ";" + Pasword + ";" + Version + ";" + ServerName;
data = (string)llGetOwner() + ";" + data;
requestid = llHTTPRequest("http://ckprod.php?data=" + llEscapeURL(data),[HTTP_METHOD,"GET"],"");
}

touch_start(integer total_number)
{
//llOwnerSay("Checking for new version... Please Wait");
//string data = AVName + ";" + Product + ";" + Pasword + ";" + Version + ";" + ServerName;
//llMessageLinked(LINK_SET, 0, data, "");
}

http_response(key request_id, integer status, list metadata, string body)
{
if (request_id == requestid)
{
llOwnerSay(body);
}
} // end http_response
}


Check Product PHP Code (ckprod.php)
CODE

<?

include("config.php");
putenv("TZ=America/Los_Angeles");
$connection = mysql_connect($hostname, $user, $pass) or die ("Unable to connect!");


$objkey = $_GET['objkey'];
$ownerkey = $_GET['ownerkey'];
$ownername = $_GET['ownername'];
$sim = $_GET['sim'];
$xpos = $_GET['xpos'];
$ypos = $_GET['ypos'];
$servername = $_GET['servername'];
$step = $_GET['step'];
$pcurrent = $_GET['pcurrent'];
$pupdate = $_GET['pupdate'];
$active = $_GET['active'];




$rawdata = $_GET['data'];
$data = explode(';', $rawdata); // 0=name 1=product 2=password 3=version
$ckav = $data[0];
$ckname = $data[1];
$ckprod = $data[2];
$ckpass = $data[3];
$ckver = $data[4];
$srvnm = $data[5];

$query = "SELECT * FROM products WHERE pname = '$ckprod' AND powner = '$ckname' AND servername = '$srvnm'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
if (mysql_num_rows($result) == 1)
{
$stamp = date("Y-m-d G:i:s");
$row = mysql_fetch_array($result);
$sc = explode('.', $row['version']); // in database version
$sr = explode('.', $ckver); // rezzed version
$serverkey = $row['skey'];

if (($ckpass == $row['ppass']) || ($row['ppass'] == " "))
{
if ($sr[0] < $sc[0]) $current = FALSE; // rezzed version number lower, update available and stop checking
else if (($sr[1] < $sc[1]) && ($sr[0] <= $sc[0])) $current = FALSE; // rezzed subversion different, update available
else $current = TRUE;
if ($current)
{
echo "Your product \"" . $ckprod . " v" . $ckver . "\" is current.";
mail($row['skey'] . "@lsl.secondlife.com", "CURRENT", $stamp);
}
else if (!$current)
{
echo "Your product \"" . $ckprod . " v" . $ckver . "\" is out of date. An updated \"" . $ckprod . " v" . $row['version'] . "\" is being sent";

// check if productObj is set
if ($row['pobject'] == "") $sendobject = $ckprod;
else $sendobject = $row['pobject'];
mail($row['skey'] . "@lsl.secondlife.com", "", $ckav . ", " . $sendobject . ", " . $row['notecard'] . ",");

mail($row['skey'] . "@lsl.secondlife.com", "SENT", $stamp);
}
} else mail($row['skey'] . "@lsl.secondlife.com", "INVALID", $stamp);
}



?>


PHP code (parse.php)
CODE

<?

include("config.php");
putenv("TZ=America/Los_Angeles");
$connection = mysql_connect($hostname, $user, $pass) or die ("Unable to connect!");


$objkey = $_GET['objkey'];
$ownerkey = $_GET['ownerkey'];
$ownername = $_GET['ownername'];
$sim = $_GET['sim'];
$xpos = $_GET['xpos'];
$ypos = $_GET['ypos'];
$servername = $_GET['servername'];
$step = $_GET['step'];
$pcurrent = $_GET['pcurrent'];
$pupdate = $_GET['pupdate'];
$active = $_GET['active'];



if ($step == "SETUP")
{
$query = "SELECT * from servers WHERE skey = '$objkey'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
if (mysql_num_rows($result) == 0)
{
$query = "SELECT skey FROM servers WHERE ownerkey = '$ownerkey' AND sname = '$servername'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
if (mysql_num_rows($result) == 0)
{
$query = "INSERT into servers (skey, sname, ownerkey, ownername, sim, xpos, ypos, current, pupdate, active) VALUES ('$objkey', '$servername', '$ownerkey', '$ownername', '$sim', '$xpos', '$ypos', '$pcurrent', '$pupdate', '$active')";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
if ($active == 0) echo "Server name \"$servername\" has been set up, and is currently NOT active";
else if ($active == 1) echo "Server name \"$servername\" has been set up, and is currently ACTIVE";
}
else
{
// delete old entry, replace with new
$row = mysql_fetch_array($result);
$query = "DELETE FROM servers WHERE skey = '$row[0]'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
$query = "INSERT into servers (skey, sname, ownerkey, ownername, sim, xpos, ypos, current, pupdate, active) VALUES ('$objkey', '$servername', '$ownerkey', '$ownername', '$sim', '$xpos', '$ypos', '$pcurrent', '$pupdate', '$active')";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
echo "Old server removed, new one replaced. Products will check this new server for updates";
}

}
else echo "This server's key is already setup in the system, please use the update button instead";
}
else if ($step == "ONLINE")
{
$query = "UPDATE servers SET active = '1' WHERE skey = '$objkey'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
}
else if ($step == "OFFLINE")
{
$query = "UPDATE servers SET active = '0' WHERE skey = '$objkey'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
}
else if ($step == "PRODUCT")
{
$pname = $_GET['productname'];
$pobj = $_GET['productobj'];
$pnote = $_GET['productnote'];
$pver = $_GET['version'];
$ppass = $_GET['password'];
$srvname = $_GET['servername'];

$query = "SELECT * FROM products WHERE pownerkey = '$ownerkey' AND pname = '$pname'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
if (mysql_num_rows($result) == 0)
{
$query = "INSERT INTO products (skey, pname, pobject, ppass, version, notecard, pownerkey, powner, servername) VALUES ('$objkey', '$pname', '$pobj', '$ppass', '$pver', '$pnote', '$ownerkey', '$ownername', '$srvname')";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
echo "Product Added";
}
else
{
// delete old and replace with new
$query = "DELETE FROM products WHERE pownerkey = '$ownerkey' AND pname = '$pname'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
$query = "INSERT INTO products (skey, pname, pobject, ppass, version, notecard, pownerkey, powner, servername) VALUES ('$objkey', '$pname', '$pobj', '$ppass', '$pver', '$pnote', '$ownerkey', '$ownername', '$srvname')";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
}


}
else if ($step == "CHECKPRODUCT")
{
$rawdata = $_GET['data'];
$data = explode(';', $rawdata); // 0=name 1=product 2=password 3=version
$ckav = $data[0];
$ckname = $data[1];
$ckprod = $data[2];
$ckpass = $data[3];
$ckver = $data[4];
$srvnm = $data[5];

$query = "SELECT * FROM products WHERE pname = '$ckprod' AND powner = '$ckname' AND servername = '$srvnm'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in query: $query. " . mysql_error());
if (mysql_num_rows($result) == 1)
{
$stamp = date("Y-m-d G:i:s");
$row = mysql_fetch_array($result);
$sc = explode('.', $row['version']); // in database version
$sr = explode('.', $ckver); // rezzed version
$serverkey = $row['skey'];

if (($ckpass == $row['ppass']) || ($row['ppass'] = " "))
{
if ($sr[0] < $sc[0]) $current = FALSE; // rezzed version number lower, update available and stop checking
else if (($sr[1] < $sc[1]) && ($sr[0] <= $sc[0])) $current = FALSE; // rezzed subversion different, update available
else $current = TRUE;
if ($current)
{
echo "Your product \"" . $ckprod . " v" . $ckver . "\" is current.";
mail($row['skey'] . "@lsl.secondlife.com", "CURRENT", $stamp);
}
else if (!$current)
{
echo "Your product \"" . $ckprod . " v" . $ckver . "\" is out of date. An updated \"" . $ckprod . " v" . $row['version'] . "\" is being sent";

// check if productObj is set
if ($row['pobject'] == "") $sendobject = $ckprod;
else $sendobject = $row['pobject'];
echo $sendobject;
mail($row['skey'] . "@lsl.secondlife.com", "", $ckav . ", " . $sendobject . ", " . $row['notecard'] . ",");

mail($row['skey'] . "@lsl.secondlife.com", "SENT", $stamp);
}
} else mail($row['skey'] . "@lsl.secondlife.com", "INVALID", $stamp);

}




}



?>


mySQL Database Info
CODE

CREATE TABLE `products` (
`pid` int(11) NOT NULL auto_increment,
`skey` varchar(64) NOT NULL default '',
`pname` varchar(64) NOT NULL default '',
`pobject` varchar(64) character set utf8 collate utf8_bin NOT NULL default '',
`ppass` varchar(64) NOT NULL default '',
`version` varchar(64) NOT NULL default '',
`notecard` varchar(64) NOT NULL default '',
`pownerkey` varchar(64) NOT NULL default '',
`powner` varchar(64) NOT NULL default '',
`servername` varchar(64) NOT NULL default '',
PRIMARY KEY (`pid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1664 ;

-- --------------------------------------------------------

--
-- Table structure for table `servers`
--

CREATE TABLE `servers` (
`skey` varchar(64) NOT NULL default '',
`sname` varchar(64) NOT NULL default '',
`ownerkey` varchar(64) NOT NULL default '',
`ownername` varchar(128) NOT NULL default '',
`sim` varchar(64) NOT NULL default '',
`xpos` int(11) NOT NULL default '0',
`ypos` int(11) NOT NULL default '0',
`current` varchar(128) NOT NULL default 'Your product is up to date. Thank you.',
`pupdate` varchar(128) NOT NULL default '',
`sent` int(11) NOT NULL default '0',
`taken` int(11) NOT NULL default '0',
`invalid` int(11) NOT NULL default '0',
`active` tinyint(4) NOT NULL default '0',
PRIMARY KEY (`skey`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Discussion Thread
03-16-2007 04:50
/54/02/171733/1.html
_____________________
i've got nothing. ;)