InnerScene.cs 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using Axiom.Math;
  31. using libsecondlife;
  32. using libsecondlife.Packets;
  33. using log4net;
  34. using OpenSim.Framework;
  35. using OpenSim.Region.Environment.Types;
  36. using OpenSim.Region.Physics.Manager;
  37. namespace OpenSim.Region.Environment.Scenes
  38. {
  39. public delegate void PhysicsCrash();
  40. public class InnerScene
  41. {
  42. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  43. #region Events
  44. public event PhysicsCrash UnRecoverableError;
  45. private PhysicsCrash handlerPhysicsCrash = null;
  46. #endregion
  47. #region Fields
  48. public Dictionary<LLUUID, ScenePresence> ScenePresences;
  49. // SceneObjects is not currently populated or used.
  50. //public Dictionary<LLUUID, SceneObjectGroup> SceneObjects;
  51. public Dictionary<LLUUID, EntityBase> Entities;
  52. public Dictionary<LLUUID, ScenePresence> RestorePresences;
  53. public BasicQuadTreeNode QuadTree;
  54. protected RegionInfo m_regInfo;
  55. protected Scene m_parentScene;
  56. protected PermissionManager PermissionsMngr;
  57. protected List<EntityBase> m_updateList = new List<EntityBase>();
  58. protected int m_numRootAgents = 0;
  59. protected int m_numPrim = 0;
  60. protected int m_numChildAgents = 0;
  61. protected int m_physicalPrim = 0;
  62. protected int m_activeScripts = 0;
  63. protected int m_scriptLPS = 0;
  64. internal object m_syncRoot = new object();
  65. public PhysicsScene _PhyScene;
  66. #endregion
  67. public InnerScene(Scene parent, RegionInfo regInfo, PermissionManager permissionsMngr)
  68. {
  69. m_parentScene = parent;
  70. m_regInfo = regInfo;
  71. PermissionsMngr = permissionsMngr;
  72. QuadTree = new BasicQuadTreeNode(null, "/0/", 0, 0, (short)Constants.RegionSize, (short)Constants.RegionSize);
  73. QuadTree.Subdivide();
  74. QuadTree.Subdivide();
  75. }
  76. public PhysicsScene PhysicsScene
  77. {
  78. get { return _PhyScene; }
  79. set
  80. {
  81. // If we're not doing the initial set
  82. // Then we've got to remove the previous
  83. // event handler
  84. try
  85. {
  86. _PhyScene.OnPhysicsCrash -= physicsBasedCrash;
  87. }
  88. catch (NullReferenceException)
  89. {
  90. // This occurs when storing to _PhyScene the first time.
  91. // Is there a better way to check the event handler before
  92. // getting here
  93. // This can be safely ignored. We're setting the first inital
  94. // there are no event handler's registered.
  95. }
  96. _PhyScene = value;
  97. _PhyScene.OnPhysicsCrash += physicsBasedCrash;
  98. }
  99. }
  100. public void Close()
  101. {
  102. ScenePresences.Clear();
  103. //SceneObjects.Clear();
  104. Entities.Clear();
  105. }
  106. #region Update Methods
  107. internal void UpdatePreparePhysics()
  108. {
  109. // If we are using a threaded physics engine
  110. // grab the latest scene from the engine before
  111. // trying to process it.
  112. // PhysX does this (runs in the background).
  113. if (_PhyScene.IsThreaded)
  114. {
  115. _PhyScene.GetResults();
  116. }
  117. }
  118. internal void UpdateEntities()
  119. {
  120. List<EntityBase> updateEntities = GetEntities();
  121. foreach (EntityBase entity in updateEntities)
  122. {
  123. entity.Update();
  124. }
  125. }
  126. internal void UpdatePresences()
  127. {
  128. List<ScenePresence> updateScenePresences = GetScenePresences();
  129. foreach (ScenePresence pres in updateScenePresences)
  130. {
  131. pres.Update();
  132. }
  133. }
  134. internal float UpdatePhysics(double elapsed)
  135. {
  136. lock (m_syncRoot)
  137. {
  138. return _PhyScene.Simulate((float)elapsed);
  139. }
  140. }
  141. internal void UpdateEntityMovement()
  142. {
  143. List<EntityBase> moveEntities = GetEntities();
  144. foreach (EntityBase entity in moveEntities)
  145. {
  146. entity.UpdateMovement();
  147. }
  148. }
  149. #endregion
  150. #region Entity Methods
  151. public void AddEntityFromStorage(SceneObjectGroup sceneObject)
  152. {
  153. sceneObject.RegionHandle = m_regInfo.RegionHandle;
  154. sceneObject.SetScene(m_parentScene);
  155. foreach (SceneObjectPart part in sceneObject.Children.Values)
  156. {
  157. part.LocalId = m_parentScene.PrimIDAllocate();
  158. }
  159. sceneObject.UpdateParentIDs();
  160. AddEntity(sceneObject);
  161. }
  162. public void AddEntity(SceneObjectGroup sceneObject)
  163. {
  164. if (!Entities.ContainsKey(sceneObject.UUID))
  165. {
  166. // QuadTree.AddObject(sceneObject);
  167. lock (Entities)
  168. {
  169. Entities.Add(sceneObject.UUID, sceneObject);
  170. }
  171. m_numPrim++;
  172. }
  173. }
  174. /// <summary>
  175. /// Add an entity to the list of prims to process on the next update
  176. /// </summary>
  177. /// <param name="obj">
  178. /// A <see cref="EntityBase"/>
  179. /// </param>
  180. internal void AddToUpdateList(EntityBase obj)
  181. {
  182. lock (m_updateList)
  183. {
  184. if (!m_updateList.Contains(obj))
  185. {
  186. m_updateList.Add(obj);
  187. }
  188. }
  189. }
  190. /// <summary>
  191. /// Process all pending updates
  192. /// </summary>
  193. internal void ProcessUpdates()
  194. {
  195. lock (m_updateList)
  196. {
  197. for (int i = 0; i < m_updateList.Count; i++)
  198. {
  199. EntityBase entity = m_updateList[i];
  200. // Don't abort the whole update if one entity happens to give us an exception.
  201. try
  202. {
  203. // A null name signals that this group was deleted before the scheduled update
  204. // FIXME: This is merely a temporary measure to reduce the incidence of failure, when
  205. // an object has been deleted from a scene before update was processed.
  206. // A more fundamental overhaul of the update mechanism is required to eliminate all
  207. // the race conditions.
  208. if (entity.Name != null)
  209. {
  210. m_updateList[i].Update();
  211. }
  212. }
  213. catch (Exception e)
  214. {
  215. m_log.ErrorFormat("[INNER SCENE]: Failed to update {0}, - {1}", entity.Name, e);//entity.m_uuid
  216. }
  217. }
  218. m_updateList.Clear();
  219. }
  220. }
  221. public void AddPhysicalPrim(int number)
  222. {
  223. m_physicalPrim++;
  224. }
  225. public void RemovePhysicalPrim(int number)
  226. {
  227. m_physicalPrim--;
  228. }
  229. public void AddToScriptLPS(int number)
  230. {
  231. m_scriptLPS += number;
  232. }
  233. public void AddActiveScripts(int number)
  234. {
  235. m_activeScripts += number;
  236. }
  237. public void RemovePrim(uint localID, LLUUID avatar_deleter)
  238. {
  239. List<EntityBase> EntityList = GetEntities();
  240. foreach (EntityBase obj in EntityList)
  241. {
  242. if (obj is SceneObjectGroup)
  243. {
  244. if (((SceneObjectGroup)obj).LocalId == localID)
  245. {
  246. m_parentScene.RemoveEntity((SceneObjectGroup)obj);
  247. m_numPrim--;
  248. return;
  249. }
  250. }
  251. }
  252. }
  253. public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
  254. {
  255. List<EntityBase> EntityList = GetEntities();
  256. foreach (EntityBase obj in EntityList)
  257. {
  258. if (obj is SceneObjectGroup)
  259. {
  260. if (((SceneObjectGroup)obj).LocalId == objectLocalID)
  261. {
  262. SceneObjectGroup group = (SceneObjectGroup)obj;
  263. //group.DetachToGround();
  264. DetachSingleAttachmentToInv(group.GetFromAssetID(),remoteClient);
  265. }
  266. }
  267. }
  268. }
  269. public void HandleUndo(IClientAPI remoteClient, LLUUID primId)
  270. {
  271. if (primId != LLUUID.Zero)
  272. {
  273. SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId);
  274. if (part != null)
  275. part.Undo();
  276. }
  277. }
  278. /// <summary>
  279. /// Event Handling routine for Attach Object
  280. /// </summary>
  281. /// <param name="remoteClient"></param>
  282. /// <param name="objectLocalID"></param>
  283. /// <param name="AttachmentPt"></param>
  284. /// <param name="rot"></param>
  285. public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot)
  286. {
  287. // Calls attach with a Zero position
  288. AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, LLVector3.Zero);
  289. }
  290. public void RezSingleAttachment(IClientAPI remoteClient, LLUUID itemID, uint AttachmentPt,uint ItemFlags, uint NextOwnerMask)
  291. {
  292. SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient, itemID, LLVector3.Zero, LLVector3.Zero, LLUUID.Zero, (byte)1, true,
  293. (uint)(PermissionMask.Copy | PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer),
  294. (uint)(PermissionMask.Copy | PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer),
  295. (uint)(PermissionMask.Copy | PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer),
  296. ItemFlags, false, false, remoteClient.AgentId, true);
  297. if (objatt != null)
  298. {
  299. AttachObject(remoteClient,objatt.LocalId,AttachmentPt,new LLQuaternion(0,0,0,1),objatt.AbsolutePosition);
  300. objatt.ScheduleGroupForFullUpdate();
  301. }
  302. }
  303. // What makes this method odd and unique is it tries to detach using an LLUUID.... Yay for standards.
  304. // To LocalId or LLUUID, *THAT* is the question. How now Brown LLUUID??
  305. public void DetachSingleAttachmentToInv(LLUUID itemID, IClientAPI remoteClient)
  306. {
  307. if (itemID == LLUUID.Zero) // If this happened, someone made a mistake....
  308. return;
  309. List<EntityBase> EntityList = GetEntities();
  310. foreach (EntityBase obj in EntityList)
  311. {
  312. if (obj is SceneObjectGroup)
  313. {
  314. if (((SceneObjectGroup)obj).GetFromAssetID() == itemID)
  315. {
  316. SceneObjectGroup group = (SceneObjectGroup)obj;
  317. group.DetachToInventoryPrep();
  318. m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
  319. m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(),group.OwnerID);
  320. m_parentScene.DeleteSceneObjectGroup(group);
  321. }
  322. }
  323. }
  324. }
  325. public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot, LLVector3 attachPos)
  326. {
  327. List<EntityBase> EntityList = GetEntities();
  328. foreach (EntityBase obj in EntityList)
  329. {
  330. if (obj is SceneObjectGroup)
  331. {
  332. if (((SceneObjectGroup)obj).LocalId == objectLocalID)
  333. {
  334. SceneObjectGroup group = (SceneObjectGroup)obj;
  335. // If the attachment point isn't the same as the one previously used
  336. // set it's offset position = 0 so that it appears on the attachment point
  337. // and not in a weird location somewhere unknown.
  338. if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
  339. {
  340. attachPos = LLVector3.Zero;
  341. }
  342. // AttachmentPt 0 means the client chose to 'wear' the attachment.
  343. if (AttachmentPt == 0)
  344. {
  345. // Check object for stored attachment point
  346. AttachmentPt = (uint)group.GetAttachmentPoint();
  347. }
  348. // if we still didn't find a suitable attachment point.......
  349. if (AttachmentPt == 0)
  350. {
  351. // Stick it on left hand with Zero Offset from the attachment point.
  352. AttachmentPt = (uint)AttachmentPoint.LeftHand;
  353. attachPos = LLVector3.Zero;
  354. }
  355. m_log.Debug("[ATTACH]: Using attachpoint: " + AttachmentPt.ToString());
  356. // Saves and gets assetID
  357. if (group.GetFromAssetID() == LLUUID.Zero)
  358. {
  359. LLUUID newAssetID = m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId);
  360. // sets assetID so client can show asset as 'attached' in inventory
  361. group.SetFromAssetID(newAssetID);
  362. }
  363. group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos);
  364. }
  365. }
  366. }
  367. }
  368. // Use the above method.
  369. public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot,
  370. bool deadMethod)
  371. {
  372. Console.WriteLine("Attaching object " + objectLocalID + " to " + AttachmentPt);
  373. SceneObjectPart p = GetSceneObjectPart(objectLocalID);
  374. if (p != null)
  375. {
  376. ScenePresence av = null;
  377. if (TryGetAvatar(remoteClient.AgentId, out av))
  378. {
  379. ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
  380. objupdate.RegionData.RegionHandle = m_regInfo.RegionHandle;
  381. objupdate.RegionData.TimeDilation = ushort.MaxValue;
  382. objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[2];
  383. // avatar stuff - horrible group copypaste
  384. objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
  385. objupdate.ObjectData[0].PSBlock = new byte[0];
  386. objupdate.ObjectData[0].ExtraParams = new byte[1];
  387. objupdate.ObjectData[0].MediaURL = new byte[0];
  388. objupdate.ObjectData[0].NameValue = new byte[0];
  389. objupdate.ObjectData[0].Text = new byte[0];
  390. objupdate.ObjectData[0].TextColor = new byte[4];
  391. objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
  392. objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
  393. objupdate.ObjectData[0].Material = 4;
  394. objupdate.ObjectData[0].TextureAnim = new byte[0];
  395. objupdate.ObjectData[0].Sound = LLUUID.Zero;
  396. objupdate.ObjectData[0].State = 0;
  397. objupdate.ObjectData[0].Data = new byte[0];
  398. objupdate.ObjectData[0].ObjectData = new byte[76];
  399. objupdate.ObjectData[0].ObjectData[15] = 128;
  400. objupdate.ObjectData[0].ObjectData[16] = 63;
  401. objupdate.ObjectData[0].ObjectData[56] = 128;
  402. objupdate.ObjectData[0].ObjectData[61] = 102;
  403. objupdate.ObjectData[0].ObjectData[62] = 40;
  404. objupdate.ObjectData[0].ObjectData[63] = 61;
  405. objupdate.ObjectData[0].ObjectData[64] = 189;
  406. objupdate.ObjectData[0].UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
  407. objupdate.ObjectData[0].PathCurve = 16;
  408. objupdate.ObjectData[0].ProfileCurve = 1;
  409. objupdate.ObjectData[0].PathScaleX = 100;
  410. objupdate.ObjectData[0].PathScaleY = 100;
  411. objupdate.ObjectData[0].ParentID = 0;
  412. objupdate.ObjectData[0].OwnerID = LLUUID.Zero;
  413. objupdate.ObjectData[0].Scale = new LLVector3(1, 1, 1);
  414. objupdate.ObjectData[0].PCode = (byte)PCode.Avatar;
  415. objupdate.ObjectData[0].TextureEntry = ScenePresence.DefaultTexture;
  416. objupdate.ObjectData[0].ID = av.LocalId;
  417. objupdate.ObjectData[0].FullID = remoteClient.AgentId;
  418. objupdate.ObjectData[0].ParentID = 0;
  419. objupdate.ObjectData[0].NameValue =
  420. Helpers.StringToField("FirstName STRING RW SV " + av.Firstname + "\nLastName STRING RW SV " + av.Lastname);
  421. LLVector3 pos2 = av.AbsolutePosition;
  422. // new LLVector3((float) Pos.X, (float) Pos.Y, (float) Pos.Z);
  423. byte[] pb = pos2.GetBytes();
  424. Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
  425. // primitive part
  426. objupdate.ObjectData[1] = new ObjectUpdatePacket.ObjectDataBlock();
  427. // SetDefaultPrimPacketValues
  428. objupdate.ObjectData[1].PSBlock = new byte[0];
  429. objupdate.ObjectData[1].ExtraParams = new byte[1];
  430. objupdate.ObjectData[1].MediaURL = new byte[0];
  431. objupdate.ObjectData[1].NameValue = new byte[0];
  432. objupdate.ObjectData[1].Text = new byte[0];
  433. objupdate.ObjectData[1].TextColor = new byte[4];
  434. objupdate.ObjectData[1].JointAxisOrAnchor = new LLVector3(0, 0, 0);
  435. objupdate.ObjectData[1].JointPivot = new LLVector3(0, 0, 0);
  436. objupdate.ObjectData[1].Material = 3;
  437. objupdate.ObjectData[1].TextureAnim = new byte[0];
  438. objupdate.ObjectData[1].Sound = LLUUID.Zero;
  439. objupdate.ObjectData[1].State = 0;
  440. objupdate.ObjectData[1].Data = new byte[0];
  441. objupdate.ObjectData[1].ObjectData = new byte[60];
  442. objupdate.ObjectData[1].ObjectData[46] = 128;
  443. objupdate.ObjectData[1].ObjectData[47] = 63;
  444. // SetPrimPacketShapeData
  445. PrimitiveBaseShape primData = p.Shape;
  446. objupdate.ObjectData[1].TextureEntry = primData.TextureEntry;
  447. objupdate.ObjectData[1].PCode = primData.PCode;
  448. objupdate.ObjectData[1].State = (byte)(((byte)AttachmentPt) << 4);
  449. objupdate.ObjectData[1].PathBegin = primData.PathBegin;
  450. objupdate.ObjectData[1].PathEnd = primData.PathEnd;
  451. objupdate.ObjectData[1].PathScaleX = primData.PathScaleX;
  452. objupdate.ObjectData[1].PathScaleY = primData.PathScaleY;
  453. objupdate.ObjectData[1].PathShearX = primData.PathShearX;
  454. objupdate.ObjectData[1].PathShearY = primData.PathShearY;
  455. objupdate.ObjectData[1].PathSkew = primData.PathSkew;
  456. objupdate.ObjectData[1].ProfileBegin = primData.ProfileBegin;
  457. objupdate.ObjectData[1].ProfileEnd = primData.ProfileEnd;
  458. objupdate.ObjectData[1].Scale = primData.Scale;
  459. objupdate.ObjectData[1].PathCurve = primData.PathCurve;
  460. objupdate.ObjectData[1].ProfileCurve = primData.ProfileCurve;
  461. objupdate.ObjectData[1].ProfileHollow = primData.ProfileHollow;
  462. objupdate.ObjectData[1].PathRadiusOffset = primData.PathRadiusOffset;
  463. objupdate.ObjectData[1].PathRevolutions = primData.PathRevolutions;
  464. objupdate.ObjectData[1].PathTaperX = primData.PathTaperX;
  465. objupdate.ObjectData[1].PathTaperY = primData.PathTaperY;
  466. objupdate.ObjectData[1].PathTwist = primData.PathTwist;
  467. objupdate.ObjectData[1].PathTwistBegin = primData.PathTwistBegin;
  468. objupdate.ObjectData[1].ExtraParams = primData.ExtraParams;
  469. objupdate.ObjectData[1].UpdateFlags = 276957500; // flags; // ??
  470. objupdate.ObjectData[1].ID = p.LocalId;
  471. objupdate.ObjectData[1].FullID = p.UUID;
  472. objupdate.ObjectData[1].OwnerID = p.OwnerID;
  473. objupdate.ObjectData[1].Text = Helpers.StringToField(p.Text);
  474. objupdate.ObjectData[1].TextColor[0] = 255;
  475. objupdate.ObjectData[1].TextColor[1] = 255;
  476. objupdate.ObjectData[1].TextColor[2] = 255;
  477. objupdate.ObjectData[1].TextColor[3] = 128;
  478. objupdate.ObjectData[1].ParentID = objupdate.ObjectData[0].ID;
  479. //objupdate.ObjectData[1].PSBlock = particleSystem;
  480. //objupdate.ObjectData[1].ClickAction = clickAction;
  481. objupdate.ObjectData[1].Radius = 20;
  482. objupdate.ObjectData[1].NameValue =
  483. Helpers.StringToField("AttachItemID STRING RW SV " + p.UUID);
  484. LLVector3 pos = new LLVector3((float)0.0, (float)0.0, (float)0.0);
  485. pb = pos.GetBytes();
  486. Array.Copy(pb, 0, objupdate.ObjectData[1].ObjectData, 0, pb.Length);
  487. byte[] brot = rot.GetBytes();
  488. Array.Copy(brot, 0, objupdate.ObjectData[1].ObjectData, 36, brot.Length);
  489. remoteClient.OutPacket(objupdate, ThrottleOutPacketType.Task);
  490. }
  491. else
  492. {
  493. m_log.Info("[SCENE]: Avatar " + remoteClient.AgentId + " not found");
  494. }
  495. }
  496. else
  497. {
  498. m_log.Info("[SCENE]: Attempting to attach object; Object " + objectLocalID + "(localID) not found");
  499. }
  500. }
  501. public ScenePresence CreateAndAddScenePresence(IClientAPI client, bool child, AvatarAppearance appearance)
  502. {
  503. ScenePresence newAvatar = null;
  504. newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance);
  505. newAvatar.IsChildAgent = child;
  506. if (child)
  507. {
  508. m_numChildAgents++;
  509. m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Creating new child agent.");
  510. }
  511. else
  512. {
  513. m_numRootAgents++;
  514. m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Creating new root agent.");
  515. m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Adding Physical agent.");
  516. newAvatar.AddToPhysicalScene();
  517. }
  518. lock (Entities)
  519. {
  520. if (!Entities.ContainsKey(client.AgentId))
  521. {
  522. Entities.Add(client.AgentId, newAvatar);
  523. }
  524. else
  525. {
  526. Entities[client.AgentId] = newAvatar;
  527. }
  528. }
  529. lock (ScenePresences)
  530. {
  531. if (ScenePresences.ContainsKey(client.AgentId))
  532. {
  533. ScenePresences[client.AgentId] = newAvatar;
  534. }
  535. else
  536. {
  537. ScenePresences.Add(client.AgentId, newAvatar);
  538. }
  539. }
  540. return newAvatar;
  541. }
  542. public void AddScenePresence(ScenePresence presence)
  543. {
  544. bool child = presence.IsChildAgent;
  545. if (child)
  546. {
  547. m_numChildAgents++;
  548. m_log.Info("[SCENE]" + m_regInfo.RegionName + ": Creating new child agent.");
  549. }
  550. else
  551. {
  552. m_numRootAgents++;
  553. m_log.Info("[SCENE] " + m_regInfo.RegionName + ": Creating new root agent.");
  554. m_log.Info("[SCENE] " + m_regInfo.RegionName + ": Adding Physical agent.");
  555. presence.AddToPhysicalScene();
  556. }
  557. lock (Entities)
  558. {
  559. Entities[presence.UUID] = presence;
  560. }
  561. lock (ScenePresences)
  562. {
  563. ScenePresences[presence.UUID] = presence;
  564. }
  565. }
  566. public void SwapRootChildAgent(bool direction_RC_CR_T_F)
  567. {
  568. if (direction_RC_CR_T_F)
  569. {
  570. m_numRootAgents--;
  571. m_numChildAgents++;
  572. }
  573. else
  574. {
  575. m_numChildAgents--;
  576. m_numRootAgents++;
  577. }
  578. }
  579. public void removeUserCount(bool TypeRCTF)
  580. {
  581. if (TypeRCTF)
  582. {
  583. m_numRootAgents--;
  584. }
  585. else
  586. {
  587. m_numChildAgents--;
  588. }
  589. }
  590. public void RemoveAPrimCount()
  591. {
  592. m_numPrim--;
  593. }
  594. public void AddAPrimCount()
  595. {
  596. m_numPrim++;
  597. }
  598. public int GetChildAgentCount()
  599. {
  600. // some network situations come in where child agents get closed twice.
  601. if (m_numChildAgents < 0)
  602. {
  603. m_numChildAgents = 0;
  604. }
  605. return m_numChildAgents;
  606. }
  607. public int GetRootAgentCount()
  608. {
  609. return m_numRootAgents;
  610. }
  611. public int GetTotalObjects()
  612. {
  613. return m_numPrim;
  614. }
  615. public int GetActiveObjects()
  616. {
  617. return m_physicalPrim;
  618. }
  619. public int GetActiveScripts()
  620. {
  621. return m_activeScripts;
  622. }
  623. public int GetScriptLPS()
  624. {
  625. int returnval = m_scriptLPS;
  626. m_scriptLPS = 0;
  627. return returnval;
  628. }
  629. #endregion
  630. #region Get Methods
  631. /// <summary>
  632. /// Request a List of all m_scenePresences in this World
  633. /// </summary>
  634. /// <returns></returns>
  635. public List<ScenePresence> GetScenePresences()
  636. {
  637. List<ScenePresence> result;
  638. lock (ScenePresences)
  639. {
  640. result = new List<ScenePresence>(ScenePresences.Values);
  641. }
  642. return result;
  643. }
  644. public List<ScenePresence> GetAvatars()
  645. {
  646. List<ScenePresence> result =
  647. GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; });
  648. return result;
  649. }
  650. /// <summary>
  651. /// Get the controlling client for the given avatar, if there is one.
  652. ///
  653. /// FIXME: The only user of the method right now is Caps.cs, in order to resolve a client API since it can't
  654. /// use the ScenePresence. This could be better solved in a number of ways - we could establish an
  655. /// OpenSim.Framework.IScenePresence, or move the caps code into a region package (which might be the more
  656. /// suitable solution).
  657. /// </summary>
  658. /// <param name="agentId"></param>
  659. /// <returns>null if either the avatar wasn't in the scene, or they do not have a controlling client</returns>
  660. public IClientAPI GetControllingClient(LLUUID agentId)
  661. {
  662. ScenePresence presence = GetScenePresence(agentId);
  663. if (presence != null)
  664. {
  665. return presence.ControllingClient;
  666. }
  667. return null;
  668. }
  669. /// <summary>
  670. /// Request a filtered list of m_scenePresences in this World
  671. /// </summary>
  672. /// <returns></returns>
  673. public List<ScenePresence> GetScenePresences(FilterAvatarList filter)
  674. {
  675. List<ScenePresence> result = new List<ScenePresence>();
  676. List<ScenePresence> ScenePresencesList = GetScenePresences();
  677. foreach (ScenePresence avatar in ScenePresencesList)
  678. {
  679. if (filter(avatar))
  680. {
  681. result.Add(avatar);
  682. }
  683. }
  684. return result;
  685. }
  686. /// <summary>
  687. /// Request a scene presence by UUID
  688. /// </summary>
  689. /// <param name="avatarID"></param>
  690. /// <returns>null if the agent was not found</returns>
  691. public ScenePresence GetScenePresence(LLUUID agentID)
  692. {
  693. if (ScenePresences.ContainsKey(agentID))
  694. {
  695. return ScenePresences[agentID];
  696. }
  697. return null;
  698. }
  699. private SceneObjectGroup GetGroupByPrim(uint localID)
  700. {
  701. List<EntityBase> EntityList = GetEntities();
  702. foreach (EntityBase ent in EntityList)
  703. {
  704. if (ent is SceneObjectGroup)
  705. {
  706. if (((SceneObjectGroup)ent).HasChildPrim(localID))
  707. return (SceneObjectGroup)ent;
  708. }
  709. }
  710. return null;
  711. }
  712. private SceneObjectGroup GetGroupByPrim(LLUUID fullID)
  713. {
  714. List<EntityBase> EntityList = GetEntities();
  715. foreach (EntityBase ent in EntityList)
  716. {
  717. if (ent is SceneObjectGroup)
  718. {
  719. if (((SceneObjectGroup)ent).HasChildPrim(fullID))
  720. return (SceneObjectGroup)ent;
  721. }
  722. }
  723. return null;
  724. }
  725. public EntityIntersection GetClosestIntersectingPrim(Ray hray, bool frontFacesOnly, bool faceCenters)
  726. {
  727. // Primitive Ray Tracing
  728. float closestDistance = 280f;
  729. EntityIntersection returnResult = new EntityIntersection();
  730. foreach (EntityBase ent in Entities.Values)
  731. {
  732. if (ent is SceneObjectGroup)
  733. {
  734. SceneObjectGroup reportingG = (SceneObjectGroup)ent;
  735. EntityIntersection result = reportingG.TestIntersection(hray, frontFacesOnly, faceCenters);
  736. if (result.HitTF)
  737. {
  738. if (result.distance < closestDistance)
  739. {
  740. closestDistance = result.distance;
  741. returnResult = result;
  742. }
  743. }
  744. }
  745. }
  746. return returnResult;
  747. }
  748. public SceneObjectPart GetSceneObjectPart(uint localID)
  749. {
  750. SceneObjectGroup group = GetGroupByPrim(localID);
  751. if (group != null)
  752. return group.GetChildPart(localID);
  753. else
  754. return null;
  755. }
  756. public SceneObjectPart GetSceneObjectPart(LLUUID fullID)
  757. {
  758. SceneObjectGroup group = GetGroupByPrim(fullID);
  759. if (group != null)
  760. return group.GetChildPart(fullID);
  761. else
  762. return null;
  763. }
  764. internal bool TryGetAvatar(LLUUID avatarId, out ScenePresence avatar)
  765. {
  766. ScenePresence presence;
  767. if (ScenePresences.TryGetValue(avatarId, out presence))
  768. {
  769. if (!presence.IsChildAgent)
  770. {
  771. avatar = presence;
  772. return true;
  773. }
  774. else
  775. {
  776. m_log.WarnFormat(
  777. "[INNER SCENE]: Requested avatar {0} could not be found in scene {1} since it is only registered as a child agent!",
  778. avatarId, m_parentScene.RegionInfo.RegionName);
  779. }
  780. }
  781. avatar = null;
  782. return false;
  783. }
  784. internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
  785. {
  786. foreach (ScenePresence presence in ScenePresences.Values)
  787. {
  788. if (!presence.IsChildAgent)
  789. {
  790. string name = presence.ControllingClient.FirstName + " " + presence.ControllingClient.LastName;
  791. if (String.Compare(avatarName, name, true) == 0)
  792. {
  793. avatar = presence;
  794. return true;
  795. }
  796. }
  797. }
  798. avatar = null;
  799. return false;
  800. }
  801. public List<EntityBase> GetEntities()
  802. {
  803. List<EntityBase> result;
  804. lock (Entities)
  805. {
  806. result = new List<EntityBase>(Entities.Values);
  807. }
  808. return result;
  809. }
  810. #endregion
  811. #region Other Methods
  812. public void physicsBasedCrash()
  813. {
  814. handlerPhysicsCrash = UnRecoverableError;
  815. if (handlerPhysicsCrash != null)
  816. {
  817. handlerPhysicsCrash();
  818. }
  819. }
  820. public LLUUID ConvertLocalIDToFullID(uint localID)
  821. {
  822. SceneObjectGroup group = GetGroupByPrim(localID);
  823. if (group != null)
  824. return group.GetPartsFullID(localID);
  825. else
  826. return LLUUID.Zero;
  827. }
  828. public void SendAllSceneObjectsToClient(ScenePresence presence)
  829. {
  830. List<EntityBase> EntityList = GetEntities();
  831. foreach (EntityBase ent in EntityList)
  832. {
  833. if (ent is SceneObjectGroup)
  834. {
  835. // Only send child agents stuff in their draw distance.
  836. // This will need to be done for every agent once we figure out
  837. // what we're going to use to store prim that agents already got
  838. // the initial update for and what we'll use to limit the
  839. // space we check for new objects on movement.
  840. if (presence.IsChildAgent && m_parentScene.m_seeIntoRegionFromNeighbor)
  841. {
  842. LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition;
  843. float distResult = (float)Util.GetDistanceTo(presence.AbsolutePosition, oLoc);
  844. //m_log.Info("[DISTANCE]: " + distResult.ToString());
  845. if (distResult < presence.DrawDistance)
  846. {
  847. // Send Only if we don't already know about it.
  848. // KnownPrim also makes the prim known when called.
  849. if (!presence.KnownPrim(((SceneObjectGroup)ent).UUID))
  850. ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
  851. }
  852. }
  853. else
  854. {
  855. ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
  856. }
  857. }
  858. }
  859. }
  860. internal void ForEachClient(Action<IClientAPI> action)
  861. {
  862. foreach (ScenePresence presence in ScenePresences.Values)
  863. {
  864. action(presence.ControllingClient);
  865. }
  866. }
  867. #endregion
  868. #region Client Event handlers
  869. /// <summary>
  870. ///
  871. /// </summary>
  872. /// <param name="localID"></param>
  873. /// <param name="scale"></param>
  874. /// <param name="remoteClient"></param>
  875. public void UpdatePrimScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
  876. {
  877. SceneObjectGroup group = GetGroupByPrim(localID);
  878. if (group != null)
  879. {
  880. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  881. {
  882. group.Resize(scale, localID);
  883. }
  884. }
  885. }
  886. public void UpdatePrimGroupScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
  887. {
  888. SceneObjectGroup group = GetGroupByPrim(localID);
  889. if (group != null)
  890. {
  891. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  892. {
  893. group.GroupResize(scale, localID);
  894. }
  895. }
  896. }
  897. /// <summary>
  898. /// This handles the nifty little tool tip that you get when you drag your mouse over an object
  899. /// Send to the Object Group to process. We don't know enough to service the request
  900. /// </summary>
  901. /// <param name="remoteClient"></param>
  902. /// <param name="AgentID"></param>
  903. /// <param name="RequestFlags"></param>
  904. /// <param name="ObjectID"></param>
  905. public void RequestObjectPropertiesFamily(IClientAPI remoteClient, LLUUID AgentID, uint RequestFlags,
  906. LLUUID ObjectID)
  907. {
  908. SceneObjectGroup group = GetGroupByPrim(ObjectID);
  909. if (group != null)
  910. {
  911. group.ServiceObjectPropertiesFamilyRequest(remoteClient, AgentID, RequestFlags);
  912. }
  913. }
  914. /// <summary>
  915. ///
  916. /// </summary>
  917. /// <param name="localID"></param>
  918. /// <param name="rot"></param>
  919. /// <param name="remoteClient"></param>
  920. public void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
  921. {
  922. SceneObjectGroup group = GetGroupByPrim(localID);
  923. if (group != null)
  924. {
  925. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  926. {
  927. group.UpdateSingleRotation(rot, localID);
  928. }
  929. }
  930. }
  931. /// <summary>
  932. ///
  933. /// </summary>
  934. /// <param name="localID"></param>
  935. /// <param name="rot"></param>
  936. /// <param name="remoteClient"></param>
  937. public void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
  938. {
  939. SceneObjectGroup group = GetGroupByPrim(localID);
  940. if (group != null)
  941. {
  942. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  943. {
  944. group.UpdateGroupRotation(rot);
  945. }
  946. }
  947. }
  948. /// <summary>
  949. ///
  950. /// </summary>
  951. /// <param name="localID"></param>
  952. /// <param name="pos"></param>
  953. /// <param name="rot"></param>
  954. /// <param name="remoteClient"></param>
  955. public void UpdatePrimRotation(uint localID, LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient)
  956. {
  957. SceneObjectGroup group = GetGroupByPrim(localID);
  958. if (group != null)
  959. {
  960. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  961. {
  962. group.UpdateGroupRotation(pos, rot);
  963. }
  964. }
  965. }
  966. public void UpdatePrimSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
  967. {
  968. SceneObjectGroup group = GetGroupByPrim(localID);
  969. if (group != null)
  970. {
  971. LLVector3 oldPos = group.AbsolutePosition;
  972. if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos) && !group.RootPart.m_IsAttachment)
  973. {
  974. group.SendGroupTerseUpdate();
  975. return;
  976. }
  977. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID) || group.RootPart.m_IsAttachment)
  978. {
  979. group.UpdateSinglePosition(pos, localID);
  980. }
  981. }
  982. }
  983. /// <summary>
  984. ///
  985. /// </summary>
  986. /// <param name="localID"></param>
  987. /// <param name="pos"></param>
  988. /// <param name="remoteClient"></param>
  989. public void UpdatePrimPosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
  990. {
  991. SceneObjectGroup group = GetGroupByPrim(localID);
  992. if (group != null)
  993. {
  994. LLVector3 oldPos = group.AbsolutePosition;
  995. if (group.RootPart.m_IsAttachment)
  996. {
  997. group.UpdateGroupPosition(pos);
  998. }
  999. else
  1000. {
  1001. if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos) && !group.RootPart.m_IsAttachment)
  1002. {
  1003. group.SendGroupTerseUpdate();
  1004. return;
  1005. }
  1006. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID) || group.RootPart.m_IsAttachment)
  1007. {
  1008. group.UpdateGroupPosition(pos);
  1009. }
  1010. }
  1011. }
  1012. }
  1013. /// <summary>
  1014. ///
  1015. /// </summary>
  1016. /// <param name="localID"></param>
  1017. /// <param name="texture"></param>
  1018. /// <param name="remoteClient"></param>
  1019. public void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient)
  1020. {
  1021. SceneObjectGroup group = GetGroupByPrim(localID);
  1022. if (group != null)
  1023. {
  1024. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
  1025. {
  1026. group.UpdateTextureEntry(localID, texture);
  1027. }
  1028. }
  1029. }
  1030. /// <summary>
  1031. ///
  1032. /// </summary>
  1033. /// <param name="localID"></param>
  1034. /// <param name="packet"></param>
  1035. /// <param name="remoteClient"></param>
  1036. public void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient)
  1037. {
  1038. SceneObjectGroup group = GetGroupByPrim(localID);
  1039. if (group != null)
  1040. {
  1041. if (PermissionsMngr.CanEditObject(remoteClient.AgentId, group.UUID))
  1042. {
  1043. group.UpdatePrimFlags(localID, (ushort)packet.Type, true, packet.ToBytes());
  1044. }
  1045. }
  1046. }
  1047. public void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 pos, IClientAPI remoteClient)
  1048. {
  1049. SceneObjectGroup group = GetGroupByPrim(objectID);
  1050. if (group != null)
  1051. {
  1052. if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))// && PermissionsMngr.)
  1053. {
  1054. group.GrabMovement(offset, pos, remoteClient);
  1055. }
  1056. // This is outside the above permissions condition
  1057. // so that if the object is locked the client moving the object
  1058. // get's it's position on the simulator even if it was the same as before
  1059. // This keeps the moving user's client in sync with the rest of the world.
  1060. group.SendGroupTerseUpdate();
  1061. }
  1062. }
  1063. /// <summary>
  1064. ///
  1065. /// </summary>
  1066. /// <param name="primLocalID"></param>
  1067. /// <param name="description"></param>
  1068. public void PrimName(IClientAPI remoteClient, uint primLocalID, string name)
  1069. {
  1070. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  1071. if (group != null)
  1072. {
  1073. if (PermissionsMngr.CanEditObject(remoteClient.AgentId, group.UUID))
  1074. {
  1075. group.SetPartName(Util.CleanString(name), primLocalID);
  1076. }
  1077. }
  1078. }
  1079. /// <summary>
  1080. ///
  1081. /// </summary>
  1082. /// <param name="primLocalID"></param>
  1083. /// <param name="description"></param>
  1084. public void PrimDescription(IClientAPI remoteClient, uint primLocalID, string description)
  1085. {
  1086. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  1087. if (group != null)
  1088. {
  1089. if (PermissionsMngr.CanEditObject(remoteClient.AgentId, group.UUID))
  1090. {
  1091. group.SetPartDescription(Util.CleanString(description), primLocalID);
  1092. }
  1093. }
  1094. }
  1095. public void UpdateExtraParam(LLUUID agentID, uint primLocalID, ushort type, bool inUse, byte[] data)
  1096. {
  1097. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  1098. if (group != null)
  1099. {
  1100. if (PermissionsMngr.CanEditObject(agentID, group.UUID))
  1101. {
  1102. group.UpdateExtraParam(primLocalID, type, inUse, data);
  1103. }
  1104. }
  1105. }
  1106. /// <summary>
  1107. ///
  1108. /// </summary>
  1109. /// <param name="primLocalID"></param>
  1110. /// <param name="shapeBlock"></param>
  1111. public void UpdatePrimShape(LLUUID agentID, uint primLocalID, ObjectShapePacket.ObjectDataBlock shapeBlock)
  1112. {
  1113. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  1114. if (group != null)
  1115. {
  1116. if (PermissionsMngr.CanEditObjectPosition(agentID, group.GetPartsFullID(primLocalID)))
  1117. {
  1118. group.UpdateShape(shapeBlock, primLocalID);
  1119. }
  1120. }
  1121. }
  1122. /// <summary>
  1123. /// Initial method invoked when we receive a link objects request from the client.
  1124. /// </summary>
  1125. /// <param name="client"></param>
  1126. /// <param name="parentPrim"></param>
  1127. /// <param name="childPrims"></param>
  1128. public void LinkObjects(IClientAPI client, uint parentPrim, List<uint> childPrims)
  1129. {
  1130. List<EntityBase> EntityList = GetEntities();
  1131. SceneObjectGroup parenPrim = null;
  1132. foreach (EntityBase ent in EntityList)
  1133. {
  1134. if (ent is SceneObjectGroup)
  1135. {
  1136. if (((SceneObjectGroup)ent).LocalId == parentPrim)
  1137. {
  1138. parenPrim = (SceneObjectGroup)ent;
  1139. break;
  1140. }
  1141. }
  1142. }
  1143. List<SceneObjectGroup> children = new List<SceneObjectGroup>();
  1144. if (parenPrim != null)
  1145. {
  1146. for (int i = 0; i < childPrims.Count; i++)
  1147. {
  1148. foreach (EntityBase ent in EntityList)
  1149. {
  1150. if (ent is SceneObjectGroup)
  1151. {
  1152. if (((SceneObjectGroup)ent).LocalId == childPrims[i])
  1153. {
  1154. children.Add((SceneObjectGroup)ent);
  1155. }
  1156. }
  1157. }
  1158. }
  1159. }
  1160. foreach (SceneObjectGroup sceneObj in children)
  1161. {
  1162. parenPrim.LinkToGroup(sceneObj);
  1163. }
  1164. // We need to explicitly resend the newly link prim's object properties since no other actions
  1165. // occur on link to invoke this elsewhere (such as object selection)
  1166. parenPrim.GetProperties(client);
  1167. }
  1168. /// <summary>
  1169. /// Delink a linkset
  1170. /// </summary>
  1171. /// <param name="prims"></param>
  1172. public void DelinkObjects(List<uint> primIds)
  1173. {
  1174. SceneObjectGroup parenPrim = null;
  1175. // Need a list of the SceneObjectGroup local ids
  1176. // XXX I'm anticipating that building this dictionary once is more efficient than
  1177. // repeated scanning of the Entity.Values for a large number of primIds. However, it might
  1178. // be more efficient yet to keep this dictionary permanently on hand.
  1179. Dictionary<uint, SceneObjectGroup> sceneObjects = new Dictionary<uint, SceneObjectGroup>();
  1180. List<EntityBase> EntitieList = GetEntities();
  1181. foreach (EntityBase ent in EntitieList)
  1182. {
  1183. if (ent is SceneObjectGroup)
  1184. {
  1185. SceneObjectGroup obj = (SceneObjectGroup)ent;
  1186. sceneObjects.Add(obj.LocalId, obj);
  1187. }
  1188. }
  1189. // Find the root prim among the prim ids we've been given
  1190. for (int i = 0; i < primIds.Count; i++)
  1191. {
  1192. if (sceneObjects.ContainsKey(primIds[i]))
  1193. {
  1194. parenPrim = sceneObjects[primIds[i]];
  1195. primIds.RemoveAt(i);
  1196. break;
  1197. }
  1198. }
  1199. if (parenPrim != null)
  1200. {
  1201. foreach (uint childPrimId in primIds)
  1202. {
  1203. parenPrim.DelinkFromGroup(childPrimId);
  1204. }
  1205. }
  1206. else
  1207. {
  1208. // If the first scan failed, we need to do a /deep/ scan of the linkages. This is /really/ slow
  1209. // We know that this is not the root prim now essentially, so we don't have to worry about remapping
  1210. // which one is the root prim
  1211. bool delinkedSomething = false;
  1212. for (int i = 0; i < primIds.Count; i++)
  1213. {
  1214. foreach (SceneObjectGroup grp in sceneObjects.Values)
  1215. {
  1216. SceneObjectPart gPart = grp.GetChildPart(primIds[i]);
  1217. if (gPart != null)
  1218. {
  1219. grp.DelinkFromGroup(primIds[i]);
  1220. delinkedSomething = true;
  1221. }
  1222. }
  1223. }
  1224. if (!delinkedSomething)
  1225. {
  1226. m_log.InfoFormat("[SCENE]: " +
  1227. "DelinkObjects(): Could not find a root prim out of {0} as given to a delink request!",
  1228. primIds);
  1229. }
  1230. }
  1231. }
  1232. public void MakeObjectSearchable(IClientAPI remoteClient, bool IncludeInSearch, uint localID)
  1233. {
  1234. LLUUID user = remoteClient.AgentId;
  1235. LLUUID objid = null;
  1236. SceneObjectPart obj = null;
  1237. List<EntityBase> EntityList = GetEntities();
  1238. foreach (EntityBase ent in EntityList)
  1239. {
  1240. if (ent is SceneObjectGroup)
  1241. {
  1242. foreach (KeyValuePair<LLUUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children)
  1243. {
  1244. if (subent.Value.LocalId == localID)
  1245. {
  1246. objid = subent.Key;
  1247. obj = subent.Value;
  1248. }
  1249. }
  1250. }
  1251. }
  1252. //Protip: In my day, we didn't call them searchable objects, we called them limited point-to-point joints
  1253. //aka ObjectFlags.JointWheel = IncludeInSearch
  1254. //Permissions model: Object can be REMOVED from search IFF:
  1255. // * User owns object
  1256. //use CanEditObject
  1257. //Object can be ADDED to search IFF:
  1258. // * User owns object
  1259. // * Asset/DRM permission bit "modify" is enabled
  1260. //use CanEditObjectPosition
  1261. if (IncludeInSearch && PermissionsMngr.CanEditObject(user, objid))
  1262. {
  1263. obj.AddFlag(LLObject.ObjectFlags.JointWheel);
  1264. }
  1265. else if (!IncludeInSearch && PermissionsMngr.CanEditObjectPosition(user, objid))
  1266. {
  1267. obj.RemFlag(LLObject.ObjectFlags.JointWheel);
  1268. }
  1269. }
  1270. /// <summary>
  1271. /// Duplicate the given object.
  1272. /// </summary>
  1273. /// <param name="originalPrim"></param>
  1274. /// <param name="offset"></param>
  1275. /// <param name="flags"></param>
  1276. public void DuplicateObject(uint originalPrim, LLVector3 offset, uint flags, LLUUID AgentID, LLUUID GroupID)
  1277. {
  1278. m_log.DebugFormat("[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}", originalPrim, offset, AgentID);
  1279. List<EntityBase> EntityList = GetEntities();
  1280. SceneObjectGroup originPrim = null;
  1281. foreach (EntityBase ent in EntityList)
  1282. {
  1283. if (ent is SceneObjectGroup)
  1284. {
  1285. if (((SceneObjectGroup)ent).LocalId == originalPrim)
  1286. {
  1287. originPrim = (SceneObjectGroup)ent;
  1288. break;
  1289. }
  1290. }
  1291. }
  1292. if (originPrim != null)
  1293. {
  1294. if (PermissionsMngr.CanCopyObject(AgentID, originPrim.UUID))
  1295. {
  1296. SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID);
  1297. copy.AbsolutePosition = copy.AbsolutePosition + offset;
  1298. copy.ResetIDs();
  1299. lock (Entities)
  1300. {
  1301. Entities.Add(copy.UUID, copy);
  1302. }
  1303. m_numPrim++;
  1304. copy.StartScripts();
  1305. copy.ScheduleGroupForFullUpdate();
  1306. }
  1307. }
  1308. else
  1309. {
  1310. m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID);
  1311. }
  1312. }
  1313. /// <summary>
  1314. /// Calculates the distance between two Vector3s
  1315. /// </summary>
  1316. /// <param name="v1"></param>
  1317. /// <param name="v2"></param>
  1318. /// <returns></returns>
  1319. public float Vector3Distance(Vector3 v1, Vector3 v2)
  1320. {
  1321. // We don't really need the double floating point precision...
  1322. // so casting it to a single
  1323. return
  1324. (float)
  1325. Math.Sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + (v1.z - v2.z) * (v1.z - v2.z));
  1326. }
  1327. #endregion
  1328. }
  1329. }