Freesex - Sex and Second Life - LibSL Edition

qDot and Emilio giving an exhibition. Hawt.

Don't call it a comeback

Even though it totally is and we all know it. This move to San Francisco (for those of you unaware: I just moved to San Francisco. You know, just in case you didn't read or process those last 5 words correctly.) has completely blown my posting schedule. However, I've managed to preservere and keep half-assing shit together in my trademark half-assed way, which brings us to today's article: TranceVibe (and teledildonics in general) in Second Life, volume 2.

I should probably preface that this article is gonna be somewhat dry if you're not directly involved in Second Life programming. I'm assuming you have at least knowledge of the world, and possibly some knowledge of programming in the world.

I'll also have a copy of this on my non-dildo-in-the-header website, Nonpolynomial Labs. It'll be the exact same text, minus the dildos (Yeah, I don't know why people would want that either. Workplaces would be a much happier environment with more dildos).

Where we left off

So, why do we need a volume 2? Simple. Volume 1 sucked.

However, for those of you not familiar with Second Life, I suggest you check out the first article to get an idea of what the hell is going on.

Let's look at our needs. In trying to make a teledildonics client, we'd preferably like to have the highest polling rate (the rate at which we recieve updates from the controller) possible. Since this isn't a built in function of the Second Life software itself, the scripting language would have to be used. There's 3 built-in communications schemes of the Second Life scripting system at the moment.

  • Email - You can send 1 every 20 seconds per script. Obviously not gonna work.
  • XML-RPC - This is what version 1 worked on. You can /reply/ to 1 request every 3 seconds per script (more with script multithreading, the act of linking multiple objects together and then having the root prim manage the "prim thread pool" of objects by delegating calls to be made by scripts not currently in a resource wait). However, you cannot make outbound connections, only reply to inbound connections, and there's no guarentee of delivery. Which means you had to figure out some way of getting the XML-RPC channel ID to whatever needed to communicate with the object. While great for proof of concept, this didn't work so well for actual usage.
  • HTTP - This is new! And still kinda slow. As of this writing, you can make 20 outgoing HTTP requests every 100 seconds per agent per region (basically, all of your objects on a single simulator take up that resource). As of tomorrow, I believe this moves to 1 request per object per second, which, while better (and also a candidate for prim thread pooling), still isn't great for our needs. While we could probably do something managable, there also exists the issue of passing the calls back and forth between clients. Either IPs would have to be exchanged and firewall ports opened, or else a proxy would have to be used.

Those are the choices given to us by Linden Lab. However, we can do better than that.

LibSL: ZOMG HAX, but in a good way

Enter LibSecondLife. LibSecondLife is the work of Eddy Striker, Bushing Spatula, Baba Yamamoto, and Adam Zaius (all SL names, of course), that reverse engineers the Second Life communications protocol. The library is written in C# using MS .Net 1.1, and can be used to translate packets before they get to the client, or inject new packets into the outgoing stream. Why is this important to us? Well, I'll get there in about 6 paragraphs from now.

Second Life is a series of pigeons...

For what we're interested in, the Second Life Client and Servers talk to each other in a format that looks something like this:

// ChatFromSimulator
// Chat text to appear on a user's screen
// Position is region local.
// Viewer can optionally use position to animate
// If audible is CHAT_NOT_AUDIBLE, message will not be valid
{
    ChatFromSimulator Low Trusted Unencoded
    {
        ChatData            Single
        {   FromName        Variable 1  }
        {   SourceID        LLUUID      }   // agent id or object id
        {   OwnerID         LLUUID      }   // object's owner
        {   SourceType      U8          }
        {   ChatType        U8          }
        {   Audible         U8          }
        {   Position        LLVector3   }
        {   Message         Variable 2  }   // UTF-8 text
    }
}

That's just 1 of the messages. If you're interested in all 600andsome messages that make up the system, an old version can be found here. An up-to-date version can be found by snooping around the libsl page somewhat, I'm sure. This template changes with almost every update of the SL software, so anything static I'd link to will probably be out of date by the time you read this.

Much of the interaction in Second Life takes place using these messages. LibSL has a program built on top of it called SLProxy that sits on the client machine, watching the messages as they pass between the client and server, and performing special processing on them if need be.

Now, I used the "chat from simulator" message as an example there for a reason. As you can see, in that message, we recieve the name of who/what sent the message, its/their ID (This is a 128bit UUID), various information about where the message came from, and finally, the body of the message (up to 255 characters). All of this data gives us more than enough to work with to create a decent teledildonics client using the SL client and SLProxy.

Through some very basic testing, it's been found that you can get between 10-20 chat messages per second from a sim, depending on sim load (number of agents, number of scripts, so on and so forth). Even the lower bound on this is much better than we could get with the built in LSL functions, and produces much less server-side load.

World's Worst Interfaces for 200, Alex

This idea was inspired by Huns Valen's SLJoy project.

Here's how my crappy, written in 1 hour client worked.

private static Packet ChatFromSimulator(Packet packet, IPEndPoint sim) 
  {   /*.....Lots of message processing code cut.....*/
    if(name.Equals("Object"))
    {
        try
        {
            //usbcontrol = The USB Controller Driver for the TranceVibe
            vibval =(UInt16.Parse(message));
            usbcontrol.SetPower(vibval);
        }
        catch(SystemException e)
        {
            Console.WriteLine("Cannot parse message: "+message);
        }
    }
    /*....Continue to send message to client....*/
  }

Yup. That's it. We watch for chat coming from anything named "Object", expect the message from it to be an 8-bit integer. If it is, we set our vibrator to that value. If it's not, we complain and go on with life.

I repeat. This is not rocket science.

That source I promised 3 weeks ago.

Yup, here it is. (Update 2013-05-25: This now points to my github repo. It's in there.)

This will need to be extracted into the applications directory of a libsl svn checkout which can be picked up at their gna.org site.

You'll also need the usb DLL in the same directory with your executable. To install the TranceVibe if you haven't yet, just plug it into your computer, then choose the .inf file included with the zip as your driver.

This code is released under the "I wrote like, 5 lines of this. I don't care what you do with it, since it has to do with teledildonics it's gonna come back to me at some point, so I already pwn your ass." license.

Where to go from here

This is just the base of what I hope to be a much more expansive project. As I said in my presentation, I'm very interested in making extensible interfaces other people can build on to easily create their own control schemes. Hopefully others will pick up the ideas from this code and go their own directions, too. SL is a fun platform to work on, and I can't wait to see what ideas others come up with.