// ==SiteScript==
// @siteName Trilulilu
// @siteUrl http://trilulilu.ro/
// @author DarkKnight
// @authorUrl http://darkknightlabs.com/
// @scriptUrl http://darkknightlabs.com/site-script/
// @description revise by mayan, 2012/05/13
// @date 2008/09/13
// @version 0.2.0.2
// ==/SiteScript==
function CravingSiteScript() {
this._initialize();
}
CravingSiteScript.prototype = {
_xhr: null,
_initialize: function() {},
_getXmlHttpRequest: function() {
if ( this._xhr != null ) {
return this._xhr;
}
var xhr = null;
var these = [
function() { return new XMLHttpRequest(); }
, function() { return new ActiveXObject( "Msxml2.XMLHTTP" ); }
, function() { return new ActiveXObject( "Microsoft.XMLHTTP" ); }
, function() { return new ActiveXObject( "Msxml2.XMLHTTP.4.0" ); }
];
for ( var i = 0, length = these.length; i < length; i++ ) {
var func = these[ i ];
try {
xhr = func();
break;
}
catch( e ) {}
}
this._xhr = xhr;
return this._xhr;
},
_load: function( url, data, method ) {
var req = this._getXmlHttpRequest();
var mtd = ( method == null ) ? "GET" : "POST";
req.open( mtd, url, false );
if ( mtd == "POST" ) {
req.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
}
req.send( data );
return req.responseText;
},
getResponseText: function( url, data, method ) {
return this._load( url, data, method );
},
getResponseJSON: function( url, data, method ) {
var text = this._load( url, data, method );
return eval( "("+text+")" );
},
/// Math
random: function( limit ) {
return Math.floor( Math.random() * limit );
},
/// String
decodeHtml: function( str ) {
return str.replace( /&(quot|#34);/ig, "\"" )
.replace( /&(amp|#38);/ig, "&" )
.replace( /&(apos|#39);/ig, "'" )
.replace( /&(lt|#60);/ig, "<" )
.replace( /&(gt|#62);/ig, ">" )
.replace( /&(nbsp|#160);/ig, " " )
.replace( /&(frasl|#8260);/ig, "/" );
}
}
function isSiteUrl( url ) {
if ( url.match( /http:\/\/(www\.)?trilulilu\.ro\/[^\/]+\/[^\/?]+/ ) ) return true;
return false;
}
function getVideoDetail( url ) {
var TYPE_AUDIO = "audio";
var TYPE_VIDEO = "video";
url = url.replace( /http:\/\/trilulilu\.ro\//, "http://www.trilulilu.ro/" );
if ( !url.match( /http:\/\/www\.trilulilu\.ro\/([^\/]+)\/([^\/?]+)/ ) ) return null;
var pth1 = RegExp.$1;
var pth2 = RegExp.$2;
var craving = new CravingSiteScript();
try {
var text = craving.getResponseText( url );
} catch( e ) {
text = "";
}
if ( !text ) return null;
if ( text.match( /]*?rel\s*=\s*("|')video_src\2[^>]*)>/ )
&& RegExp.$1.match( /\s+href\s*=\s*("|')(.*?)\1/ )
&& RegExp.$2.match( /http:\/\/embed\.trilulilu\.ro\/([^\/]+)\/([^\/]+)\/([0-9a-f]+)\.swf/ ) ) {
var type = ( ( RegExp.$1.toLowerCase() == TYPE_AUDIO )? TYPE_AUDIO: TYPE_VIDEO );
var userid = RegExp.$2;
var hash = RegExp.$3;
}
if ( text.match( /swfobject\.embedSWF\(\s*("|')(.*?)\1\s*,(\s*("|').*?\4\s*,){5}\s*\{([^}]*?)\}/ ) ) {
var swf = RegExp.$2;
var prm = RegExp.$5;
if ( !type ) {
var playername = swf.substr( swf.lastIndexOf( "/" ) + 1 );
if ( playername.indexOf( "audio" ) >= 0 ) var type = TYPE_AUDIO;
else type = TYPE_VIDEO;
}
if ( !userid && prm.match( /("|')userid\1\s*:\s*("|')(.*?)\2/ ) ) userid = RegExp.$3;
if ( !hash && prm.match( /("|')hash\1\s*:\s*("|')(.*?)\2/ ) ) hash = RegExp.$3;
if ( prm.match( /("|')server\1\s*:\s*("|')(.*?)\2/ ) ) var server = RegExp.$3;
if ( prm.match( /("|')key\1\s*:\s*("|')(.*?)\2/ ) ) var key = RegExp.$3;
}
if ( !userid || !hash ) return null;
if ( text.match( /]*?property\s*=\s*("|')og:title\2[^>]*)>/ )
&& RegExp.$1.match( /\s+content\s*=\s*("|')(.*?)\1/ ) )
var title = RegExp.$2;
if ( !title && text.match( /
([\S\s]+?)<\/h1>/m ) )
title = RegExp.$1.replace( /\r|\n/g, "" ).replace( /^\s+/, "" ).replace( /\s+$/, "" );
if ( title )
title = craving.decodeHtml( title.replace( /(\d+);/g, function(a,b){
return String.fromCharCode( parseInt( b, 10 ) ); } ) );
if ( !type ) type = TYPE_VIDEO;
switch( type ) {
case TYPE_VIDEO:
if ( !server || !title ) {
var relurl = "http://www.trilulilu.ro/" + userid + "/" + hash + "/related2";
try {
text = craving.getResponseText( relurl );
} catch( e ) {
text = "";
}
if ( text && text.match( /([\s\S]*?)<\/main_movie>/m ) ) {
var main_movie = RegExp.$1;
if ( !server && main_movie.match( /(.+?)<\/server>/ ) ) server = RegExp.$1;
if ( !title && main_movie.match( /(.+?)<\/titlu>/ ) ) title = RegExp.$1;
}
}
if ( !server ) return null;
if ( !title ) title = "trilulilu_" + pth1 + "_" + pth2;
title = title.replace(/[\\\/:*?"<>|]/g, "_");
var fmturl = "http://fs" + server + ".trilulilu.ro/" + hash + "/video-formats2";
try {
text = craving.getResponseText( fmturl );
} catch( e ) {
text = "";
}
if ( text.match( /mp4-720p<\/format>/ ) ) var format = "mp4-720p";
else if ( text.match( /mp4-360p<\/format>/ ) ) format = "mp4-360p";
else format = "mp4-360p";
var realUrl = "http://fs" + server + ".trilulilu.ro/stream.php?type=video&source=site"
+ "&hash=" + hash
+ "&username=" + userid
+ "&key=" + ( key? key: "ministhebest" )
+ "&format=" + format
+ "&start=";
return { videoTitle0: title, videoUrl0: realUrl };
break;
case TYPE_AUDIO:
var objBny = new clsGetBinary();
if ( !objBny.isOK ) return null;
getSendData( objBny, userid, hash );
var objHttp = craving._getXmlHttpRequest();
var amfurl = "http://www.trilulilu.ro/amf";
try {
objHttp.open( "POST", amfurl, false );
objHttp.setRequestHeader( "Content-Type", "application/x-amf" );
objHttp.Send( objBny.senddata );
var objByte = new clsGetByteCode( objHttp.responseBody );
} catch( e ) {
objByte = {};
}
if ( !objByte.isOK ) return null;
var sig = objByte.pickStrData( "sig" );
if ( !sig ) return null;
var exp = objByte.pickStrData( "exp" );
if ( !exp ) return null;
if ( !server ) server = objByte.pickStrData( "server" );
if ( !server ) return null;
if ( !title ) title = objByte.pickStrData( "titlu" );
if ( !title ) title = title + pth1 + "_" + pth2;
title = title.replace(/[\\\/:*?"<>|]/g, "_");
var realUrl = "http://fs" + server + ".trilulilu.ro/stream.php"
+ "?type=audio&source=site"
+ "&hash=" + hash
+ "&username=" + userid
+ "&key=" + key
+ "&sig=" + sig
+ "&exp=" + exp;
return { videoTitle0: title, videoUrl0: realUrl };
break;
default:
return null;
}
return null;
}
function getSendData( objBny, strUserId, strHash ){
var arrHeader = [
0x00, 0x03, 0x00, 0x00, 0x00, 0x01
];
var arrBodyHe = [
0x00, 0x0f, //target
0x66, 0x69, 0x6c, 0x65, 0x2e, 0x61, 0x75, 0x64,
0x69, 0x6f, 0x5f, 0x69, 0x6e, 0x66, 0x6f,
0x00, 0x02, //response
0x2f, 0x31
];
//body length
var arrBodyCo1 = [
0x0a, 0x00, 0x00, 0x00, 0x03
];
//+userid
//+hash
var arrBodyCo2 = [
0x02, 0x00, 0x04,
0x70, 0x6c, 0x61, 0x79 //play
];
var arrUserId = makeStringArr( strUserId );
var arrHash = makeStringArr( strHash );
var contentLength = 12 + arrUserId.length + arrHash.length;
var objStream = new ActiveXObject( "ADODB.Stream" );
objStream.type = 1;
objStream.Open();
objStream.Position = 0;
for ( var i = 0; i < arrHeader.length; i++ )
objStream.Write( objBny.fromByteCode( arrHeader[i] ) );
for ( var i = 0; i < arrBodyHe.length; i++ )
objStream.Write( objBny.fromByteCode( arrBodyHe[i] ) );
var arrTmp = LenToByteCode( contentLength, 4 );
for ( var i = 0; i < arrTmp.length; i++ )
objStream.Write( objBny.fromByteCode( arrTmp[i] ) );
for ( var i = 0; i < arrBodyCo1.length; i++ )
objStream.Write( objBny.fromByteCode( arrBodyCo1[i] ) );
for ( var i = 0; i < arrUserId.length; i++ )
objStream.Write( objBny.fromByteCode( arrUserId[i] ) );
for ( var i = 0; i < arrHash.length; i++ )
objStream.Write( objBny.fromByteCode( arrHash[i] ) );
for ( var i = 0; i < arrBodyCo2.length; i++ )
objStream.Write( objBny.fromByteCode( arrBodyCo2[i] ) );
objStream.Position = 0;
objBny.senddata = objStream.Read();
objStream.Close();
}
function LenToByteCode( intLen, intByteLen ){
var arr = new Array();
var tmp = intLen;
for ( var i = 0; i < intByteLen; i++ ){
arr.push( tmp & 255 );
tmp = tmp >> 8 ;
}
return arr.reverse();
}
function makeStringArr( str ){
var arr = [];
var len = str.length;
arr.push( 0x02 );
arr = arr.concat( LenToByteCode( len, 2 ) );
for ( var i = 0; i < len; i++ ){
arr.push( str.charCodeAt( i ) );
}
return arr;
}
function clsGetBinary(){
this.isOK = false;
this._objStream = null;
this._binaryNone;
this._initialize = function (){
try {
this._objStream = new ActiveXObject( "ADODB.Stream" );
this.isOK = true;
} catch(e) {
this.isOk = false;
return false;
}
this._objStream.Open();
this._objStream.type = 1;
this._binaryNone = this._objStream.Read( 0 );
this._objStream.Close();
return true;
}
this._initialize();
this.fromByteCode = function ( intByteCode ){
if ( !this.isOK ) return this._binaryNone;
if ( intByteCode < 0 || 255 < intByteCode ) return this._binaryNone;
this._objStream.Open();
this._objStream.type = 2;
this._objStream.Charset = "Unicode";
this._objStream.WriteText( String.fromCharCode( intByteCode ) );
this._objStream.Position = 0;
this._objStream.type = 1;
this._objStream.Position = 2;//big endian
var binary = this._objStream.Read( 1 );
this._objStream.Close();
return binary;
}
}
function clsGetByteCode( binarydata ){
this._binary = binarydata;
this.isOK = false;
this.size = 0;
this._objSC = null;
this._initialize= function (){
try {
this._objSC = new ActiveXObject( "ScriptControl" );
this.isOK = true;
} catch(e) {
this.isOK = falae;
this.size = 0;
return false;
}
this._objSC.Language = "VBScript";
this._objSC.AddCode( "Function VB_getSize( bin ) : VB_getSize = LenB( bin ) : End Function" );
this._objSC.AddCode( "Function VB_getByte( bin, pos ) : VB_getByte = AscB( MidB( bin, pos, 1 ) ) : End Function" );
this.size = this._objSC.Run( "VB_getSize", this._binary );
return true;
};
this._initialize();
this.byteCodeAt = function ( index ){
//arg:index0-, ret: Number
if ( !this.isOK ) return 0;
if ( index < 0 || this.size <= index ) return 0;
return this._objSC.Run( "VB_getByte", this._binary, index + 1 );
};
this.toByteArray = function (){
var arr = [];
for ( var i = 0; i < this.size; i++ ) arr.push( this.byteCodeAt(i) );
return arr;
};
this.pickStrData = function ( strFn ) {
var arrFn = [];
arrFn[ 0 ] = 0;
arrFn[ 1 ] = strFn.length;
for ( var i = 0; i < strFn.length; i++ )
arrFn[ i + 2 ] = strFn.charCodeAt( i );
var flag = false;
var ptr = 0;
jump1:
for ( var i = 0; i < this.size - arrFn.length; i++ ) {
flag = false;
for ( var j = 0; j < arrFn.length; j++ ) {
ptr = i + j;
if ( this.byteCodeAt( ptr ) != arrFn[ j ] ) continue jump1;
}
flag = true;
break;
}
if ( !flag ) return "";
var type = this.byteCodeAt( ++ptr );
switch ( type ) {
case 2:
var len = ( this.byteCodeAt( ++ptr ) << 8 ) + this.byteCodeAt( ++ptr );
var str = "";
ptr = ptr + 1;
for ( var i = 0; i < len; i++ )
str = str + String.fromCharCode( this.byteCodeAt( ptr + i ) );
return str;
break;
case 0:
var arr = [];
ptr++;
for ( var i = 0; i < 8; i++ ) arr[ i ] = this.byteCodeAt( ptr + i );
return dblbyte2Int( arr );
break;
default:
return "";
}
return "";
};
function dblbyte2Int( arrByte ){
//integer only
var arr = [];
for ( var i = 0; i < 8; i++ ){
if ( arrByte[ i ] == undefined ) arr[ i ] = 0;
else arr[ i ] = arrByte[ i ] & 0xFF;
}
var sig = 1 - ( ( arr[ 0 ] >> 7 ) << 1 );
var exp = ( ( ( arr[ 0 ] << 4 ) & 0x7FF ) | ( arr[ 1 ] >> 4 ) ) - 1023;
var man = "1" + zeropad( ( arr[ 1 ] & 0xF ).toString( 2 ), 4 );
for ( var i = 2; i < 8; i++ ){
man = man + zeropad( arr[ i ].toString( 2 ), 8 );
}
if ( 0 <= exp && exp < 52 ){
man = man.substring( 0, exp + 1 ) + "." + man.substr( exp + 1 );
}else if ( exp > 52 ){
man = man + zeropad( "", exp - 52 );
}else if ( exp < 0 ){
man = "0." + zeropad( "", Math.abs( exp ) - 1 );
}
return sig * parseInt( man, 2 );
}
function zeropad( strNum, keta ){
for ( var i = strNum.length; i < keta; i++ ) strNum = "0" + strNum;
return strNum;
}
}