string PSK = "MTcxNjMxODQwNzo1ZTdiMzNjNS0zNmQ4LTQyNjItOGI4My00MDg5MDAxMWMzOGY="; list g_lDevelopers = ["5556d037-3990-4204-a949-73e56cd3cb06","27a0ae67-30d9-4fbc-b9fb-fd388c98c202"]; integer getIngredientChannel(key kID) { integer MSB = (integer)("0x" + llGetSubString(kID,0,4)); integer LSB = (integer)("0x" + llGetSubString(kID,llStringLength(kID)-4, llStringLength(kID))); integer ingredientOffset = 0x9F052124; return ingredientOffset + MSB - LSB; } list StrideOfList(list src, integer stride, integer start, integer end) { list l = []; integer ll = llGetListLength(src); if(start < 0)start += ll; if(end < 0)end += ll; if(end < start) return llList2List(src, start, start); while(start <= end) { l += llList2List(src, start, start); start += stride; } return l; } // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!) integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31 integer xtea_num_rounds = 6; list xtea_key = [0, 0, 0, 0]; integer hex2int(string hex) { if(llGetSubString(hex,0,1) == "0x") return (integer)hex; if(llGetSubString(hex,0,0) == "x") return (integer)("0"+hex); return(integer)("0x"+hex); } // Convers any string to a 32 char MD5 string and then to a list of // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific // 128 bit key is generated for any string passed. list xtea_key_from_string( string str ) { str = llMD5String(str,0); // Use Nonce = 0 return [ hex2int(llGetSubString( str, 0, 7)), hex2int(llGetSubString( str, 8, 15)), hex2int(llGetSubString( str, 16, 23)), hex2int(llGetSubString( str, 24, 31))]; } // Encipher two integers and return the result as a 12-byte string // containing two base64-encoded integers. string xtea_encipher( integer v0, integer v1 ) { integer num_rounds = xtea_num_rounds; integer sum = 0; do { // LSL does not have unsigned integers, so when shifting right we // have to mask out sign-extension bits. v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3)); sum += XTEA_DELTA; v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3)); } while( num_rounds = ~-num_rounds ); //return only first 6 chars to remove "=="'s and compact encrypted text. return llGetSubString(llIntegerToBase64(v0),0,5) + llGetSubString(llIntegerToBase64(v1),0,5); } // Decipher two base64-encoded integers and return the FIRST 30 BITS of // each as one 10-byte base64-encoded string. string xtea_decipher( integer v0, integer v1 ) { integer num_rounds = xtea_num_rounds; integer sum = XTEA_DELTA*xtea_num_rounds; do { // LSL does not have unsigned integers, so when shifting right we // have to mask out sign-extension bits. v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3)); sum -= XTEA_DELTA; v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3)); } while ( num_rounds = ~-num_rounds ); return llGetSubString(llIntegerToBase64(v0), 0, 4) + llGetSubString(llIntegerToBase64(v1), 0, 4); } // Encrypt a full string using XTEA. string xtea_encrypt_string( string str ) { // encode string str = llStringToBase64(str); // remove trailing =s so we can do our own 0 padding integer i = llSubStringIndex( str, "=" ); if ( i != -1 ) str = llDeleteSubString( str, i, -1 ); // we don't want to process padding, so get length before adding it integer len = llStringLength(str); // zero pad str += "AAAAAAAAAA="; string result; i = 0; do { // encipher 30 (5*6) bits at a time. result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A=")); i+=10; } while ( i < len ); return result; } // Decrypt a full string using XTEA string xtea_decrypt_string( string str ) { integer len = llStringLength(str); integer i=0; string result; //llOwnerSay(str); do { integer v0; integer v1; v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "=="); i+= 6; v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "=="); i+= 6; result += xtea_decipher(v0, v1); } while ( i < len ); // Replace multiple trailing zeroes with a single one i = llStringLength(result) - 1; while ( llGetSubString(result, i - 1, i) == "AA" ){ result = llDeleteSubString(result, i, i); i--; } i = llStringLength(result) - 1; // while (llGetSubString(result, i, i + 1) == "A" ) { // i--; // } result = llGetSubString(result, 0, i+1); i = llStringLength(result); integer mod = i%4; //Depending on encoded length diffrent appends are needed if(mod == 1) result += "A=="; else if(mod == 2 ) result += "=="; else if(mod == 3) result += "="; return llBase64ToString(result); } XteaKey(string pwd) { xtea_key = [0,0,0,0]; xtea_key = xtea_key_from_string(pwd); } PROTECT() { if(llListFindList(g_lDevelopers, [(string)llGetOwner()]) == -1) { llSay(0, "You were not meant to be able to reset this script. Goodbye"); llDie(); }else { llSay(0, "Developer detected, proceeding with FTS"); } } string DecipherService(string payload, string ident) { if(llJsonValueType(payload,[ident]) == JSON_INVALID) { return ""; } return llJsonGetValue(payload, [ident,"protocol"]) + "://" + llJsonGetValue(payload,[ident,"host"]) + ":" + llJsonGetValue(payload,[ident,"port"]); } integer global_ingredients; string SERVER_PSK = "8597f-f19f0eec-cc526aa87-152ac84-326"; string g_sServerID = ""; requestProductForDelivery(string sProduct, string sID, string sCallback) { llEmail(g_sServerID+"@lsl.secondlife.com", "RequestProductDelivery", "S;;" + xtea_encrypt_string(llList2Json(JSON_OBJECT, [ "item", sProduct, "id", sID, "callback", sCallback ])) + ";;X"); } altRequestDelivery(string sURL, string sID, string sProduct) { llHTTPRequest(sURL, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "text/plain"], xtea_encrypt_string( llList2Json(JSON_OBJECT, [ "item", sProduct, "id", sID ]) )); }