Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discussion: 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
Original Thread
03-16-2007 04:50
/15/10/170888/1.html
_____________________
i've got nothing. ;)
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
03-16-2007 12:01
not that I have any plans to.. mind you...

But can people sell modded versions of this script? or include it in "packages"? If someone were to, let's say.. modify this into a notecard giver that would give a notice to all users of the product... or if someone were to mod this into "something wholly different"....

I'm just concerned.. because you've posted open code.. that is essentially just an assembly of pre-existing code pieces. While you're of course entitled to do so in this manner.. I have real concerns with anyone who STARTS by threatening everyone with DMCA actions.

Frankly, I wish youhadn't posted this code. Because now, anyone who develops an update server.. even if they do so without looking at your code.. needs to fear that you'll sue them.. over code *YOU* chose to release into the Public Domain.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
03-16-2007 12:31
I don't seriously think you can DCMA something you put into the public domain. If it was released under GPL maybe, but I don't see a GPL license anywhere. This kind of thing always bothers me. If you want to give something away, do so. If you don't want to give it way, then don't. Its like giving a friend a set of dishes, but then telling them they can only serve foods that begin with the letter A on the dishes. And if they don't do that, you'll take the dishe s back.
Woopsy Dazy
Registered User
Join date: 12 Nov 2006
Posts: 173
03-16-2007 12:36
So what if I write this code from scratch and it works the same way. Did I copy it? Agree with previous posters. Why share it if you don't wanna share it?
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
03-16-2007 13:06
Darien, if he wrote it, he has a copyright, implicitly. He has not put it into the public domain, he's released it with conditions. If you violate those conditions, you're liable.

However, if he has no right to make claims about code he didn't write. If you're using precursor versions of the same code already released by others, you aren't violating his copyright. (Furthermore, there are complications involving a derivitive work -- assuming the post above is a derivitive work.)

Woopsy, if you write it and it works the same way, it's not a copyright violation. It's only a violation if you copy his code (even if you do it by looking at it and typing it in). It's a violation even if you make little changes as you go.
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
03-16-2007 13:14
Well, I'm not too concerned, my update code I wrote myself, and it doesn't need MySQL or an external website to work, it's totally different. And while he may be within his 'legal' right to put such restrictions, i find it morally distasteful. Don't give stuff away if you aren't really giving it away. If anyone else sells a similar product, he can claim they are using this code and DCMA them, effectively shutting out any competition. I'm not going to get pulled into another discussion about how Copyright laws have deteriorated over the years to be slanted heavily in favor of the copyright holder, and are way to broad and open to interpretation about what can and can't be copyrighted. But I think it's pretty well recognized that putting something into the public domain means you give up all rights to it. Posting something on a forum that millions read is giving it up. As a copyright holder you have the responsibility to protect your copyright. No judge will side with you if you give something to millions of people but claim it's a private work.

I had intended to sell my system at some point, but now I think i'll post it here, free to be used, sold, twisted, and mangled by anyone, once it's cleaned up, so people dont' have to bother with this legal nightmare.
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
03-16-2007 13:25
Am I the only one that read the OP as "Here you go, feel free to use it, just dont sell it commercially AS-IS and pretend it is entirely your original work"?
_____________________
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
03-16-2007 13:27
i don't see the words AS-IS anywhere in the post. in fact 'not for use in a product you intend to sell' means you couldn't even use it to update any item you sell. You could only use it to update freebies...
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
03-16-2007 13:33
From: Darien Caldwell
i don't see the words AS-IS anywhere in the post. in fact 'not for use in a product you intend to sell' means you couldn't even use it to update any item you sell. You could only use it to update freebies...


It could also mean that you dont use it as the basis for an update server that you sell as an update server product... Anyone who has written software for RL companies for any significant length of time has seen that open source code repackaged as a commercial product is far more common than it ought to be, so I guess that is where my interpretation of the post came from.

Just sayin' there is some ambiguity and a lot of people seem to really read it in the most negative light. Personally, I couldnt care less one way or another in this particular instance. At BEST I would draw inspiration from this code, but I already have a keyless product server that I wrote for my products so it is kind of a moot point.
_____________________
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
03-16-2007 13:35
From: Darien Caldwell
i don't see the words AS-IS anywhere in the post. in fact 'not for use in a product you intend to sell' means you couldn't even use it to update any item you sell. You could only use it to update freebies...


Oh.. hehe. I see that you are calling attention to the fact that I bolded the phrase "as-is"... That is not because I said he used those words, it is because I wanted to emphasize my interpretation and for no other reason.
_____________________
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
03-16-2007 13:37
Darien, I interpret it the same way you do. I completely disagree with your all-or-nothing sense of taste. Folks can learn from his post. Folks can use the ideas in his post. Folks can use the code literally, in freebie products. (If he meant we can use it to update our products, by clarifying his wording, then so much the better.)

