Main logo
Digital Strawberry Girl (Chris) Blog

So I volunteered again for a .NET user group monthly meeting – this time I’m presenting a whole session on getting information into and out of Second Life using .NET on the server-side. If you can make it along on Saturday 27th at 12pm SLT, you may learn something about the following (agenda still to be confirmed!):


It's all about the data - storing data from SL externally, using external data in-world
                What can you store?
                What can you get in-world?
                How can you get data into and out of SL - HTTP, XML RPC.
The basics of HTTP - GET and POST
Making HTTP requests from SL
                Encoding request data correctly
                Handling a response
ASP.NET Pages and Handlers
                How to respond to data coming from SL
Using LSL to work with responses
                A brief overview of LSL lists
                Doing something fun with data
XML RPC - what is it? How can it be used?
                Walkthough of basic XML RPC code on the server
                Sending data in-world to a prim and doing something fun with it
Email – send feedback on a notecard, receive data
Future – LSL HTTP server (designed to replace XML-RPC) - still a work-in-progress
Breakout time!

 

Once I get slides and code demos ready I’ll package it all together for Saturday and make it all available after the event.

05/09/2008 Blog tagging

So I got blog tagged by Dana Coffey - and what does this mean? Well, I have to let the world know 6 random facts about myself. Here goes!

  1. I'm allergic to milk (diagnosed officially), and I think I'm allergic to almonds, possibly peanuts. Personally, I'd rather not test this out, so I just avoid them.
  2. I grew up with, at one time, 4 cats, a pair of lovebirds, two rabbits, and a tank of tropical fish. The fish died, Romeo killed Juliet, the rabbits tried making bunnies so we had to give one away... the cats lasted years, though.
  3. I once almost joined the RAF to be a pilot, but chickened out. Still would love to learn to get my pilots licence, and to fly a helicopter.
  4. I had ballet, tap dance, and modern stage dance lessons as a kid over around 13 years. During that time, I appeared on stage as a sailor, an icicle, a cat, and in quite a few outfits covered in sequins.
  5. Because of the dance lessons, I had real problems with my ankles as a kid, and once ended up off sport with ankle in plaster for 6 weeks. During all sports lessons, I would play on the BBC micro in the school, tinkering with BASIC programs. This may have had an impact on my chosen career.
  6. I used to go by the alias of Crustacean on several Telnet talker services (primitive chat rooms, for those of you too young to remember them) around the mid 90's, and it's because of those talkers that I ended up meeting my husband.

So, now, aren't you glad you read that? So, here are the rules:

  1. Link to the person who tagged you.
  2. Post the rules on the blog.
  3. Write six random things about yourself.
  4. Tag six people at the end of your post.
  5. Let each person know they have been tagged.
  6. Let the tagger know when your entry is up.

My victims for this are:

James Hart, Dave Sussman, Dan Maharry, Lou Barr, Kyle G, and Zain Naboulsi

25/08/2008 Catching up

I've been totally swamped with all sorts of projects recently, including hacking with OpenSim code, building a SharePoint deployment solution, building content for then hosting another fantastic event on Second Life, hosting Code Clinics on Microsoft Island every Wednesday, and watching Bob the Builder (we love BBC iPlayer).

From the recent code clinics I've had requests for some links and follow-up materials, so catching up on the past few weeks here's what I've got (it's not an exhaustive list, sorry, but I'll try to keep more notes following meetings in future!):

Data Access tricks - the Using statement

This one generated a fair bit of feedback from members who'd not discovered this extremely handy tool. With minor tweaks to your code you can ensure that data access code always closes your connections cleanly. For example:

Using conn As New SqlConnection(dsn)
  Using cmd As New SqlCommand("SELECT * FROM Employees", conn)
    conn.Open()
      Using rdr As SqlDataReader = cmd.ExecuteReader()
        While rdr.Read()
          Console.WriteLine(rdr(0))
        End While
      End Using
  End Using
End Using

And here is the C# version:

using (SqlConnection conn = new SqlConnection(dsn))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Employees", conn))
{
  conn.Open();
  using (SqlDataReader rdr = cmd.ExecuteReader())
  {
    while (rdr.Read())
       Console.WriteLine(rdr[0]);
  }
}

And it can be used for much more than just data access code too. Here's a starting resource for you:  http://msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx

 

Themes in Visual Studio

