Store1 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // :CATEGORY:Prim Animator
  2. // :NAME:Archipelis scripts for prim animator
  3. // :AUTHOR:Ferd Frederix
  4. // :CREATED:2013-09-06
  5. // :EDITED:2013-09-18 15:38:48
  6. // :ID:52
  7. // :NUM:79
  8. // :REV:1
  9. // :WORLD:Second Life
  10. // :DESCRIPTION:
  11. // Prim storage Script Should be names Store 1
  12. // :CODE:
  13. // prim store
  14. // constants
  15. integer debug =0 ;
  16. // return codes
  17. integer countchannel= 2001; // echo the number iof prims loaded to the animator
  18. // Commands
  19. integer Clear = 99; // erase local db
  20. integer Erase = 100; // erase Server DB command
  21. integer Add = 101; // add a coordinate
  22. integer Publish = 102; // save to db
  23. integer Name = 103; // send Name to db
  24. integer Password = 104; // send Password to db
  25. integer Play = 1; // backwards compat
  26. // vars
  27. integer full = FALSE; // this script RAM is full
  28. integer myNum = 0; // the number at the end of this script name 0, 1, 2....
  29. integer imax; // total records in store
  30. integer datum; // the load counter increments as we load anims from db
  31. string MyName;
  32. string MyPassword;
  33. // remote db reading
  34. key kHttpRequestID;
  35. // lists
  36. list names; // a list of distnct animation names stored here
  37. list db; // name, prin num, pos, rot, size
  38. integer STRIDE = 5; // 4 items in the above list
  39. integer recordcount = 0; // how many anims are stored
  40. vector vRootScale ; // the initial size when the prims were recorded
  41. vector vScaleChange = <1,1,1>; // The change percent if resized
  42. integer GetScale()
  43. {
  44. //Debug ("Size:" + (string) orig_size);
  45. vector newScale = llGetScale();
  46. vScaleChange.x = newScale.x / vRootScale.x;
  47. vScaleChange.y = newScale.y / vRootScale.y;
  48. vScaleChange.z = newScale.z / vRootScale.z;
  49. return (vScaleChange != <1,1,1>);
  50. }
  51. // Start saving records. The first record is the prim size.
  52. StartPublishing ()
  53. {
  54. imax = llGetListLength(db);
  55. datum = 0; // point to the first record, counts as we load records
  56. integer howmany = imax / STRIDE ;
  57. llOwnerSay((string) howmany + " movements recorded - now saving to server.");
  58. }
  59. EraseDB()
  60. {
  61. string url;
  62. //Debug( "Saving Size:" + (string) llGetScale());
  63. url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Erase";
  64. url += "&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
  65. Debug(url);
  66. kHttpRequestID = llHTTPRequest(url, [], "");
  67. }
  68. Put()
  69. {
  70. if (datum < imax)
  71. {
  72. string sAniName = llList2String (db, datum);
  73. float fprimNum = llList2Float (db, datum+1);
  74. vector vprimPos = llList2Vector (db, datum+2);
  75. rotation rprimRot = llList2Rot (db, datum+3) ;
  76. vector vprimSize = llList2Vector (db, datum+4);
  77. string url = "http://secondlife.mitsi.com/cgi/animate.plx?Type=Save&Name=" + llEscapeURL(MyName) + "&Password=" + llEscapeURL(MyPassword);
  78. url += "&aniName=" + (string) sAniName;
  79. url += "&PrimNum=" + (string) fprimNum;
  80. url += "&Pos=" + (string) vprimPos;
  81. url += "&Rot=" + (string) rprimRot;
  82. url += "&Size=" + (string) vprimSize;
  83. Debug(url);
  84. if ((datum/STRIDE) % 10 == 0 && datum)
  85. llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE) ,"");
  86. kHttpRequestID = llHTTPRequest(url, [], "");
  87. llSleep(1);
  88. datum += STRIDE;
  89. }
  90. else
  91. {
  92. llMessageLinked(LINK_THIS,countchannel,(string) (datum/STRIDE),"");
  93. llSleep(2.0);
  94. llMessageLinked(LINK_THIS,countchannel,"","");
  95. }
  96. }
  97. Debug(string msg)
  98. {
  99. if (debug)
  100. llOwnerSay(llGetScriptName() + ":" + msg);
  101. }
  102. default
  103. {
  104. state_entry()
  105. {
  106. list parts = llParseString2List( llGetScriptName(),[" "],[""]);
  107. myNum = llList2Integer(parts,1);
  108. vRootScale = llGetScale(); // set a default of this size, the real size when recorded comes from the server
  109. Add = Add + (10 * myNum);
  110. Debug("DB " + (string) myNum + " is empty");
  111. }
  112. link_message(integer sender_num, integer num, string msg, key id)
  113. {
  114. //Debug("cmd:" + (string) num + ":" + msg);
  115. // valid commands only.
  116. if (num != Clear && num != Erase && num != Play && num != Add && num != Publish && num != Name && num!= Password)
  117. return;
  118. Debug("cmd rcv :" + (string) num + ":" + msg);
  119. if (num == Clear)
  120. {
  121. db = []; // zero the animations
  122. names = []; // zero names db
  123. //Debug((string) myNum + " erased " );
  124. full = FALSE;
  125. recordcount = 0;
  126. return;
  127. }
  128. else if (num == Add)
  129. {
  130. if (full)
  131. {
  132. Debug((string) myNum + " pass Add on to " + (string) (num +10));
  133. llMessageLinked(LINK_THIS,num +10,msg,id);
  134. return;
  135. }
  136. //Debug("Add");
  137. list vecs = llParseString2List(msg,["|"],[""]);
  138. // Debug(llDumpList2String(vecs,"---"));
  139. string name= llList2String(vecs,0);
  140. if (llListFindList(names,[name]) == -1)
  141. names += name;
  142. float fNum = (float) (llList2String(vecs,1));
  143. vector vPos = (vector) (llList2String(vecs,2));
  144. rotation rRot = (rotation) (llList2String(vecs,3));
  145. vector vprimSize = (vector) (llList2String(vecs,4));
  146. db += name;
  147. db += fNum;
  148. db += vPos;
  149. db += rRot;
  150. db += vprimSize;
  151. recordcount ++;
  152. Debug("Mem:" + (string) llGetFreeMemory() );
  153. if (llGetFreeMemory() < 2000)
  154. full++;
  155. }
  156. else if (num == Name)
  157. {
  158. MyName = msg;
  159. }
  160. else if (num == Password)
  161. {
  162. MyPassword = msg;
  163. }
  164. else if (num == Play)
  165. {
  166. if (llListFindList(names,[msg]) == -1)
  167. return;
  168. integer currpos;
  169. integer end = recordcount * STRIDE;
  170. // play back all we find
  171. for (currpos = 0; currpos < end; currpos+= STRIDE)
  172. {
  173. if ( msg == llList2String(db,currpos) )
  174. {
  175. float fPrim = (float) llList2String(db,currpos+1);
  176. vector vPos = (vector) llList2String(db,currpos+2);
  177. rotation rRot = (rotation) llList2String (db,currpos+3);
  178. vector vprimSize = (vector) llList2String(db,currpos+4);
  179. if (fPrim > 1 ) // skip root prim
  180. {
  181. // set the local pos and locat rot to the prims orientation and position
  182. if (llGetAttached())
  183. rRot = rRot/llGetLocalRot();
  184. else
  185. rRot = rRot/llGetRootRotation();
  186. if (GetScale())
  187. {
  188. vPos.x *= vScaleChange.x;
  189. vprimSize.x *= vScaleChange.x;
  190. vPos.y *= vScaleChange.y;
  191. vprimSize.y *= vScaleChange.y;
  192. vPos.z *= vScaleChange.z;
  193. vprimSize.z *= vScaleChange.z;
  194. }
  195. // Debug("p=" + (string) fPrim
  196. // + " l=" + (string) vPos
  197. // + " r=" + (string) rRot
  198. // + " s=" + (string) vprimSize);
  199. llSetLinkPrimitiveParamsFast((integer) fPrim,[PRIM_POSITION,vPos,PRIM_ROTATION,rRot,PRIM_SIZE,vprimSize]);
  200. }
  201. else if (fPrim == 0)
  202. {
  203. vRootScale = (vector) msg;
  204. Debug("Set scale to " + (string) vRootScale);
  205. }
  206. else if (fPrim < 0)
  207. {
  208. Debug("Sleep");
  209. llSleep( fPrim * -1);
  210. }
  211. }
  212. }
  213. }
  214. else if (num == Publish)
  215. {
  216. if (myNum)
  217. llSleep(5); // time to delete the database and save the root prim
  218. StartPublishing();
  219. }
  220. else if (num == Erase)
  221. {
  222. EraseDB();
  223. }
  224. else
  225. {
  226. Debug("Bad command");
  227. }
  228. }
  229. // use for publishing in parallel
  230. http_response(key queryid, integer status, list metadata, string data)
  231. {
  232. if (queryid == kHttpRequestID )
  233. {
  234. if (status == 200) // HTTP success status
  235. {
  236. Debug(data);
  237. if (data == "ok")
  238. {
  239. Put();
  240. return;
  241. }
  242. else if (data == "deleted")
  243. {
  244. llOwnerSay("Remote database is empty");
  245. return;
  246. }
  247. }
  248. else
  249. {
  250. llOwnerSay("Server Error loading animations");
  251. }
  252. }
  253. }
  254. }