Close

Hacking within VR

A project log for Metaverse Lab

Experiments with Decentralized VR/AR Infrastructure, Neural Networks, and 3D Internet.

alusionalusion 04/02/2015 at 23:250 Comments

With full 2D support for the web inside Janus, it would be an incredibly useful feature to have a web access terminal to SSH into remote Linux servers. I dream of creating the ultimate operations and command center inside VR. It's more than just having your crazy multiscreened office wherever you go, it's about having other people join you in that space and do cool stuff together. Grab models, view and edit them directly inside Janus, create rooms on the fly, hack all the things. Lets get into it then.

Janus uses the AssetWebSurface to define an interactive surface that provides the 2D web view. This can be placed on an object by specifying a websurface_id that matches theAssetWebSurface's id.

id - id of the AssetWebSurface (note that the corresponding Object should have its "websurface_id" attribute set to this value)
src - website to use for the AssetWebsurface
width - texture width for rendering the AssetWebSurface height - texture height for rendering the AssetWebSurface

<AssetWebSurface id="google" src="https://www.google.com" width="1920" height="1080" /> ... <Object id="plane" websurface_id="google" />

Here's an example I pulled from a room, notice the websurface_id being used to tag those objects you wish to map the surface onto:

<!-- Written with Janus VR.  URL: http://bitgrid.io/lullabot.comVR/index.html -->
<html>
<head>
<title>Lullabot loves you!</title>
</head>
<body>
<FireBoxRoom>
<Assets>
<AssetObject id="plane" src="plane.obj" />
<AssetWebSurface id="dotcom" src="https://www.lullabot.com" width="1920" height="1080" />
</Assets>
<Room use_local_asset="room_plane" pos="0.000000 0.000000 0.000000" xdir="1.000000 0.000000 0.000000" ydir="0.000000 1.000000 0.000000" zdir="0.000000 0.000000 1.000000" col="1.000000 1.000000 1.000000" default_sounds="false">
<Object id="plane" js_id="1" pos="1.000000 1.000000 5.000000" ydir="0.000 0.000 1.000" zdir="0.000 -1.000 0.000" scale="25.600000 3.900000 17.800001" websurface_id="dotcom" />
</Room>
</FireBoxRoom>
</body>
</html>

This is what the code looks like inside Janus. The obj is just a slab like a tablet that can be resized / positioned / rotated any which way.

In order to do live editing inside of Janus, I recommend turning off cache (delete the folder too; don't worry it'll respawn) and enable editing mode. Any changes that you make inside the room can be saved by pressing ctrl+s to copy the HTML source to clipboard. Btw, the js_id's will change all the time, just ignore that variable.

You can add as many screens as you want and position them inside Janus. Here's an example of a multi screen environment:

<!-- Written with Janus VR.  URL: http://alusion.net/snacka.html -->
<html>
<head>
<title>Snackaday</title>
</head>
<body>
<FireBoxRoom>
<Assets>
<AssetObject id="plane" src="plane.obj" />
<AssetWebSurface id="twitt" src="http://www.twitter.com" width="1920" height="1080" />
<AssetWebSurface id="hacka" src="http://www.hackaday.com/" width="1920" height="1080" />
<AssetWebSurface id="utube" src="http://youtube.com" width="1920" height="1080" />
<AssetWebSurface id="dyne" src="http://dyne.org" width="1920" height="1080" />
<AssetWebSurface id="goog" src="http://www.google.com" width="1920" height="1080" />
<AssetWebSurface id="stack" src="https://stackoverflow.com/" width="1920" height="1080" />
</Assets>
<Room use_local_asset="room_plane" pos="0.000000 0.000000 0.000000" xdir="1.000000 0.000000 0.000000" ydir="0.000000 1.000000 0.000000" zdir="0.000000 0.000000 1.000000" col="1.000000 1.000000 1.000000" default_sounds="false">
<Object id="plane" js_id="14" pos="-6.200000 2.700000 4.800000" xdir="-0.866 0.000 -0.500" ydir="0.129 0.966 -0.224" zdir="0.483 -0.259 -0.837" scale="3.700000 2.600000 2.000000" websurface_id="hacka" />
<Object id="plane" js_id="15" pos="10.000000 1.000000 5.000000" xdir="-0.866 0.000 -0.500" ydir="0.129 0.966 -0.224" zdir="0.483 -0.259 -0.837" scale="2.000000 2.000000 2.000010" websurface_id="dyne" />
<Object id="plane" js_id="16" pos="-10.000000 1.000000 5.000000" xdir="-0.866 0.000 -0.500" ydir="0.129 0.966 -0.224" zdir="0.483 -0.259 -0.837" scale="2.000000 2.000000 2.000001" websurface_id="utube" />
<Object id="plane" js_id="10" pos="1.000000 1.000000 5.000000" xdir="-0.866 0.000 -0.500" ydir="0.129 0.966 -0.224" zdir="0.483 -0.259 -0.837" scale="2.000000 2.000000 2.000001" websurface_id="goog" />
<Object id="plane" js_id="11" pos="-5.000000 1.000000 5.000000" xdir="-0.866 0.000 -0.500" ydir="0.129 0.966 -0.224" zdir="0.483 -0.259 -0.837" scale="2.000000 2.000000 2.000001" websurface_id="stack" />
<Object id="plane" js_id="12" pos="-2.300000 3.100000 5.000000" xdir="-0.866 0.000 -0.500" ydir="0.129 0.966 -0.224" zdir="0.483 -0.259 -0.837" scale="3.300000 2.400000 2.000000" websurface_id="twitt" />
</Room>
</FireBoxRoom>
</body>
</html>