Tools - Options, in almost any flavour of Visual Studio. Head into that menu and you can customise your entire environment, showing line numbers, control how your code is formatted, and change your font styles and colours completely. Scott Hanselman's blog post on this has some great links to some dark themes for Visual Studio.

 

VS 2008 & .NET 3.5 SP1

Quite a lot of new features bundled in the latest point release - yes, the numbering system for .NET really is all over the place, since this service pack includes new features, not just bug fixes. But no, it's 3.5 SP1, not 3.6. Numbering aside, for more information, and links to the download, head here.

 

SQL Server 2008

The latest and greatest database from the MS; personally I'm interested in seeing if I can get my OpenSim database down from 1.4Gb to something more realistic with some of the new data compression wizardry! For more about new data types, new features, and the rest, head here.

 

10 Tips to Better Javascript

From the recent discussion on how to improve your JavaScript life came the following:

/* JavaScript 
    - it's not as bad as you think */
/* 10 steps to better JS Code */

var agenda = [
    'Use a proper editor and debugger',
    'Use var obsessively',
    'Understand "falsiness" and "truthiness"',
    'Learn to love object, function and array literals',
    'Grasp the symbol/string dichotomy',
    'Learn to use regexes and JS string functions',
    'Master scope and closures',
    'Don\'t try to build classes like you\'re used to',
    'Grok "this" and functions as values',
    'Use JQuery'
];

 

If you've not yet joined us for a Code Clinic on Microsoft Island, or have never even logged onto Second Life, why not give it a try? It's a great way to meet peers and learn about new and existing technology without having to leave your own home. Drop me a line if you need convincing - chris at codetorque dot com.


Over the past week I've made some great progress on my OpenSim experiment. For starters, I've got my server configured in Grid mode, and I have all four of the main servers running on SQL Server. This did require a bit of development - the inventory server was quite broken for SQL Server, so James and I fixed the code and submitted a patch, but the good news is that this means it'll be in a better state for the rest of you from now on.

If you're committed to switching from SQLite as much as possible then I would recommend configuring your server to run in grid mode. Even if you are working locally, there's something a bit more comforting about seeing messages relevant to each server on each of the console windows, rather than all jumbled up in one console window. Makes it much easier to see bugs and have a think about how to fix them, for starters.

So, where to start? Well, good news and bad news - the good news is that this is possible, the bad news is that it's not simple, and unless you figure out how to export content from a SQLite-based OpenSim, you'll be starting from scratch on your new sim. Before you start, you obviously need a SQL Server to work with. As long as you can install SQL Express on your OpenSim server, you have everything you need, and since SQL Express is a free download, there's no cost involved. Get SQL Express from here, then get SQL Management Studio Express from here - this will give you a tool for running queries and editing your database.

Now, I'm assuming you've done the right thing and already configured your system so you have a Subversion client installed, right? TortoiseSVN is my favourite, with its extremely simple shell integration. So, you have an OpenSim directory and you can grab the latest source code from the Subversion repository - this is pretty important, since the code changes very frequently. Now you will need to head to SQL Management Studio Express and create a database ready to store your OpenSim data. Right-click on the Databases node and and select New Database. Call it OpenSim, accept all defaults and click OK.

The next step is to create a user account for running your OpenSim on SQL Server. Firstly, you need to enable Mixed Mode authentication on SQL Server.

Right-click on your database server in Management Studio and select Properties, then go to the Security tab and select SQL Server and Windows Authentication mode, click OK. Back in Management Studio, expand the Security node and in the Logins section right-click and create a new user, called whatever you like, select SQL Server authentication, give it a strong password and select the OpenSim database as the default database. Click OK.

Then navigate to the OpenSim database and go to the Security, then Users section. In there, create a new user, select your new admin account and make sure it has the db_owner role in the Database role membership section. Click OK and you should be ready to use that account to connect to the database.

Next step is to create the tables you'll need to store all the data from OpenSim. I have my OpenSim code in C:\OpenSim, so on my system, I navigate to C:\OpenSim\OpenSim\Data\MSSQL\Resources to find the SQL scripts you'll be needing to create the base tables in the database. Open each script in turn in Management studio and click Execute against them all. Provided you have no errors, you will be good to go with running OpenSim in grid mode on SQL Server!

Time to edit the Ini file. I recommend heading to the OpenSim documentation on configuration for more in-depth details on this process, but here's an abbreviated version that might help fill in some gaps for you. While there is a mssql_connection.ini file, I also have settings in my main ini file too - I haven't yet dug through the code thoroughly enough to know which ones are used and which ones are not. There's a sample mssql_connection.ini.example file in the OpenSim code repository, so make a copy, rename it mssql_connection.ini and replace the appropriate values with the correct data for your server. As an example:

[mssqlconnection]
data_source=servername\SQLEXPRESS
initial_catalog=OpenSim
persist_security_info=True
user_id=adminuser
password=password

In the main ini file, [EDIT 25th Oct: NOTE that the section below marked asset_database should be set to "grid" - this is very important or you end  up using  SQLite for asset storage!]

gridmode = True

storage_plugin = OpenSim.Data.MSSQL.dll
storage_connection_string = "Data Source=servername\sqlexpress;Database=OpenSim;User=adminuser;password=password;";
storage_prim_inventories = True

appearance_persist = true
appearance_database = "MSSQL"
appearance_connection_string = "Data Source=servername\sqlexpress;Database=OpenSim;User=adminuser;password=password;";

inventory_plugin = OpenSim.Data.MSSQL.dll
inventory_source = "Data Source=servername\sqlexpress;Database=OpenSim;User=adminuser;password=password;";

userDatabase_plugin = OpenSim.Data.MSSQL.dll
user_source = "Data Source=servername\sqlexpress;Database=OpenSim;User=adminuser;password=password;";

asset_database = "grid"
asset_plugin = OpenSim.Data.MSSQL.dll
asset_source ="Data Source=servername\sqlexpress;Database=OpenSim;User=adminuser;password=password;";

The other part of the puzzle is getting your sim running in grid mode, and for that to work you need to be a little more clever with IP addresses and the like, but don't let that put you off. Know your server's IP address, then enter it in the following section with the following port numbers:

grid_server_url = http://192.168.0.1:8001
grid_send_key = null
grid_recv_key = null
user_server_url = http://192.168.0.1:8002
user_send_key = null
user_recv_key = null
asset_server_url = http://192.168.0.1:8003
inventory_server_url = http://192.168.0.1:8004

Notice there are some keys listed in here that are null - you should change these so that you only allow access to people who know both your server's IP AND the appropriate keys to grid up with you. And from looking through the code, it appears that the keys are any valid string value, though I haven't yet tested this out.

You may also want to double-check that the IP address is configured correctly for your region (head to the OpenSim\bin\Regions\default.xml file) and make sure that the IP addresses are set appropriately. Again, check the OpenSim site for a bit more information on this.

Once you have configuration sorted, time to run the servers and keep your fingers crossed! The OpenSim site strongly recommends starting servers in a specific order: UGAIS: UserServer, GridServer, AssetServer, InventoryServer, Sim. Note that the first time that you fire up the servers in grid mode, you are asked for some information to create some system-specific configuration files. Make sure that when you start up each server you enter the data correctly - the data you will need to enter is exactly the same as that entered in the ini file, so make sure you fill in the fields so that they match. Once you have configured one server, move on to the next. Once you have all five running, you're almost ready to log in!

Here's a handy tip - now you have 5 console windows open, click on one of them on the task bar, then ctrl+click on the other four windows. Right-click on any of them and select Tile Horizontally and you will see all your servers neatly arranged, and you can watch things happening as you log in and do stuff on your sim.

Just before you connect, you need to create a user account, so go to the user console and create a new user account. Then it's time for the client bit - if you're using the SL client, set your loginuri startup switch as before, but this time you'll connect to port 8002, not port 9000, so for example:

"C:\Program Files\SecondLife\SecondLife.exe" -loginuri http://192.168.0.1:8002 

Once you launch your client, you should be able to connect to your grid and off you go. Fingers crossed, and I hope it works for you. Note that I think there's a bug with creating folders in your inventory, so watch for errors there. You may have to go with a completely unorganised inventory for a while until that's fixed (which may well be soon).


I've just been through two days of pain trying to get content deployment to work from an internal authoring site, authenticated against Active Directory, to a live site that is Internet-facing (hence allows anonymous access), and has a forms authentication user store. It's more of an admin nightmare than a developer task, but as I've found over many months, working with SharePoint as a developer involves a lot of the admin side of things too. This blog post is a guide to a proof-of-concept, and not meant for a live production environment.

So, what can I share with you that might help? Well, let's list a few links that you need to read first:

http://technet.microsoft.com/en-us/library/cc263428.aspx

http://www.harbar.net/archive/2007/06/27/Content-Deployment-Ensure-your-platform-hygiene-before-randomly-abusing-the.aspx