What he's doing is perfectly normal and legit. Not unlike posting a picture on the web -- it's there for us to admire, learn from, and even use under certain circumstances. If you don't like it, don't read the code after hearing his conditions, and you're not harmed in any way.

I find your post of your distaste somewhat distasteful. Ah well, it's a free world and we're entitled to our opinions.
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
03-16-2007 13:43
yes, well, c'est la vie. :P I think the root of the problem I have with things like this is the gist of what is being said: "I'm giving you some knowledge, however, you aren't allowed to use this knowledge except how I say." It's a bit like mind control, and a limit on one's personal freedom. And I'm a big believer in personal freedom. You can, as you say, just not read it, but really that doesn't protect you. Because he HE PERCIEVES that you have infringed, you are DMCAed. Guilty until proven innocent. This goes against the very freedoms that a democracy is supposed to support. Do I blame him, no, I blame the system. Any system that makes it fine and legal for a company to make a business out of suing other businesses over patents that hey hold, but don't use, its corrupt and unfair. Any yes, I'm getting way off topic so i"ll quit now. (you can tell this touches a nerve? :D )
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
03-16-2007 13:55
Robby, your "as-is" interpretation is incorrect. Ask a lawyer, if you don't believe me.
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
03-16-2007 13:59
Darien, we're allowed to use the concepts in his post. A copyright does not cover concepts; that's what a patent is for.

All open-source code is published this way. If you don't like open source, well, that's your perogative. However, reams of software has been developed using open source tools, and the SL browser is now an open source program. With restrictions. It's a common model in the industry. Too bad you find it distasteful.
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
03-16-2007 14:11
From: Learjeff Innis
Robby, your "as-is" interpretation is incorrect. Ask a lawyer, if you don't believe me.


hehe. I dont think that will be necessary :) I don't intend to use the code in any fashion anyways, and I enjoy reading all the posts by armchair attorneys in the forums :)

If, however, I did intend to use the code, I probably would do exactly that. Always pays to consult a qualified professional when you need an informed opinion rather than taking any chances, I think.
_____________________
Dragon Keen
Registered User
Join date: 24 Apr 2006
Posts: 245
03-16-2007 14:19
From: RobbyRacoon Olmstead
Am I the only one that read the OP as "Here you go, feel free to use it, just dont sell it commercially AS-IS and pretend it is entirely your original work"?


this was the intended application of what was stated. if its mis-interpreted, oh well. The point is to not sell it as-is and claim its your own as many do with scripts found here.

The point is... don't put the code together, and sell it. Me releasing the code is intended for users to potentially customize for their specific need. Nothing about what was stated means I can go after similar products, since there already are.

Again, simply, don't compile, package, and sell... I will DMCA that, since its not the intended purpose to release source code. However if you create a package or system based on the source, it'd be nice to send me a copy, give credit as "built from" or something to that effect. Isn't the entire point of open source to get the "framework" and customize from there?

Jesus, had no idea basically saying "dont copy and redistribute as your own" would cause such a stir.
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
03-16-2007 14:31
From: Dragon Keen
Jesus, had no idea basically saying "dont copy and redistribute as your own" would cause such a stir.


I appreciate the clarification of your intent in saying what you did. However, your summary there does not reflect what you ACTUALLY said.. and the meanings it can have.

The reason I raised issue (and I suspect why others did as well) is because of this statement from the OP.

From: someone
I will file DMCA complaints for any product I feel violates my source code.


I will file DMCA complaints for any product I feel violates my source code.

Unfortunately, in this litigious era we live in, what you have done in the above statement, is state unequivocably that you *WILL* seek to damage, destroy or ruin anyone who creates a product that you decide has "violated" your "source code".. at your sole discretion.

Also, in your eagerness to say the above, your basically allowed us almost no development rights whatsoever.. by stating words to the effect of "personal use only, not for resale". At that point, we can't derive products from expanding on, or taking away from.. your script. And that REALLY bugs the hell out of me. Because in essence you're saying that you own anything I make, having read your code.. and you won't allow me to sell something I made.. if it used anything from your code.

Now.. you've clarified your position to a level that I think everyone can understand.. but we're at 2 pages of discourse here.. that wouldn't have existed, had you been either less preemptively letigious, or more complete in your explanation of our rights from the beginning.

Sadly.. the words we use.. matter.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
Dragon Keen
Registered User
Join date: 24 Apr 2006
Posts: 245
03-16-2007 14:37
From: Winter Ventura
I appreciate the clarification of your intent in saying what you did. However, your summary there does not reflect what you ACTUALLY said.. and the meanings it can have.