Nice view. But what if you wanted to edit text files from inside Janus? Shellinabox is a web-based SSH terminal to access remote Linux servers. It has a built in web server that runs as a web based ssh client on a specified port and prompt you a terminal emulator using any AJAX/JavaScript and CSS enabled browser. Sweet, my VPS is running Debian so all I had to do was to simply apt-get install openssl shellinabox. I changed the default port, initiated the daemon, and opened up a web browser:

Yes it works! That was almost too easy. I went into Janus and opened a portal to my site but was greeted with blank gray screens. Janus is only going to allow 80/443 through afaik and shellinthebox uses port 4200 by default; I should try routing the traffic through a webserver proxy. I followed instructions to setup an always available Linux terminal for the Raspberry Pi here:

http://blog.remibergsma.com/2013/03/15/always-available-linux-terminal-shell-in-a-box-on-raspberry-pi/

I installed Lighttpd web server and configured it to provide a proxy service to route a web request on a specific url to another port.

Add in /etc/lighttpd/lighttpd.conf file the item "mod_proxy" in the server.modules section:

server.modules = (
    "mod_access",
    "mod_alias",
    "mod_accesslog",
    "mod_compress",
    "mod_redirect",
    "mod_proxy"
)

Add these lines at the end of /etc/lighttpd/lighttpd.conf

proxy.server = ( 
    "/shell" => 
    ( ( 
        "host" => "127.0.0.1",
        "port" => 4200
    ) )
)
~# /etc/init.d/lighttpd restart

So when I go into my browser I type http://mydomain.com/shell instead of http://mydomain.com:4200. It worked inside my browser but inside Janus I still get blank grey screens. After some trial and error I also ran into 404 File Not Found. Sleep is lost.

After some more research I learned about GateOne through a comment. It's an HTML5-powered terminal emulator and SSH client that's loaded with features:

Support for Multi-users and multi-terminals, image and PDF support, fancy text, natural copy paste, logging, embedding into any web application via JavaScript, multi-factor auth, playback plugin to rewind and play back connected sessions in real time, and no browser plugins required.

The setup is as easy as 1, 2, 3:

git clone https://github.com/liftoff/GateOne.git
python setup.py install
sudo gateone

The configuration files are in sudo nano /etc/gateone/conf.d/10server.conf. For testing I disabled ssl and named a url_prefix. For production it'd be wise to purchase a SSL certificate. Here's what it looks like in a browser.

Integrating it into Janus is tricky. For most of the night the web app failed to initalize. I went through the documentation and remembered that I needed to embed some JavaScript into my page in order to make it work. The documentation inside the repo is updated. ~/GateOne/gateone/tests/hello_embedded/static. I created an <AssetScript> and pointed that to the gateone.js file found in the directory.

I opened up the JavaScript support documentation for JanusVR to see if there was something I could do to initialize the web app and came up with this: [change the url]

room.onload = function() {
        GateOne.init({url: 'http://yourdomain.com/gateone'});
}

I stuck that into the header of my Firebox HTML file. After many trial and errors, still no dice. File not found, blank page, it wasn't initializing for me. The closest it got was displaying the UI:

I decided to get some rest and see if I could go at this again with a fresh mind in the morning.

Discussions