http://blogs.msdn.com/sharepoint/archive/2006/05/02/content-deployment.aspx

So, that out of the way, here's how I got it to work. And bear in mind that this is on a development machine where all sites are hosted on the same box - albeit in different web applications. Different applications, different authentication, same central administration application.

Firstly, you'll need to have two sites, one for authoring, one for live. If you want a forms auth site as your live site, there are many resources - this one is pretty good. When you create your sites, the golden rule applies:

The target site for content deployment MUST be created using the BLANK site template

Even better, if you can get it to work (and I could only get this to work for an AD-based site, not the forms auth site, but I digress), you can try the following once you have created the web application to create your target site collection:

STSADM.EXE -o createsite -url <url-to-site-collection> -ownerlogin domain\user -owneremail <email-address>

So, you have a blank target site. I'm going to assume you have an authoring site set up to use some kind of template - I set mine up as a collaboration portal. Another word of warning - as yet, I've not tried content deployment against a site with custom features, web parts, etc. As far as I know, those have to be installed separately and available on the destination server prior to deployment - I may have to write a follow up to this article when I get that far. Enter some content to make it clear that your site has been deployed - I added some images to the main images library and edited a couple of content editor parts. Now, over to Central Administration console you go.

Head to the Operations tab and there you will find the option to change your content deployment settings and to set up deployment paths and jobs. In my Content Deployment Settings, I have configured my server to accept all incoming deployment jobs, and selected my server from the import and export server drop-downs. Worth a note - the temporary files entry on here specifies a local path for temporary storage of deployment data. I have read that you need to make sure this directory can be written to by your service account, so I added appropriate security settings to that path to make sure there would be no grumbles there.

Now, to set up some paths and jobs. I created a new path and selected my source application as the authoring site. Make sure you select the appropriate site collection - mine all use the root site collection, so this was a simple setting. The URL to your Central Administration application should be simple enough to enter, and you need to make sure you can connect to that application using the appropriate credentials. One of the benefits of a hacky dev environment is a central user account for all application pools. Again, this is a proof-of-concept. Select the destination web application and site collection, then decide on what to export - user names, other security information - the choice is yours depending on your configuration. I've set this up to only deploy role definitions. Click OK, and fingers crossed the first part is done.

If this works ok, you'll have a quick deploy job set up already. Try running that and pray for success (keep clicking on the Status column header to refresh the grid). If you get a fail, you may need to double-check some settings. And if you chose anything other than a blank site when you started out, don't blame me :) Now, bear in mind that this quick deploy doesn't deploy the content! This is a big thing I found - I was expecting it to have deployed everything - not so. If you browse to your site now it will look pretty empty, so you should now create a new job to deploy content from authoring to live.

Create a new content deployment job for that same path and set it to deploy the entire site collection, and deploy all content, including anything previously deployed. You may be able to run this with just deploying new content, but my first instinct was to deploy everything first time. Later on, create a job to deploy changed content and set it to run on a schedule if you like. Run the job, make a coffee, then come back and find that the whole thing has run perfectly... well, that's the theory, and I certainly hope it works for you. If not, there are a lot of resources out there with suggestions for how to make it run a bit more smoothly, and there's a great blog post from Andrew Connell with information on a couple of hotfixes that might help solve some issues.

I'm going to be doing a lot of work on a project that involves this configuration over the next few weeks, so I may write some more on this as and when I can. In the meantime, I'd like to thank Nebulae Voom, friendly SharePoint guru from the .NET group in Second Life, and SharePoint from twitter (The official tweetstream of the SharePoint product group) - while neither solved this for me, you helped my brain think the right way!


Over the past few weeks I've taken a big leap into the world of Open Source development and started messing around with OpenSim, the BSD licenced 3D virtual world based on Second Life, but reinvented from scratch using C#. It's an immense project that's been in development for a while, and it's starting to look pretty good.

Getting hold of OpenSim is relatively easy, especially if you're a developer and have used Subversion before. Grab the latest code, run the pre-build tool, build the solution and you're just about ready. Make sure you run the correct exe for your system (64bit machines have to run a 32bit launcher), and you are hosting your own little simulator that you can connect to.

So, next step is to connect to the newly-created world. You can either use the standard Second Life client with a modified startup shortcut, or you can download and use the realXtend viewer and specify your server as part of the launch. And then you're in your own little world...

sf5

