xs_home.lsl 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // :CATEGORY:XS Pet
  2. // :NAME:XS Pet Xundra Snowpaw Original Quail
  3. // :AUTHOR:Xundra Snowpaw
  4. // :CREATED:2013-09-06
  5. // :EDITED:2013-09-18 15:39:11
  6. // :ID:989
  7. // :NUM:1483
  8. // :REV:1
  9. // :WORLD:Second Life, Opensim
  10. // :DESCRIPTION:
  11. // Original Pet Quail
  12. // :CODE:
  13. string SECRET_PASSWORD = "top secret";
  14. integer ANIMAL_CHANNEL = -999192;
  15. integer HOME_CHANNEL = -999194;
  16. // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!)
  17. integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
  18. integer xtea_num_rounds = 6;
  19. list xtea_key = [0, 0, 0, 0];
  20. integer hex2int(string hex) {
  21. if(llGetSubString(hex,0,1) == "0x")
  22. return (integer)hex;
  23. if(llGetSubString(hex,0,0) == "x")
  24. return (integer)("0"+hex);
  25. return(integer)("0x"+hex);
  26. }
  27. // Convers any string to a 32 char MD5 string and then to a list of
  28. // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
  29. // 128 bit key is generated for any string passed.
  30. list xtea_key_from_string( string str )
  31. {
  32. str = llMD5String(str,0); // Use Nonce = 0
  33. return [ hex2int(llGetSubString( str, 0, 7)),
  34. hex2int(llGetSubString( str, 8, 15)),
  35. hex2int(llGetSubString( str, 16, 23)),
  36. hex2int(llGetSubString( str, 24, 31))];
  37. }
  38. // Encipher two integers and return the result as a 12-byte string
  39. // containing two base64-encoded integers.
  40. string xtea_encipher( integer v0, integer v1 )
  41. {
  42. integer num_rounds = xtea_num_rounds;
  43. integer sum = 0;
  44. do {
  45. // LSL does not have unsigned integers, so when shifting right we
  46. // have to mask out sign-extension bits.
  47. v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  48. sum += XTEA_DELTA;
  49. v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
  50. } while( num_rounds = ~-num_rounds );
  51. //return only first 6 chars to remove "=="'s and compact encrypted text.
  52. return llGetSubString(llIntegerToBase64(v0),0,5) +
  53. llGetSubString(llIntegerToBase64(v1),0,5);
  54. }
  55. // Decipher two base64-encoded integers and return the FIRST 30 BITS of
  56. // each as one 10-byte base64-encoded string.
  57. string xtea_decipher( integer v0, integer v1 )
  58. {
  59. integer num_rounds = xtea_num_rounds;
  60. integer sum = XTEA_DELTA*xtea_num_rounds;
  61. do {
  62. // LSL does not have unsigned integers, so when shifting right we
  63. // have to mask out sign-extension bits.
  64. v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
  65. sum -= XTEA_DELTA;
  66. v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  67. } while ( num_rounds = ~-num_rounds );
  68. return llGetSubString(llIntegerToBase64(v0), 0, 4) +
  69. llGetSubString(llIntegerToBase64(v1), 0, 4);
  70. }
  71. // Encrypt a full string using XTEA.
  72. string xtea_encrypt_string( string str )
  73. {
  74. // encode string
  75. str = llStringToBase64(str);
  76. // remove trailing =s so we can do our own 0 padding
  77. integer i = llSubStringIndex( str, "=" );
  78. if ( i != -1 )
  79. str = llDeleteSubString( str, i, -1 );
  80. // we don't want to process padding, so get length before adding it
  81. integer len = llStringLength(str);
  82. // zero pad
  83. str += "AAAAAAAAAA=";
  84. string result;
  85. i = 0;
  86. do {
  87. // encipher 30 (5*6) bits at a time.
  88. result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A="));
  89. i+=10;
  90. } while ( i < len );
  91. return result;
  92. }
  93. // Decrypt a full string using XTEA
  94. string xtea_decrypt_string( string str ) {
  95. integer len = llStringLength(str);
  96. integer i=0;
  97. string result;
  98. //llOwnerSay(str);
  99. do {
  100. integer v0;
  101. integer v1;
  102. v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  103. i+= 6;
  104. v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  105. i+= 6;
  106. result += xtea_decipher(v0, v1);
  107. } while ( i < len );
  108. // Replace multiple trailing zeroes with a single one
  109. i = llStringLength(result) - 1;
  110. while ( llGetSubString(result, i - 1, i) == "AA" ){
  111. result = llDeleteSubString(result, i, i);
  112. i--;
  113. }
  114. i = llStringLength(result) - 1;
  115. // while (llGetSubString(result, i, i + 1) == "A" ) {
  116. // i--;
  117. // }
  118. result = llGetSubString(result, 0, i+1);
  119. i = llStringLength(result);
  120. integer mod = i%4; //Depending on encoded length diffrent appends are needed
  121. if(mod == 1) result += "A==";
  122. else if(mod == 2 ) result += "==";
  123. else if(mod == 3) result += "=";
  124. return llBase64ToString(result);
  125. }
  126. string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  127. default
  128. {
  129. state_entry()
  130. {
  131. xtea_key = xtea_key_from_string(SECRET_PASSWORD);
  132. llListen(-237918, "", "", "XSPET_PING_HOME");
  133. }
  134. touch_start(integer total_number)
  135. {
  136. if (llDetectedKey(0) == llGetOwner()) {
  137. vector size = llGetScale();
  138. vector pos = llGetPos();
  139. pos.z = pos.z - size.z / 2;
  140. // llOwnerSay("XSPET^HOME_LOCATION^" + (string)llGetPos() + "^" + llGetObjectDesc());
  141. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^HOME_LOCATION^" + (string)pos + "^" + llGetObjectDesc()));
  142. }
  143. }
  144. listen(integer channel, string name, key id, string msg)
  145. {
  146. vector size = llGetScale();
  147. vector pos = llGetPos();
  148. pos.z = pos.z - size.z / 2;
  149. // llOwnerSay("XSPET^HOME_LOCATION^" + (string)llGetPos() + "^" + llGetObjectDesc());
  150. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^HOME_LOCATION^" + (string)pos + "^" + llGetObjectDesc())); }
  151. }