Show Public Room info on your HP

Show Public Room info on your HP

Update – IMVU has recently updated their SSL policy, so the URLs below have been changed to “https://” instead of “http://”.

The “My Room” panel currently on an avatar’s home page is incredibly lame. Recently, there was this post on the Homepage Building forum, where the OP wondered if it would be possible to put actual public room info, picture, status, etc. right on your home page.  The answer might be a flat out “no”, but I took this as a challenge to see if I could find a tricky way to this.

If you want to show public room info on your HP, here’s the TL;DR version. I’ll explain how I did it afterwards, in the nerd zone.

1) First make sure your “My Room” panel is visible to all. You can change that if you need to on the Account page.

2) Copy/paste the following codes to the Custom HTML/CSS editor:

<script type="text/javascript">
/* Triggerless.com Public Room Codes */
$(document).ready(function() {
$('#room_panel_colRow').empty();
$('#room_panel_header').find('.paneltitletext').text('My Public Rooms');
});
</script>
<link rel="stylesheet" href="https://www.triggerless.com/imvu/DisplayRoomDark.css" />
<script type="text/javascript" src="https://www.triggerless.com/imvu/DisplayRoom.ashx?room=your-room">
</script>

3) If your page background is light, change DisplayRoomDark.css to DisplayRoomLight.css, otherwise leave it as is.

4) Change your-room to the actual name of your room, which you can look at at http://www.imvu.com/rooms.

5) (optional) If you have more rooms to display than one, then copy and paste the whole <script>...</script> tag for your-room and give each room parameter the name of each room. It’s best not to duplicate the same room more than once (why would you?) because that might not work.

6) Click the Save button, then reload the page. And voilà, everything worked.  If it didn’t, and you get “Unknown Room”, then you probably got the name of the room wrong.  If it still doesn’t work, PM me and we can figure it out.

7) (very optional) Maybe you don’t like the font size, colors, positioning, or something else I chose. It’s easy to add a <style> element to override my style choices, and I’d encourage you to do so.

Here’s a template of the CSS controlling the styles of the Public Room widget, with explanations. Fill in the curly braces of what you want to change, and delete whatever you don’t want to modify:

<style type="text/css">
.room-info {}    /* Container element for the whole widget */
.room-table {}   /* The two cell table */
.room-left {}    /* The left cell of the table */
.room-img {}     /* The room image */
.room-right {}   /* The right cell of the table */
.room-name {}    /* The name of the room */
.room-owner {}   /* The line stating "by Owner" */
a:visited.room-owner-link, a:link.room-owner-link, a:hover.room-owner-link,
a:active.room-owner-link {} /* The link to "Owner" */
.room-desc {}    /* Room description text */
.room-detail {}  /* The line that reads "Participants: 0/10 | Join" */
.room-number {}  /* The numbers for the participants */
a:visited.room-join, a:link.room-join, a:hover.room-join,
a:active.room-join {}   /* The Join link */
.room-avis {}     /* Text saying "Who's there" plus names/sizes of avis */
.room-avi {}      /* Each entry for a joined avi */
.room-avi-name {} /* Name of joined avi */
.room-avi-size {} /* Size of joined avi */
</style>

If you’re comfortable with CSS, this should give you all you need. If this was over your head, then you should probably end here because we’re now entering…(cue video game beeps)

nerdzone

How does this thing even work? Where to begin?

The sequence of steps involved includes:

  • Call GetRoom.ashx, which returns JavaScript code that builds an empty HTML UI template for the Public Room widget, and also JavaScript code that will run when the page is fully loaded,
  • Once the page is loaded, call the getRoomInfo() method, which makes an AJAX request to Room.ashx,
  • Room.ashx makes a client request for the public room web page, scrapes the HTML for useful info, and returns JSON data, and
  • Use the returned JSON to fill out the HTML UI template with the current information.

GetRoom.ashx

If you code in ASP.NET or MVC, you may or may not know about “generic handlers”, which have the file extension .ashx. These allow you to grab an HttpWebRequest, run some C# code, and return a response, typically plain text, back to the client.  They don’t have the overhead of WebForms or MVC plumbing, so in many ways they are like compiled PHP script, only written in C#.

You can see the JavaScript emanated by GetRoom.ashx at https://www.triggerless.com/imvu/DisplayRoom.ashx?room=your-room.  It’s basically just a JavaScript template, where the value for “room” is inserted in several places. There are three pieces to this script, the first creates a new method getRoomInfo() if it doesn’t yet exist. The second is a bunch of document.write() statements that build up the HTML template for the public room widget sans actual data.  The last line called getRoomInfo(), which will attach a JavaScript callback when the document is finally complete, or in jQuery-speak, $(document).ready(function() {});

getRoomInfo() method

This method makes an AJAX GET request to Room.ashx, supplying the correct room parameter.  The result is JSON, plain and simple. You can see for yourself: https://www.triggerless.com/imvu/Room.ashx?room=cheris-office-4. Once the plain text response is successfully received, we parse it into a JavaScript object, then use jQuery to modify the HTML, set the <img src=””> for the room picture, the name of the room, the participants, and so forth. All very straightforward if you have basic jQuery knowledge.  Some of the properties are HTML encoded, so you have to use .html() instead of .text() to get them to show up correctly. The AP and VIP badges are hidden using the CSS rule display:none, so if the room is AP and/or VIP, you have to unhide the badge images using .css().

Room.ashx

This is written in C# and it does the heavy lifting.  You can find the code here: https://www.triggerless.com/imvu/Room.ashx.txt. The code flows basically as follows:

  • Set the Response.ContentType to “text/plain”,
  • Add an “Access-Control-Allow-Origin” response header so you can call this script from an IMVU page,
  • Create an HttpWebRequest to http://www.imvu.com/rooms/room-name,
  • Create its CookieContainer, and add the osCsid cookie stored in web.config (you didn’t think I would list mine, did you?),
  • Spoof the user agent as Google Chrome (or your favorite browser, also in web.config)
  • Get the response stream, and use Western-1252 encoding to read the characters into a StringBuilder (IMVU, why u no UTF-8??),
  • Wrap the final string from StringBuilder into a StringReader, and read line by line until you get to the goody, the line reading “var roomInfo = {“, and start collecting the JSON text off the page,
  • Replace apostrophes with quotation marks, because JSON parsers barf on apostrophes, even though they’re legit in inline JavaScript,
  • Send it back as a response.

There’s also instances when things can fail, like a bad room name, so we send back some JSON for “Unknown Room” (ErrorText) instead. I factored out “GetParameter()” and “Write()” for unit testing, where the HttpContext isn’t available, in case you saw that and were wondering. I should probably do the same thing for AppSettings in the absence of a web/app.config file, but I haven’t gotten around to that yet.

Blah blah blah

So there you have it. It’s not as easy as “just add this CSS and everything is hunky dory”. But it was interesting to make this actually work in a way that anyone can use it without any special JavaScript knowledge.

And about 90% of the way through, I found out a much better way to obtain public room information, actually any room information, using IMVU’s APIs.  If you’re logged into IMVU’s web site, check out http://www.imvu.com/api/rooms/room_info.php?room_id=57622347-225 as an example.  No more HTML scraping, the JSON is syntactically correct, and you get even more info than the public room page.  I figured this out using WireShark while logged into the IMVU client while getting room information.  I plan on using this when I add new features to the home page widget.  Stay tuned 🙂