The reason I raised issue (and I suspect why others did as well) is because of this statement from the OP.



I will file DMCA complaints for any product I feel violates my source code.

Unfortunately, in this litigious era we live in, what you have done in the above statement, is state unequivocably that you *WILL* seek to damage, destroy or ruin anyone who creates a product that you decide has "violated" your "source code".. at your sole discretion.

Also, in your eagerness to say the above, your basically allowed us no rights whatsoever.. by stating "personal use only". At that point, we can't derive products from expanding on, or taking away from.. your script. And that REALLY bugs the hell out of me. Because in essence you're saying that you own anything I make, having read your code.. and you won't allow me to sell something I made.. if it used anything from your code.

Now.. you've clarified your position to a level that I think everyone can understand.. but we're at 2 pages of discourse here.. that wouldn't have existed, had you been either less preemptively letigious, or more complete in your explanation of our rights from the beginning.

Sadly.. the words we use.. matter.


OK let me clarify that. If I *FEEL* that someone just took the code, compiled, and sold, then yes... I'm well within my right to do that, legally and morally.

That does NOT mean that if someone takes the code, adds a feature, and sells it that I would *feel* that I was violated. Since there is added functionality, someone took my code (perhaps) and modified it. That would be fine, I have no issues with that, and thats partly why I released the code.

It was late when I made that post... was tired and only half thinking...
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
03-16-2007 14:38
From: Learjeff Innis
Darien, we're allowed to use the concepts in his post. A copyright does not cover concepts; that's what a patent is for.

All open-source code is published this way. If you don't like open source, well, that's your perogative. However, reams of software has been developed using open source tools, and the SL browser is now an open source program. With restrictions. It's a common model in the industry. Too bad you find it distasteful.


I don't see most Open Source projects threatening to DMCA you if you use their code. Huge difference. I can make my own version of the SL client, and could even sell it, much the way Red Hat sells Linux. You can't compare that to this post. (and yes I know technically Red Hat sells support and printed manuals, but still...)
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
03-16-2007 14:42
From: Dragon Keen
OK let me clarify that. If I *FEEL* that someone just took the code, compiled, and sold, then yes... I'm well within my right to do that, legally and morally.

That does NOT mean that if someone takes the code, adds a feature, and sells it that I would *feel* that I was violated. Since there is added functionality, someone took my code (perhaps) and modified it. That would be fine, I have no issues with that, and thats partly why I released the code.

It was late when I made that post... was tired and only half thinking...


Dragon, I appreciate your clarification. Indeed it is sad that we even have to talk legal stuff in what's supposed to be a fun, relaxing, creative, enjoyable place like SL. But DMCA is a very dirty word to a lot of people, and should be used carefully.
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
03-16-2007 14:44
From: Dragon Keen
It was late when I made that post... was tired and only half thinking...


From: Darien Caldwell
I don't see most Open Source projects threatening to DMCA you if you use their code.


I'm willing to chalk that up to "I was tired"... I know I *AM* tired.. Dragon has now made it much clearer that we are quite entitled, and encouraged to use this code to base "new and improved" products upon. Both personal and commercial. Given the much clearer understanding of what Dragon *INTENDED* to communicate, I'd like to retract my first post.. and THANK him for posting this code. I can totally understand his "don't copy and paste this code, and try and under-price me with my own product" argument... that's not only fair.. but generous of him to take that risk with this code.. knowing the unscrupulous characters out there.

I myself have wondered how my update server works (hippotech) because it seems so smooth. So.. seeing the code available here for a similar product.. means I can perhaps hammer together the features I've felt were lacking in my purchased update server. And possibly remarket (or publish .. at my discretion) any major works accomplished.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
03-16-2007 14:47
From: Darien Caldwell
I don't see most Open Source projects threatening to DMCA you if you use their code. Huge difference. I can make my own version of the SL client, and could even sell it, much the way Red Hat sells Linux. You can't compare that to this post. (and yes I know technically Red Hat sells support and printed manuals, but still...)


The DCMA threat is implicit in the licensing agreements for open source licensed code. There are a number of organizations such as FSF and GNU and each has different restrictions. With FSF, you cannot use their source in a product you sell. GNU is not as restrictive, IIRC.

I don't know which particular license LSL client uses. If it uses one like FSF, then you cannot use the source code in a commercial product.

The OP is merely stating his legal rights. Perhaps it sounds unfriendly.
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
03-16-2007 14:49
Yes, thanks for posting your code. I'll still post mine later as an alternative for people who can't or dont have access to a web server.
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
03-16-2007 14:51
Darien.. that would be awesome if you would. I am sure it would be really educational to compare and contrast the two systems.. and look at their weaknesses and strengths.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
1 2 3