I've started working on creating my networked vending machine. The code below is demo code that I used to confirm what people said above about being able to sell things across sims. I'll summarize my progress here. There is more information if your interested on my blog
www.secondlifehowto.com.
What I’ve created and described below is a demo of a vending machine where the purchase is made at one vending machine and the item is delivered to the purchaser from a different central vending machine server. All the remote server has is a notecard which describes the item in the central server.
There are two scripts used in this demo: RemoteVendor.lsl and VendorServer.lsl. I’ll describe each of them here.
RemoteVendor.lsl
This script does the following:
1. Starts up and reads the notecard SaleItem1. I’ve hard coded this demo for one sales item for simplicity. A real version would obviously have multiple items.
2. Based on the data in the SaleItem1 notecard it puts a short description of the item for sale above the vending machine in red hover text and puts the price just below it. It also sets the pay price for the item.
3. When a purchaser pays the vending machine an email is sent to the central server. The email contains the key of the person who paid and the name of the purchased item.
VendorServer.lsl
This script does the following:
1. Starts up and says the key of the vendor server object. (This is required so that you can fill out the notecard for the item you want to sell with the original vendor of the item for sale.)
2. Starts up a timer that regularly checks email.
3. Up receipt of an email, it parses the email, determines who bought what and gives it to them.
Remote Vendor Code:
// Detailed explination of this script can be found at www.secondlifehowto.com
// This is a simplified demo of a remote vendor that sells an item located at a central
// vendor. This example is hard coded to sell one item that is described in a notecard
// that is hand placed in this vendor object.
list gCurrentItemBeingDisplayed=[];
integer ITEM_DISPLAYED_SHORT_DESCRIPTION_INDEX = 0;
integer ITEM_DISPLAYED_PRICE_INDEX = 1;
integer ITEM_DISPLAYED_ORIGINAL_VENDOR_KEY_INDEX = 2;
integer ITEM_DISPLAYED_ITEM_NAME_INDEX = 3;
string gCurrentItemNoteCardName = "SaleItem1";
key gIdCurrentNoteCardQuery;
integer gLineCurrentNoteCardQuery=0;
default
{
//--------------------------------------------------------------
// On startup, a request is made to read the first line of a notecard. This eventually causes
// a call to be made to dataserver with the resulting line. From there dataserver will read the
// rest of the items
//--------------------------------------------------------------
state_entry()
{
// Start read of notecard
gIdCurrentNoteCardQuery = llGetNotecardLine(gCurrentItemNoteCardName, gLineCurrentNoteCardQuery);
}
//--------------------------------------------------------------
// dataserver is called whenever a line is read out from a notecard. The call within this
// event to llGetNotecardLine continues the read of the notecard in a loop until End Of File
// is reached
//--------------------------------------------------------------
dataserver(key query_id, string data)
{
if (query_id == gIdCurrentNoteCardQuery)
{
if (data != EOF)
{
// Notecard is structured line by line to correspond with the items to go in the
// gCurrentItemBeingDisplayed list, so add it to the list line by line
gCurrentItemBeingDisplayed += data;
gLineCurrentNoteCardQuery++; // increase line count
gIdCurrentNoteCardQuery = llGetNotecardLine(gCurrentItemNoteCardName, gLineCurrentNoteCardQuery); // request next line
}
else
{
// We've reached the end of the notecard and should have copied everything into our list
// Now update the display
string description = llList2String(gCurrentItemBeingDisplayed, ITEM_DISPLAYED_SHORT_DESCRIPTION_INDEX);
string price = llList2String(gCurrentItemBeingDisplayed, ITEM_DISPLAYED_PRICE_INDEX);
llSetText(description + "\nL$"+price, <1,0,0>, 1.0);
// Now set the pay price
llSetPayPrice(PAY_HIDE, [(integer)price, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
}
}
}
//--------------------------------------------------------------
// This function is activated when someone pays the points dispenser
// it only takes the givers money if they have a HUD active
//--------------------------------------------------------------
money(key giver, integer amount)
{
string price_string = llList2String(gCurrentItemBeingDisplayed, ITEM_DISPLAYED_PRICE_INDEX);
if (amount >= (integer) price_string)
{
string item_name = llList2String(gCurrentItemBeingDisplayed, ITEM_DISPLAYED_ITEM_NAME_INDEX);
string original_vendor = llList2String(gCurrentItemBeingDisplayed, ITEM_DISPLAYED_ORIGINAL_VENDOR_KEY_INDEX);
llEmail(original_vendor + "@lsl.secondlife.com", "Purchase", item_name + "," + (string)giver);
}
}
}
Vendor Server Code:
// Detailed explination of this script can be found at www.secondlifehowto.com
// This is a simplified demo of a remote vendor that sells an item located at a central
// server. This server has no security. It just hands out the object to anyone that
// emails it the name of an item it has and the key of who it should go to
default
{
//------------------------------------------------------------------------------------
//On startup the server states it's key. This key is required for making sale item
//notecards
//------------------------------------------------------------------------------------
state_entry()
{
llWhisper(0, "VendorServer Key is " + (string)llGetKey());
llSetTimerEvent(2.5); // Poll for emails.
}
//------------------------------------------------------------------------------------
//Every time the timer expires, check for emails
//------------------------------------------------------------------------------------
timer()
{
llGetNextEmail("", "Purchase"); // Check for email with any sender address and subject.
}
//------------------------------------------------------------------------------------
//If we get an email, hand out the specified item
//------------------------------------------------------------------------------------
email(string time, string address, string subj, string message, integer num_left)
{
// Remove the header
message = llDeleteSubString(message, 0, llSubStringIndex(message, "\n\n") + 1);
// Break of the message
list purchase_request = llParseString2List(message,[","],[" "]);
string item_name = llList2String(purchase_request, 0);
key purchasers_key = (key) llList2String(purchase_request, 1);
// Debug
llWhisper(0,"item name: " + item_name);
llWhisper(0,"purchasers_key: " + (string) purchasers_key);
// give item specified in the email to person described in email
llGiveInventory(purchasers_key,item_name);
}
}