HTML HUD Demo

From Second Life Wiki
Revision as of 16:09, 25 August 2011 by Kelly Linden (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

<lsl>// HTML Based, Single Script HUD // This is intended to be a tech demo of what html on a hud allows. // * Interaction with SL world (give items, play animations, scan nearby avatars) // * Simple, low overhead (1 scripts, 1 prim) // * Rich, dynamic interface (images, menus, flash) // Updates and improvements are welcome at http://wiki.secondlife.com/wiki/HTML_HUD_Demo

// To Use: // * Create a cube and wear it as a hud. // * Edit the cube while wearing it and add this script to it. // * Add any animations you want to play to the object // * Add any notecards or objects you want to give away to the object.

// License: // This script itself is free to share, modify and use without restriction. // Any linked or referenced files are not included in this license and are licensed by their respective owners under their own respective copyright and other licenses. // Created by Kelly Linden, 2011.

integer display_face = 4; integer button_face = 2; integer link = LINK_THIS; list visible = [PRIM_POS_LOCAL,<0,-0.13,-0.13>,PRIM_SIZE,<0.01,0.25,0.25>,PRIM_ROT_LOCAL,<0,0,0,1>]; list button = [PRIM_POS_LOCAL,<0,-0.04,-0.04>,PRIM_SIZE,<0.05,0.05,0.05>,PRIM_ROT_LOCAL,<0,0,-1,0>]; list init = [PRIM_TEXTURE,ALL_SIDES,TEXTURE_BLANK,<1,1,1>,<1,1,1>,0,PRIM_TEXTURE,button_face,"0b815b79-c8f5-fc98-91fc-e77b53a468e2",<1,1,1>,<1,1,1>,0]; integer is_visible = FALSE; string my_url = "";

string footer; string header; key current_request;

set_header() {

   // TODO: Remove dependency on this css file.
   header = "<html><head>"
           + "<link href='https://d1979ns0fqtj19.cloudfront.net/assets/common-103828347986224535963905120979424958961.css' media='all' rel='stylesheet' type='text/css' />"
           + "<base href='" + my_url + "/' />"
           + "</head><body>";

}

set_footer() {

   // TODO: Remove dependency on the js file
footer = "
<a href='anims'>Anims</a> | <a href=>Scan</a> | <a href='hide'>Hide</a> | <a href='video'>Video</a>
"
       + "<script src='https://d2mjw3k7q9u8rb.cloudfront.net/assets/common-170919042270376442559931151451605602726.js' type='text/javascript'></script></body></html>";

}

toggle_show() {

   if (is_visible)
       llSetLinkPrimitiveParamsFast(link,visible);
   else
       llSetLinkPrimitiveParamsFast(link,button);
   is_visible = !is_visible;

}

string av_image(key id) {

   return "https://my-secondlife.s3.amazonaws.com/users/" + llGetUsername(id) + "/thumb_sl_image.png";

}

string app_profile_url(key id) {

   return "secondlife:///app/agent/" + (string)id + "/about";

}

set_media(string url) {

   //llClearLinkMedia(link,display_face);
   llSetLinkMedia(link, display_face,              // Side to display the media on.
           [PRIM_MEDIA_AUTO_PLAY,TRUE,     // Show this page immediately
            PRIM_MEDIA_CURRENT_URL,url,    // The url if they hit 'home'
            PRIM_MEDIA_HOME_URL,url,       // The url currently showing
            PRIM_MEDIA_HEIGHT_PIXELS,256,  // Height/width of media texture will be
            PRIM_MEDIA_WIDTH_PIXELS,256,   //   rounded up to nearest power of 2.
            PRIM_MEDIA_PERMS_CONTROL, PRIM_MEDIA_PERM_NONE]);  

}

string vec2str(vector v) {

   return "<" + (string)((integer)v.x) + "," + (string)((integer)v.y) + ","  + (string)((integer)v.z) + ">";

}

string bytes2str(integer b) {

   if (b < 1024 * 1024) return (string)(b / 1024) + "KB";
   return (string)(b / (1024 * 1024)) + "MB";

}

string img_html(key agent) {

   return "<a href='" + app_profile_url(agent) + "' class='avatar avatar_thumb' rel='#sl_image_zoom' title='Click to zoom'><img alt='Thumb_sl_image' src='https://my-secondlife.s3.amazonaws.com/users/" + llGetUsername(agent) + "/sl_image.png' /></a>";

}

string agent_menu_html(key agentid) {

return "";

}

string give_list(key agentid, integer type) {

   string resp;
   integer n = llGetInventoryNumber(type);
   integer i;
   for (i=0;i<n;++i)
   {
resp += "
  • <a href='agent/" + (string)agentid + "/give/" + llGetInventoryName(type,i) + "'>" + llGetInventoryName(type,i) + "</a>
  • ";
       }
       return resp;
    

    }

    string give_menu_html(key agentid) {

    string resp = "";
       return resp;
    

    }

    agent_details(key request, key agent) {

       // Get the details we want.
       list r = llGetObjectDetails(agent,[OBJECT_POS,OBJECT_TOTAL_SCRIPT_COUNT,OBJECT_SCRIPT_MEMORY,OBJECT_SCRIPT_TIME]);
    
       // Build the html.
    
    string resp = header + "" + "" + "
    " + agent_menu_html(agent) + "
    " + give_menu_html(agent) + "
    " + img_html(agent) + "" + "
      " + "
    • Scripts:" + "
        " + "
      • " + (string)llList2Integer(r,1) + " total
      • " + "
      • " + bytes2str(llList2Integer(r,2)) + "
      • " + "
      • " + (string)((integer)(llList2Float(r,3) * 1000000.0)) + "us
      • " + "
    " + footer;
       // Send the response.
       llSetContentType(current_request, CONTENT_TYPE_HTML);
       llHTTPResponse(current_request,200,resp);
    
       //llOwnerSay("Memory used: " + (string)llGetUsedMemory() + ", response size: " + (string)llStringLength(resp));
    

    }

    string anim_menu_html() {

    string resp = "";
       return resp;
    

    }

    play_anim(string anim) {

       llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION);
       llStartAnimation(llUnescapeURL(anim));
    

    }

    anims_page() {

    string resp = header + "

    Animations

    Choose an animation:

    " + "
    " + anim_menu_html() + "


    " + footer;
       llSetContentType(current_request, CONTENT_TYPE_HTML);
       llHTTPResponse(current_request,200,resp);
    

    }

    // Process a get request with a path. GET(key request, list path) {

       current_request = request;
       integer path_segments = llGetListLength(path);
       if (path_segments == 0)
       {
           // Home page.
           llSensor("",NULL_KEY,AGENT,96,PI);
           return;
       }
       
       string p0 = llList2String(path,0);
       if (p0 == "agent")
       {
           if (path_segments == 1)
           {
               // just /agent lets show stuff for the owner.
               agent_details(request,llGetOwner());
               return;
           }
           
           // p1 should be an agent id
           key agent = (key)llList2String(path,1);
    
           if (path_segments == 2)
           {
               // Just an agent id. Get their info.
               agent_details(request,agent);
               return;
           }
           else if (path_segments == 4)
           {
               // agent/<id>/<cmd>/<option>
               string p2 = llList2String(path,2);
               if (p2 == "give")
               {
                   string p3 = llUnescapeURL(llList2String(path,3));
                   llOwnerSay("Giving " + p3 + " to " + llKey2Name((key)agent));
                   llGiveInventory(agent,p3);
                   agent_details(request,agent);
                   return;
               }
           }
       }
       else if (p0 == "hide")
       {
           llSensor("",NULL_KEY,AGENT,96,PI);
           toggle_show();
       }
       else if (p0 == "anims")
       {
           if (path_segments == 1)
           {
               anims_page();
           }
           else if (path_segments == 2)
           {
               play_anim(llList2String(path,1));
               anims_page();
           }
       }
       else if (p0 == "video")
       {
           string resp = header
               + "
    <iframe width='255' height='173' src='http://www.youtube.com/embed/m7p9IEpPu-c?rel=0' frameborder='0' allowfullscreen></iframe>" + footer; llSetContentType(current_request, CONTENT_TYPE_HTML); llHTTPResponse(current_request,200,resp); }

    }

    default {

       state_entry()
       {
           llSetObjectName(llKey2Name(llGetOwner()) + "'s HUD");
           llSetLinkPrimitiveParamsFast(link,init);
           toggle_show();
           //llOwnerSay(llList2CSV(llGetLinkPrimitiveParams(2,[PRIM_POS_LOCAL])));
           //llSetColor(<1,0,0>,button_face);
           llRequestURL();
       }
    
       on_rez(integer n) { llResetScript();}
       changed(integer c)
       {
           if (c & (CHANGED_TELEPORT | CHANGED_OWNER | CHANGED_REGION)) { llResetScript();}
       }
       
       touch_start(integer total_number)
       {
           toggle_show();
       } 
       
       http_request(key id, string method, string body)
       {
           //llOwnerSay(method + ": "  + llGetHTTPHeader(id,"x-path-info"));
           if (method == URL_REQUEST_GRANTED)
           {
               my_url = body;
               set_footer();
               set_header();
               set_media(my_url);
               return;
           }
           else if (method == URL_REQUEST_DENIED)
           {
               llOwnerSay("Unable to get url: " + body);
               llSleep(10);
               llRequestURL();
               return;
           }
           
           if (method == "GET")
           {
               list path = llParseString2List(llGetHTTPHeader(id,"x-path-info"),["/"],[]);
               GET(id,path);
               return;
           }
           
           llHTTPResponse(id,400,"Unsupported method.");
           return;
       }
       
       sensor(integer n)
       {
    
    string resp = header + "

    Scan Results:

      ";
             // TODO: Only fits 14 right now. Figure out how to fit all 16. Figure out how to find more than 16.
             if (n > 14) n = 14;
             for (--n; n >= 0; --n)
             {
      
      resp += "
    • <a href='agent/" + (string)llDetectedKey(n) + "'>" + llDetectedName(n) + "</a>
    • ";
             }
      
      resp += "
    " + footer;
           llSetContentType(current_request, CONTENT_TYPE_HTML);
           llHTTPResponse(current_request,200,resp);
       }
       
       no_sensor()
       {
    
    string resp = header + "

    Scan Results:

      "; resp += "
    • No one near by.
    • "; resp += "
    • Owner: <a href='agent/" + (string)llGetOwner() + "'>" + llKey2Name(llGetOwner()) + "</a>
    • "; resp += "
    " + footer;
           llSetContentType(current_request, CONTENT_TYPE_HTML);
           llHTTPResponse(current_request,200,resp);
       }
    

    }

    </lsl>