Now, since that picture was taken I've completely broken the server by attempting to hook it up to SQL Server, but that's all part of the fun - and there are so many bits and pieces to look at and tweak that this is proving to be quite an entertaining project.

So, why am I doing this? Well, I've been working with Kyle for a while on MS Island on Second Life, and this is part of an exploration of open source alternatives to the Linden Labs controlled world. Project Manhattan is the first project we're working on, and it's still in its early stages - but it certainly makes a welcome change from SharePoint development.


Handy tip that James pointed out the other day - my Virtual PC machine console window keeps disappearing (perhaps thinking that I have an external monitor plugged in). You can see it on the task bar, but clicking on it doesn't bring it to the top of the pile on the desktop, so, how do you get it back on your main screen?

In the following order:

  • alt
  • space
  • m
  • any arrow key
  • move the mouse

Hey presto, the window snaps to under your mouse cursor and you can drop it wherever you like. Very handy and useful to remember.


April 26th is the day for your diary; all our preparation work finally gets load tested to the extreme as we host the Heroes Happen Here launch event for Visual Studio 2008, Windows Server 2008 and SQL Server 2008 on Second Life. We're getting three extra islands for launch day so we can make the event run as smoothly as possible for all the attendees, and there'll be much partying and some freebies for those who come along to the island.

Before that happens, I'm travelling to Orlando for 3 days (figured I'd need jet lag before a major launch event), for the DevConnections conference, where I'm hoping to get up to speed on some of the cool new stuff that's been coming out recently. I've not had a chance to play with Silverlight yet, or look into the new MVC framework, since I've been so busy with SharePoint code and SL fun. And there's also a load of SharePoint talks happening at the same time, so I'm hoping to chat to some gurus about SharePoint Internet site projects (my next piece of work, starting soon).

I also mentioned recently that I was in a recording of .NET Rocks recently; well, the show is now live, so hit the link and hear a bit more about what I've been doing (along with Kyle and Zain) on Second Life, and some discussion of why it's not (as many people think of it) a game. Zain Naboulsi does a great job of explaining that too in his recent video interview with Keith Combs and Matt Hester.


Since I got involved with the Second Life .NET group, my free time has been eaten up by a monster! Ok, not the bad kind, but it's amazing how addictive Second Life is once you start to get involved with something worthwhile. We've been tackling this monster from two perspectives - one is to think about what members would like to see and do on the Microsoft Island, and the other is to get very geeky and enthusiastic about what the technology can do for us and figure out ways of making it work. It's a fun little hobby, made all the more exciting by the constant stream of client updates coming out from Linden Labs; the most recent Release Candidate viewer (1.19.1) has got us most excited, since it gives us the option of showing a web page in-world with very little effort. Ok, so it doesn't seem to work on any of my Vista machines, but I'm sure this will be fixed soon.

Anyway, as a result of all the work that's been done in-world, friend of the group, Todd Anglin of Telerik had a word with Richard Campbell of .NET Rocks (the excellent long-running podcast show on .NET development), and to cut a long story short, Kyle Gomboy (G2 Proto in SL) and I will be participating in a recording of the show next week about .NET in Second Life. I'm sure it'll be a fairly strange experience, but hopefully I won't make a complete fool of myself.

13/03/2008 Two and a bit

I have been amazed at how quickly Nathan has changed over the past few months. He never stops talking, and while we may not catch every word, he tries so hard and you can hear his pronunciation improve daily. His rapidly exploding vocabulary is amazing - he knows numbers up to 12, all the letters by name, and takes pride in telling me how we have "one gate, two gates" on our stairs. His enthusiasm for life is fantastic, and it makes for some hilarious moments - shopping in Sainsburys is possibly the best example, since he will shout out the numbers of each of the aisles as we go down them. He's also getting the hang of brands, and enjoying the likes of Bob and Thomas - partly though exposure at the nursery. And his friends at nursery are very sweet - each morning when I drop them off, they run over to say hello.

Of course, he has his little moments - he gets very frustrated if we don't understand what he's saying, and if he decides he wants to do something, we have to tread very carefully if we don't really want him to do it. We get told off regularly, and we get told what to do quite often. "Sit down, play cars", for example. And then last night, he was being cheeky and refusing to go to bed by telling me, with a smile on his face, how "Bob's hat is yellow..., aaaaand Wendy's hat is blue..., aaaaaand Scoop's yellow, aaaaand... " and so on - makes it _very_ hard to tell him it's time to go to sleep!