// RICP : Robot Information/Control Protocol
//
// Vendor Sample for a no-config vendor object
//
// This kind of vendor puts prices into the object names,
// and associates images with products by some prefix/suffix.
//
// You can configure or modify the script to work with your
// vendors. This particular version works with nXC EzVendor V0.1
//
// Created: 2007-08-18
// Authors: Diva Canto and Felix Wakmann
//
// Copyright (c) 2007 by The Regents of the University of California.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
string gConfigFormatFile = "SLRCP config";
// the offset is used to pick a point in *front* of the vendor
vector gOffset = <0, -2, 0>;
// the prefix and suffix specify how an image name differs from the object name
string gPrefix = "pic_";
string gSuffix = "";
// number of digits of price on the end of the object (and image)
integer gPriceLen = 5;
// prints out location
integer gDebug = FALSE;
// ******** Internal Variables ********
// convert a floating point to an integer
string ftos(float n)
{
return (string)((integer) (n + 0.5));
}
integer SLRCP_channel = 1020304;
// scan throught the objects and send them to the robot
startUpload(key target)
{
string secret = (string)llFrand(1000000);
list detailParts = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_OWNER]);
string owner = llList2String(detailParts, 0);
string msg = "verify?tag=" + secret + "&owner=" + owner;
// THis command sets the media URL *only* for the robot!
// It does not affect other users
llParcelMediaCommandList( [
PARCEL_MEDIA_COMMAND_AGENT, (key)target,
PARCEL_MEDIA_COMMAND_URL, msg
]);
integer prefixLen = llStringLength(gPrefix);
integer suffixLen = llStringLength(gSuffix);
vector pos = llGetPos() + gOffset * llGetRot();
string location = llGetRegionName() + "/" + ftos(pos.x) + "/" + ftos(pos.y) + "/" + ftos(pos.z);
if (gDebug)
llOwnerSay("secondlife://" + location);
integer num = llGetInventoryNumber(INVENTORY_TEXTURE);
while (num-- > 0)
{
string name = llGetInventoryName(INVENTORY_TEXTURE, num);
if (startsWith(name, gPrefix) || endsWith(name, gSuffix))
{
string image = llGetInventoryKey(name);
name = llGetSubString(name, prefixLen, -(suffixLen + 1));
string id = llGetInventoryKey(name);
string title = llGetSubString(name, 0, -(gPriceLen + 1));
string price = llGetSubString(name, -gPriceLen, -1);
integer i = 0;
for (i = 0; llGetSubString(price, i, i) == "0"; i++)
;
price = llGetSubString(price, i, 100);
if (price == "")
price = "0";
publish(secret, target, id, title, "", image, location, price);
}
}
}
integer startsWith(string str, string prefix)
{
integer len = llStringLength(prefix);
if (len == 0)
return TRUE;
return llGetSubString(str, 0, len) == prefix;
}
integer endsWith(string str, string prefix)
{
integer len = llStringLength(prefix);
if (len == 0)
return TRUE;
return llGetSubString(str, -len, 500) == prefix;
}
// publish info to the robot
publish(string tag, key target, string id, string title, string description, string image, string location, string price)
{
string info =
"product?tag=" + tag +
"&title=" + llEscapeURL(title) +
"&id=" + id +
"&description=" + llEscapeURL(description) +
"&image=" + image +
"&location=" + llEscapeURL(location) +
"&price=" + llEscapeURL(price);
llInstantMessage(target, info);
}
default
{
// set up the listener
state_entry()
{
llListen(SLRCP_channel, "", "", "");
}
// listen for a robot
listen(integer chan, string name, key id, string msg)
{
// The incoming message msg looks like this:
// robot|
list parts = llParseStringKeepNulls(msg, ["|"], []);
if (llList2String(parts, 0) == "robot")
{
string bot = llList2String(parts, 1);
if (bot == "")
bot = id;
startUpload(bot);
}
}
}