aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorUbitUmarov2012-02-15 03:51:30 +0000
committerUbitUmarov2012-02-15 03:51:30 +0000
commit04279e36d1bc01f966940eb8cc0457064356fced (patch)
treebff74b33a2cf072877e8f1d876944905399d4be6 /OpenSim/Region
parent remove drawstuff from ubitode (diff)
parentMerge branch 'master' of ssh://melanie@3dhosting.de/var/git/careminster into ... (diff)
downloadopensim-SC-04279e36d1bc01f966940eb8cc0457064356fced.zip
opensim-SC-04279e36d1bc01f966940eb8cc0457064356fced.tar.gz
opensim-SC-04279e36d1bc01f966940eb8cc0457064356fced.tar.bz2
opensim-SC-04279e36d1bc01f966940eb8cc0457064356fced.tar.xz
Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs40
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs150
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs7
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs1
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs89
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs150
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs14
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs71
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs12
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs43
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs29
19 files changed, 460 insertions, 218 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index c20f7b2..161feda 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1549,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1549 1549
1550 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1550 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1551 { 1551 {
1552// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1552// foreach (uint id in localIDs)
1553// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1553 1554
1554 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1555 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1555 // TODO: don't create new blocks if recycling an old packet 1556 // TODO: don't create new blocks if recycling an old packet
@@ -7689,6 +7690,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7689 } 7690 }
7690 } 7691 }
7691 } 7692 }
7693 else
7694 if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
7695 {
7696 //TransferRequestPacket does not include covenant uuid?
7697 //get scene covenant uuid
7698 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
7699 }
7692 7700
7693 MakeAssetRequest(transfer, taskID); 7701 MakeAssetRequest(transfer, taskID);
7694 7702
@@ -12113,6 +12121,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12113 { 12121 {
12114 requestID = new UUID(transferRequest.TransferInfo.Params, 80); 12122 requestID = new UUID(transferRequest.TransferInfo.Params, 80);
12115 } 12123 }
12124 else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate)
12125 {
12126 requestID = taskID;
12127 }
12128
12116 12129
12117// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12130// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
12118 12131
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 8d503bd..c7f4c20 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -111,6 +111,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
111 111
112 #region IAvatarFactoryModule 112 #region IAvatarFactoryModule
113 113
114 /// </summary>
115 /// <param name="sp"></param>
116 /// <param name="texture"></param>
117 /// <param name="visualParam"></param>
118 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
119 {
120 SetAppearance(sp, appearance.Texture, appearance.VisualParams);
121 }
122
114 /// <summary> 123 /// <summary>
115 /// Set appearance data (texture asset IDs and slider settings) 124 /// Set appearance data (texture asset IDs and slider settings)
116 /// </summary> 125 /// </summary>
@@ -156,14 +165,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
156 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 165 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
157 166
158// WriteBakedTexturesReport(sp, m_log.DebugFormat); 167// WriteBakedTexturesReport(sp, m_log.DebugFormat);
159 if (!ValidateBakedTextureCache(sp)) 168
169 // If bake textures are missing and this is not an NPC, request a rebake from client
170 if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
160 RequestRebake(sp, true); 171 RequestRebake(sp, true);
161 172
162 // This appears to be set only in the final stage of the appearance 173 // This appears to be set only in the final stage of the appearance
163 // update transaction. In theory, we should be able to do an immediate 174 // update transaction. In theory, we should be able to do an immediate
164 // appearance send and save here. 175 // appearance send and save here.
165 } 176 }
166 177
178 // NPC should send to clients immediately and skip saving appearance
179 if (((ScenePresence)sp).PresenceType == PresenceType.Npc)
180 {
181 SendAppearance((ScenePresence)sp);
182 return;
183 }
184
167 // save only if there were changes, send no matter what (doesn't hurt to send twice) 185 // save only if there were changes, send no matter what (doesn't hurt to send twice)
168 if (changed) 186 if (changed)
169 QueueAppearanceSave(sp.ControllingClient.AgentId); 187 QueueAppearanceSave(sp.ControllingClient.AgentId);
@@ -174,6 +192,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
174 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); 192 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
175 } 193 }
176 194
195 private void SendAppearance(ScenePresence sp)
196 {
197 // Send the appearance to everyone in the scene
198 sp.SendAppearanceToAllOtherAgents();
199
200 // Send animations back to the avatar as well
201 sp.Animator.SendAnimPack();
202 }
203
177 public bool SendAppearance(UUID agentId) 204 public bool SendAppearance(UUID agentId)
178 { 205 {
179// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); 206// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
@@ -185,12 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
185 return false; 212 return false;
186 } 213 }
187 214
188 // Send the appearance to everyone in the scene 215 SendAppearance(sp);
189 sp.SendAppearanceToAllOtherAgents();
190
191 // Send animations back to the avatar as well
192 sp.Animator.SendAnimPack();
193
194 return true; 216 return true;
195 } 217 }
196 218
@@ -626,4 +648,4 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
626 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); 648 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt");
627 } 649 }
628 } 650 }
629} \ No newline at end of file 651}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index f1399af..9a6dfe1 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -681,11 +681,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
681 681
682 #region Agent Crossings 682 #region Agent Crossings
683 683
684 public bool Cross(ScenePresence agent, bool isFlying) 684 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
685 { 685 {
686 Scene scene = agent.Scene; 686 version = String.Empty;
687 Vector3 pos = agent.AbsolutePosition; 687 newpos = new Vector3(pos.X, pos.Y, pos.Z);
688 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
689 uint neighbourx = scene.RegionInfo.RegionLocX; 688 uint neighbourx = scene.RegionInfo.RegionLocX;
690 uint neighboury = scene.RegionInfo.RegionLocY; 689 uint neighboury = scene.RegionInfo.RegionLocY;
691 const float boundaryDistance = 1.7f; 690 const float boundaryDistance = 1.7f;
@@ -706,53 +705,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
706 } 705 }
707 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 706 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
708 { 707 {
709 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 708 neighboury--;
710 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 709 newpos.Y = Constants.RegionSize - enterDistance;
711 {
712 neighboury--;
713 newpos.Y = Constants.RegionSize - enterDistance;
714 }
715 else
716 {
717 agent.IsInTransit = true;
718
719 neighboury = b.TriggerRegionY;
720 neighbourx = b.TriggerRegionX;
721
722 Vector3 newposition = pos;
723 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
724 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
725 agent.ControllingClient.SendAgentAlertMessage(
726 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
727 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
728 return true;
729 }
730 }
731
732 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
733 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
734 {
735 neighbourx--;
736 newpos.X = Constants.RegionSize - enterDistance;
737 } 710 }
738 else
739 {
740 agent.IsInTransit = true;
741
742 neighboury = ba.TriggerRegionY;
743 neighbourx = ba.TriggerRegionX;
744
745
746 Vector3 newposition = pos;
747 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
748 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
749 agent.ControllingClient.SendAgentAlertMessage(
750 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
751 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
752 711
753 712 neighbourx--;
754 return true; 713 newpos.X = Constants.RegionSize - enterDistance;
755 }
756 714
757 } 715 }
758 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 716 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
@@ -763,26 +721,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
763 721
764 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 722 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
765 { 723 {
766 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 724 neighboury--;
767 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 725 newpos.Y = Constants.RegionSize - enterDistance;
768 {
769 neighboury--;
770 newpos.Y = Constants.RegionSize - enterDistance;
771 }
772 else
773 {
774 agent.IsInTransit = true;
775
776 neighboury = ba.TriggerRegionY;
777 neighbourx = ba.TriggerRegionX;
778 Vector3 newposition = pos;
779 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
780 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
781 agent.ControllingClient.SendAgentAlertMessage(
782 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
783 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
784 return true;
785 }
786 } 726 }
787 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 727 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
788 { 728 {
@@ -790,35 +730,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
790 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); 730 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
791 newpos.Y = enterDistance; 731 newpos.Y = enterDistance;
792 } 732 }
793
794
795 } 733 }
796 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 734 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
797 { 735 {
798 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 736 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
799 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 737 neighboury--;
800 { 738 newpos.Y = Constants.RegionSize - enterDistance;
801 neighboury--;
802 newpos.Y = Constants.RegionSize - enterDistance;
803 }
804 else
805 {
806 agent.IsInTransit = true;
807
808 neighboury = b.TriggerRegionY;
809 neighbourx = b.TriggerRegionX;
810 Vector3 newposition = pos;
811 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
812 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
813 agent.ControllingClient.SendAgentAlertMessage(
814 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
815 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
816 return true;
817 }
818 } 739 }
819 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 740 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
820 { 741 {
821
822 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); 742 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
823 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); 743 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
824 newpos.Y = enterDistance; 744 newpos.Y = enterDistance;
@@ -849,19 +769,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
849 } 769 }
850 */ 770 */
851 771
852 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 772 xDest = neighbourx;
773 yDest = neighboury;
853 774
854 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 775 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
855 776
777 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
778
856 ExpiringCache<ulong, DateTime> r; 779 ExpiringCache<ulong, DateTime> r;
857 DateTime banUntil; 780 DateTime banUntil;
858 781
859 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 782 if (m_bannedRegions.TryGetValue(agentID, out r))
860 { 783 {
861 if (r.TryGetValue(neighbourHandle, out banUntil)) 784 if (r.TryGetValue(neighbourHandle, out banUntil))
862 { 785 {
863 if (DateTime.Now < banUntil) 786 if (DateTime.Now < banUntil)
864 return false; 787 return null;
865 r.Remove(neighbourHandle); 788 r.Remove(neighbourHandle);
866 } 789 }
867 } 790 }
@@ -873,28 +796,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
873 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 796 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
874 797
875 string reason; 798 string reason;
876 string version; 799 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
877 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
878 { 800 {
879 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
880 if (r == null) 801 if (r == null)
881 { 802 {
882 r = new ExpiringCache<ulong, DateTime>(); 803 r = new ExpiringCache<ulong, DateTime>();
883 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 804 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
884 805
885 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 806 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
886 } 807 }
887 else 808 else
888 { 809 {
889 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 810 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
890 } 811 }
812 return null;
813 }
814
815 return neighbourRegion;
816 }
817
818 public bool Cross(ScenePresence agent, bool isFlying)
819 {
820 uint x;
821 uint y;
822 Vector3 newpos;
823 string version;
824
825 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
826 if (neighbourRegion == null)
827 {
828 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
891 return false; 829 return false;
892 } 830 }
893 831
894 agent.IsInTransit = true; 832 agent.IsInTransit = true;
895 833
896 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 834 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
897 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 835 d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
898 836
899 return true; 837 return true;
900 } 838 }
@@ -951,13 +889,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
951 icon.EndInvoke(iar); 889 icon.EndInvoke(iar);
952 } 890 }
953 891
954 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
955
956 /// <summary> 892 /// <summary>
957 /// This Closes child agents on neighbouring regions 893 /// This Closes child agents on neighbouring regions
958 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 894 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
959 /// </summary> 895 /// </summary>
960 protected ScenePresence CrossAgentToNewRegionAsync( 896 public ScenePresence CrossAgentToNewRegionAsync(
961 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 897 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
962 bool isFlying, string version) 898 bool isFlying, string version)
963 { 899 {
@@ -1731,17 +1667,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1731 { 1667 {
1732 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 1668 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID);
1733 1669
1670 // Need to turn off the physics flags, otherwise the object will continue to attempt to
1671 // move out of the region creating an infinite loop of failed attempts to cross
1672 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
1673
1734 // We are going to move the object back to the old position so long as the old position 1674 // We are going to move the object back to the old position so long as the old position
1735 // is in the region 1675 // is in the region
1736 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 1676 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1);
1737 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 1677 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1);
1738 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f); 1678 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
1739 1679
1740 grp.RootPart.GroupPosition = oldGroupPosition; 1680 grp.AbsolutePosition = oldGroupPosition;
1741
1742 // Need to turn off the physics flags, otherwise the object will continue to attempt to
1743 // move out of the region creating an infinite loop of failed attempts to cross
1744 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
1745 1681
1746 grp.ScheduleGroupForFullUpdate(); 1682 grp.ScheduleGroupForFullUpdate();
1747 } 1683 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index a47bc9a..82a035b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -560,12 +560,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
560 return null; 560 return null;
561 561
562 userID = remoteClient.AgentId; 562 userID = remoteClient.AgentId;
563
564// m_log.DebugFormat(
565// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is {1} {2}",
566// action, remoteClient.Name, userID);
563 } 567 }
564 else 568 else
565 { 569 {
566 // All returns / deletes go to the object owner 570 // All returns / deletes go to the object owner
567 // 571 //
568 userID = so.RootPart.OwnerID; 572 userID = so.RootPart.OwnerID;
573
574// m_log.DebugFormat(
575// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is object owner {1}",
576// action, userID);
569 } 577 }
570 578
571 if (userID == UUID.Zero) // Can't proceed 579 if (userID == UUID.Zero) // Can't proceed
@@ -651,11 +659,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
651 } 659 }
652 660
653 // Override and put into where it came from, if it came 661 // Override and put into where it came from, if it came
654 // from anywhere in inventory 662 // from anywhere in inventory and the owner is taking it back.
655 // 663 //
656 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) 664 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
657 { 665 {
658 if (so.RootPart.FromFolderID != UUID.Zero) 666 if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
659 { 667 {
660 InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID); 668 InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
661 if (f != null) 669 if (f != null)
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 5e7d37a..ba38488 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -707,7 +707,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
707 // Object owners should be able to edit their own content 707 // Object owners should be able to edit their own content
708 if (currentUser == objectOwner) 708 if (currentUser == objectOwner)
709 { 709 {
710 permission = true; 710 // there is no way that later code can change this back to false
711 // so just return true immediately and short circuit the more
712 // expensive group checks
713 return true;
714
715 //permission = true;
711 } 716 }
712 else if (group.IsAttachment) 717 else if (group.IsAttachment)
713 { 718 {
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
index 39a760c..34aca33 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
@@ -35,6 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
35 35
36 public interface IAvatarFactoryModule 36 public interface IAvatarFactoryModule
37 { 37 {
38 void SetAppearance(IScenePresence sp, AvatarAppearance appearance);
38 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); 39 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams);
39 40
40 /// <summary> 41 /// <summary>
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index c38ecd9..76f1641 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes;
35 35
36namespace OpenSim.Region.Framework.Interfaces 36namespace OpenSim.Region.Framework.Interfaces
37{ 37{
38 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
39
38 public interface IEntityTransferModule 40 public interface IEntityTransferModule
39 { 41 {
40 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, 42 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position,
@@ -53,7 +55,12 @@ namespace OpenSim.Region.Framework.Interfaces
53 55
54 void EnableChildAgent(ScenePresence agent, GridRegion region); 56 void EnableChildAgent(ScenePresence agent, GridRegion region);
55 57
58 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos);
59
56 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 60 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
61
62 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
63
57 } 64 }
58 65
59 public interface IUserAgentVerificationModule 66 public interface IUserAgentVerificationModule
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index 5dfd3e0..f678d07 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -148,7 +148,8 @@ namespace OpenSim.Region.Framework.Scenes
148 x = m_inventoryDeletes.Dequeue(); 148 x = m_inventoryDeletes.Dequeue();
149 149
150 m_log.DebugFormat( 150 m_log.DebugFormat(
151 "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count); 151 "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.",
152 left, x.action, x.objectGroups.Count);
152 153
153 try 154 try
154 { 155 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 456e86b..8552d4c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3408,9 +3408,9 @@ namespace OpenSim.Region.Framework.Scenes
3408 3408
3409 // Don't disable this log message - it's too helpful 3409 // Don't disable this log message - it's too helpful
3410 m_log.DebugFormat( 3410 m_log.DebugFormat(
3411 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6}, position {7})", 3411 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags {8}, position {9})",
3412 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, 3412 RegionInfo.RegionName, (agent.child ? "child" : "root"),agent.firstname, agent.lastname,
3413 agent.AgentID, agent.circuitcode, teleportFlags, agent.startpos); 3413 agent.AgentID, agent.circuitcode, agent.IPAddress, agent.Viewer, teleportFlags, agent.startpos);
3414 3414
3415 if (LoginsDisabled) 3415 if (LoginsDisabled)
3416 { 3416 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 9961438..644b78a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -465,7 +465,77 @@ namespace OpenSim.Region.Framework.Scenes
465 || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) 465 || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
466 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) 466 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
467 { 467 {
468 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 468 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
469 uint x = 0;
470 uint y = 0;
471 string version = String.Empty;
472 Vector3 newpos = Vector3.Zero;
473 OpenSim.Services.Interfaces.GridRegion destination = null;
474
475 bool canCross = true;
476 foreach (ScenePresence av in m_linkedAvatars)
477 {
478 // We need to cross these agents. First, let's find
479 // out if any of them can't cross for some reason.
480 // We have to deny the crossing entirely if any
481 // of them are banned. Alternatively, we could
482 // unsit banned agents....
483
484
485 // We set the avatar position as being the object
486 // position to get the region to send to
487 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
488 {
489 canCross = false;
490 break;
491 }
492
493 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
494 }
495
496 if (canCross)
497 {
498 // We unparent the SP quietly so that it won't
499 // be made to stand up
500 foreach (ScenePresence av in m_linkedAvatars)
501 {
502 SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
503 if (parentPart != null)
504 av.ParentUUID = parentPart.UUID;
505
506 av.ParentID = 0;
507 }
508
509 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
510
511 // Normalize
512 if (val.X >= Constants.RegionSize)
513 val.X -= Constants.RegionSize;
514 if (val.Y >= Constants.RegionSize)
515 val.Y -= Constants.RegionSize;
516 if (val.X < 0)
517 val.X += Constants.RegionSize;
518 if (val.Y < 0)
519 val.Y += Constants.RegionSize;
520
521 // If it's deleted, crossing was successful
522 if (IsDeleted)
523 {
524 foreach (ScenePresence av in m_linkedAvatars)
525 {
526 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
527
528 av.IsInTransit = true;
529
530 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
531 d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
532 }
533
534 return;
535 }
536 }
537
538 val = AbsolutePosition;
469 } 539 }
470 } 540 }
471 541
@@ -524,6 +594,23 @@ namespace OpenSim.Region.Framework.Scenes
524 } 594 }
525 } 595 }
526 596
597 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
598 {
599 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
600 ScenePresence agent = icon.EndInvoke(iar);
601
602 //// If the cross was successful, this agent is a child agent
603 //if (agent.IsChildAgent)
604 // agent.Reset();
605 //else // Not successful
606 // agent.RestoreInCurrentScene();
607
608 // In any case
609 agent.IsInTransit = false;
610
611 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
612 }
613
527 public override uint LocalId 614 public override uint LocalId
528 { 615 {
529 get { return m_rootPart.LocalId; } 616 get { return m_rootPart.LocalId; }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 9100c29..8a42616 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes
233 private bool m_collisionEventFlag = false; 233 private bool m_collisionEventFlag = false;
234 private object m_collisionEventLock = new Object(); 234 private object m_collisionEventLock = new Object();
235 235
236 private Vector3 m_prevSitOffset;
237
236 protected AvatarAppearance m_appearance; 238 protected AvatarAppearance m_appearance;
237 239
238 public AvatarAppearance Appearance 240 public AvatarAppearance Appearance
@@ -295,13 +297,10 @@ namespace OpenSim.Region.Framework.Scenes
295 /// </summary> 297 /// </summary>
296 public PhysicsActor PhysicsActor { get; private set; } 298 public PhysicsActor PhysicsActor { get; private set; }
297 299
298 private byte m_movementflag; 300 /// <summary>
299 301 /// Record user movement inputs.
300 public byte MovementFlag 302 /// </summary>
301 { 303 public byte MovementFlag { get; private set; }
302 set { m_movementflag = value; }
303 get { return m_movementflag; }
304 }
305 304
306 private bool m_updateflag; 305 private bool m_updateflag;
307 306
@@ -647,6 +646,13 @@ namespace OpenSim.Region.Framework.Scenes
647 } 646 }
648 private uint m_parentID; 647 private uint m_parentID;
649 648
649 public UUID ParentUUID
650 {
651 get { return m_parentUUID; }
652 set { m_parentUUID = value; }
653 }
654 private UUID m_parentUUID = UUID.Zero;
655
650 public float Health 656 public float Health
651 { 657 {
652 get { return m_health; } 658 get { return m_health; }
@@ -868,7 +874,26 @@ namespace OpenSim.Region.Framework.Scenes
868 "[SCENE]: Upgrading child to root agent for {0} in {1}", 874 "[SCENE]: Upgrading child to root agent for {0} in {1}",
869 Name, m_scene.RegionInfo.RegionName); 875 Name, m_scene.RegionInfo.RegionName);
870 876
871 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 877 if (ParentUUID != UUID.Zero)
878 {
879 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
880 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
881 if (part == null)
882 {
883 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
884 }
885 else
886 {
887 part.ParentGroup.AddAvatar(UUID);
888 if (part.SitTargetPosition != Vector3.Zero)
889 part.SitTargetAvatar = UUID;
890 ParentPosition = part.GetWorldPosition();
891 ParentID = part.LocalId;
892 m_pos = m_prevSitOffset;
893 pos = ParentPosition;
894 }
895 ParentUUID = UUID.Zero;
896 }
872 897
873 bool wasChild = IsChildAgent; 898 bool wasChild = IsChildAgent;
874 IsChildAgent = false; 899 IsChildAgent = false;
@@ -881,62 +906,64 @@ namespace OpenSim.Region.Framework.Scenes
881 906
882 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 907 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
883 908
884 // Moved this from SendInitialData to ensure that Appearance is initialized 909 if (ParentID == 0)
885 // before the inventory is processed in MakeRootAgent. This fixes a race condition
886 // related to the handling of attachments
887 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
888 if (m_scene.TestBorderCross(pos, Cardinals.E))
889 { 910 {
890 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 911 // Moved this from SendInitialData to ensure that Appearance is initialized
891 pos.X = crossedBorder.BorderLine.Z - 1; 912 // before the inventory is processed in MakeRootAgent. This fixes a race condition
892 } 913 // related to the handling of attachments
914 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
915 if (m_scene.TestBorderCross(pos, Cardinals.E))
916 {
917 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
918 pos.X = crossedBorder.BorderLine.Z - 1;
919 }
893 920
894 if (m_scene.TestBorderCross(pos, Cardinals.N)) 921 if (m_scene.TestBorderCross(pos, Cardinals.N))
895 { 922 {
896 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 923 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
897 pos.Y = crossedBorder.BorderLine.Z - 1; 924 pos.Y = crossedBorder.BorderLine.Z - 1;
898 } 925 }
899 926
900 CheckAndAdjustLandingPoint(ref pos); 927 CheckAndAdjustLandingPoint(ref pos);
901 928
902 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 929 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
903 { 930 {
904 m_log.WarnFormat( 931 m_log.WarnFormat(
905 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 932 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
906 pos, Name, UUID); 933 pos, Name, UUID);
907 934
908 if (pos.X < 0f) pos.X = 0f; 935 if (pos.X < 0f) pos.X = 0f;
909 if (pos.Y < 0f) pos.Y = 0f; 936 if (pos.Y < 0f) pos.Y = 0f;
910 if (pos.Z < 0f) pos.Z = 0f; 937 if (pos.Z < 0f) pos.Z = 0f;
911 } 938 }
912 939
913 float localAVHeight = 1.56f; 940 float localAVHeight = 1.56f;
914 if (Appearance.AvatarHeight > 0) 941 if (Appearance.AvatarHeight > 0)
915 localAVHeight = Appearance.AvatarHeight; 942 localAVHeight = Appearance.AvatarHeight;
916 943
917 float posZLimit = 0; 944 float posZLimit = 0;
918 945
919 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 946 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
920 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 947 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
921 948
922 float newPosZ = posZLimit + localAVHeight / 2; 949 float newPosZ = posZLimit + localAVHeight / 2;
923 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 950 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
924 { 951 {
925 pos.Z = newPosZ; 952 pos.Z = newPosZ;
926 } 953 }
927 AbsolutePosition = pos; 954 AbsolutePosition = pos;
928 955
929 AddToPhysicalScene(isFlying); 956 AddToPhysicalScene(isFlying);
930 957
931 if (ForceFly) 958 if (ForceFly)
932 { 959 {
933 Flying = true; 960 Flying = true;
934 } 961 }
935 else if (FlyDisabled) 962 else if (FlyDisabled)
936 { 963 {
937 Flying = false; 964 Flying = false;
965 }
938 } 966 }
939
940 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 967 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
941 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 968 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
942 // elsewhere anyway 969 // elsewhere anyway
@@ -954,11 +981,13 @@ namespace OpenSim.Region.Framework.Scenes
954 { 981 {
955 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 982 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
956 // Resume scripts 983 // Resume scripts
957 foreach (SceneObjectGroup sog in m_attachments) 984 Util.FireAndForget(delegate(object x) {
958 { 985 foreach (SceneObjectGroup sog in m_attachments)
959 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 986 {
960 sog.ResumeScripts(); 987 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
961 } 988 sog.ResumeScripts();
989 }
990 });
962 } 991 }
963 } 992 }
964 993
@@ -3122,6 +3151,9 @@ namespace OpenSim.Region.Framework.Scenes
3122 cAgent.AlwaysRun = SetAlwaysRun; 3151 cAgent.AlwaysRun = SetAlwaysRun;
3123 3152
3124 cAgent.Appearance = new AvatarAppearance(Appearance); 3153 cAgent.Appearance = new AvatarAppearance(Appearance);
3154
3155 cAgent.ParentPart = ParentUUID;
3156 cAgent.SitOffset = m_pos;
3125 3157
3126 lock (scriptedcontrols) 3158 lock (scriptedcontrols)
3127 { 3159 {
@@ -3181,6 +3213,8 @@ namespace OpenSim.Region.Framework.Scenes
3181 CameraAtAxis = cAgent.AtAxis; 3213 CameraAtAxis = cAgent.AtAxis;
3182 CameraLeftAxis = cAgent.LeftAxis; 3214 CameraLeftAxis = cAgent.LeftAxis;
3183 m_CameraUpAxis = cAgent.UpAxis; 3215 m_CameraUpAxis = cAgent.UpAxis;
3216 ParentUUID = cAgent.ParentPart;
3217 m_prevSitOffset = cAgent.SitOffset;
3184 3218
3185 // When we get to the point of re-computing neighbors everytime this 3219 // When we get to the point of re-computing neighbors everytime this
3186 // changes, then start using the agent's drawdistance rather than the 3220 // changes, then start using the agent's drawdistance rather than the
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index ba33122..4b80e37 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -1486,7 +1486,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1486 m_SOPXmlProcessors, 1486 m_SOPXmlProcessors,
1487 reader, 1487 reader,
1488 (o, nodeName, e) 1488 (o, nodeName, e)
1489 => m_log.ErrorFormat( 1489 => m_log.DebugFormat(
1490 "[SceneObjectSerializer]: Exception while parsing {0} in object {1} {2}: {3}{4}", 1490 "[SceneObjectSerializer]: Exception while parsing {0} in object {1} {2}: {3}{4}",
1491 ((SceneObjectPart)o).Name, ((SceneObjectPart)o).UUID, nodeName, e.Message, e.StackTrace)); 1491 ((SceneObjectPart)o).Name, ((SceneObjectPart)o).UUID, nodeName, e.Message, e.StackTrace));
1492 1492
@@ -1539,14 +1539,18 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1539 1539
1540 reader.ReadStartElement(name, String.Empty); // Shape 1540 reader.ReadStartElement(name, String.Empty); // Shape
1541 1541
1542 ExternalRepresentationUtils.ExecuteReadProcessors( 1542 errors = ExternalRepresentationUtils.ExecuteReadProcessors(
1543 shape, 1543 shape,
1544 m_ShapeXmlProcessors, 1544 m_ShapeXmlProcessors,
1545 reader, 1545 reader,
1546 (o, nodeName, e) 1546 (o, nodeName, e)
1547 => m_log.ErrorFormat( 1547 =>
1548 "[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}", 1548 {
1549 nodeName, e.Message, e.StackTrace)); 1549 m_log.DebugFormat(
1550 "[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}",
1551 nodeName, e.Message, e.StackTrace);
1552 }
1553 );
1550 1554
1551 reader.ReadEndElement(); // Shape 1555 reader.ReadEndElement(); // Shape
1552 1556
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 1b675a6..8af3652 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -63,9 +63,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
63 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 63 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
64 64
65 // Capability string prefixes 65 // Capability string prefixes
66 private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; 66 private static readonly string m_parcelVoiceInfoRequestPath = "0207/";
67 private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; 67 private static readonly string m_provisionVoiceAccountRequestPath = "0208/";
68 private static readonly string m_chatSessionRequestPath = "0009/"; 68 private static readonly string m_chatSessionRequestPath = "0209/";
69 69
70 // Control info 70 // Control info
71 private static bool m_Enabled = false; 71 private static bool m_Enabled = false;
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
index 42008da..130513d 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Specialized; 31using System.Collections.Specialized;
32using System.Reflection; 32using System.Reflection;
33using System.Threading;
33 34
34using Nwc.XmlRpc; 35using Nwc.XmlRpc;
35 36
@@ -167,6 +168,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
167 168
168 private bool m_debugEnabled = false; 169 private bool m_debugEnabled = false;
169 170
171 private Dictionary<string, bool> m_pendingRequests = new Dictionary<string,bool>();
172
170 private ExpiringCache<string, OSDMap> m_memoryCache; 173 private ExpiringCache<string, OSDMap> m_memoryCache;
171 private int m_cacheTimeout = 30; 174 private int m_cacheTimeout = 30;
172 175
@@ -1348,6 +1351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1348 // Immediately forward the request if the cache is disabled. 1351 // Immediately forward the request if the cache is disabled.
1349 if (m_cacheTimeout == 0) 1352 if (m_cacheTimeout == 0)
1350 { 1353 {
1354 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: cache is disabled");
1351 return WebUtil.PostToService(m_groupsServerURI, requestArgs); 1355 return WebUtil.PostToService(m_groupsServerURI, requestArgs);
1352 } 1356 }
1353 1357
@@ -1355,6 +1359,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1355 if (requestArgs["RequestMethod"] == "RemoveGeneric" 1359 if (requestArgs["RequestMethod"] == "RemoveGeneric"
1356 || requestArgs["RequestMethod"] == "AddGeneric") 1360 || requestArgs["RequestMethod"] == "AddGeneric")
1357 { 1361 {
1362 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache");
1363
1358 // Any and all updates cause the cache to clear 1364 // Any and all updates cause the cache to clear
1359 m_memoryCache.Clear(); 1365 m_memoryCache.Clear();
1360 1366
@@ -1366,18 +1372,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1366 1372
1367 // Create the cache key for the request and see if we have it cached 1373 // Create the cache key for the request and see if we have it cached
1368 string CacheKey = WebUtil.BuildQueryString(requestArgs); 1374 string CacheKey = WebUtil.BuildQueryString(requestArgs);
1369 OSDMap response = null; 1375
1370 if (!m_memoryCache.TryGetValue(CacheKey, out response)) 1376 // This code uses a leader/follower pattern. On a cache miss, the request is added
1377 // to a queue; the first thread to add it to the queue completes the request while
1378 // follow on threads busy wait for the results, this situation seems to happen
1379 // often when checking permissions
1380 while (true)
1371 { 1381 {
1372 // if it wasn't in the cache, pass the request to the Simian Grid Services 1382 OSDMap response = null;
1373 response = WebUtil.PostToService(m_groupsServerURI, requestArgs); 1383 bool firstRequest = false;
1374 1384
1375 // and cache the response 1385 lock (m_memoryCache)
1376 m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); 1386 {
1387 if (m_memoryCache.TryGetValue(CacheKey, out response))
1388 return response;
1389
1390 if (! m_pendingRequests.ContainsKey(CacheKey))
1391 {
1392 m_pendingRequests.Add(CacheKey,true);
1393 firstRequest = true;
1394 }
1395 }
1396
1397 if (firstRequest)
1398 {
1399 // if it wasn't in the cache, pass the request to the Simian Grid Services
1400 try
1401 {
1402 response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1403 }
1404 catch (Exception e)
1405 {
1406 m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey);
1407 }
1408
1409 // and cache the response
1410 lock (m_memoryCache)
1411 {
1412 m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
1413 m_pendingRequests.Remove(CacheKey);
1414 }
1415
1416 return response;
1417 }
1418
1419 Thread.Sleep(50); // waiting for a web request to complete, 50msecs is reasonable
1377 } 1420 }
1378 1421
1379 // return cached response 1422 // if (!m_memoryCache.TryGetValue(CacheKey, out response))
1380 return response; 1423 // {
1424 // m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache");
1425 // Util.PrintCallStack();
1426
1427 // // if it wasn't in the cache, pass the request to the Simian Grid Services
1428 // response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1429
1430 // // and cache the response
1431 // m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
1432 // }
1433
1434 // // return cached response
1435 // return response;
1381 } 1436 }
1382 #endregion 1437 #endregion
1383 1438
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 6803644..d395206 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -96,15 +96,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
96 if (!m_avatars.ContainsKey(agentId)) 96 if (!m_avatars.ContainsKey(agentId))
97 return false; 97 return false;
98 98
99 // Delete existing sp attachments
99 scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); 100 scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
100 101
101 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); 102 // Set new sp appearance. Also sends to clients.
102 sp.Appearance = npcAppearance; 103 scene.RequestModuleInterface<IAvatarFactoryModule>().SetAppearance(sp, new AvatarAppearance(appearance, true));
104
105 // Rez needed sp attachments
103 scene.AttachmentsModule.RezAttachments(sp); 106 scene.AttachmentsModule.RezAttachments(sp);
104 107
105 IAvatarFactoryModule module = scene.RequestModuleInterface<IAvatarFactoryModule>();
106 module.SendAppearance(sp.UUID);
107
108 return true; 108 return true;
109 } 109 }
110 110
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 7c1c046..6d1f41d 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -156,6 +156,22 @@ namespace OpenSim.Region.Physics.OdePlugin
156 internal UUID m_uuid { get; private set; } 156 internal UUID m_uuid { get; private set; }
157 internal bool bad = false; 157 internal bool bad = false;
158 158
159 /// <summary>
160 /// ODE Avatar.
161 /// </summary>
162 /// <param name="avName"></param>
163 /// <param name="parent_scene"></param>
164 /// <param name="pos"></param>
165 /// <param name="size"></param>
166 /// <param name="pid_d"></param>
167 /// <param name="pid_p"></param>
168 /// <param name="capsule_radius"></param>
169 /// <param name="tensor"></param>
170 /// <param name="density">
171 /// Only used right now to return information to LSL. Not actually used to set mass in ODE!
172 /// </param>
173 /// <param name="walk_divisor"></param>
174 /// <param name="rundivisor"></param>
159 public OdeCharacter( 175 public OdeCharacter(
160 String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, 176 String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p,
161 float capsule_radius, float tensor, float density, 177 float capsule_radius, float tensor, float density,
@@ -786,6 +802,10 @@ namespace OpenSim.Region.Physics.OdePlugin
786 Vector3 vec = Vector3.Zero; 802 Vector3 vec = Vector3.Zero;
787 d.Vector3 vel = d.BodyGetLinearVel(Body); 803 d.Vector3 vel = d.BodyGetLinearVel(Body);
788 804
805// m_log.DebugFormat(
806// "[ODE CHARACTER]: Current velocity in Move() is <{0},{1},{2}>, target {3} for {4}",
807// vel.X, vel.Y, vel.Z, _target_velocity, Name);
808
789 float movementdivisor = 1f; 809 float movementdivisor = 1f;
790 810
791 if (!m_alwaysRun) 811 if (!m_alwaysRun)
@@ -884,18 +904,20 @@ namespace OpenSim.Region.Physics.OdePlugin
884 904
885 if (flying) 905 if (flying)
886 { 906 {
907 // This also acts as anti-gravity so that we hover when flying rather than fall.
887 vec.Z = (_target_velocity.Z - vel.Z) * (PID_D); 908 vec.Z = (_target_velocity.Z - vel.Z) * (PID_D);
888 } 909 }
889 } 910 }
890 911
891 if (flying) 912 if (flying)
892 { 913 {
914 // Anti-gravity so that we hover when flying rather than fall.
893 vec.Z += ((-1 * _parent_scene.gravityz) * m_mass); 915 vec.Z += ((-1 * _parent_scene.gravityz) * m_mass);
894 916
895 //Added for auto fly height. Kitto Flora 917 //Added for auto fly height. Kitto Flora
896 //d.Vector3 pos = d.BodyGetPosition(Body); 918 //d.Vector3 pos = d.BodyGetPosition(Body);
897 float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset; 919 float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset;
898 920
899 if (_position.Z < target_altitude) 921 if (_position.Z < target_altitude)
900 { 922 {
901 vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f; 923 vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f;
@@ -921,6 +943,25 @@ namespace OpenSim.Region.Physics.OdePlugin
921 943
922 return; 944 return;
923 } 945 }
946
947 d.Vector3 newVel = d.BodyGetLinearVel(Body);
948 if (newVel.X >= 256 || newVel.X <= 256 || newVel.Y >= 256 || newVel.Y <= 256 || newVel.Z >= 256 || newVel.Z <= 256)
949 {
950// m_log.DebugFormat(
951// "[ODE CHARACTER]: Limiting falling velocity from {0} to {1} for {2}", newVel.Z, -9.8, Name);
952
953 newVel.X = Util.Clamp<float>(newVel.X, -255f, 255f);
954 newVel.Y = Util.Clamp<float>(newVel.Y, -255f, 255f);
955
956 if (!flying)
957 newVel.Z
958 = Util.Clamp<float>(
959 newVel.Z, -_parent_scene.AvatarTerminalVelocity, _parent_scene.AvatarTerminalVelocity);
960 else
961 newVel.Z = Util.Clamp<float>(newVel.Z, -255f, 255f);
962
963 d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z);
964 }
924 } 965 }
925 966
926 /// <summary> 967 /// <summary>
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 4530c09..598530c 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -144,6 +144,8 @@ namespace OpenSim.Region.Physics.OdePlugin
144 public float gravityy = 0f; 144 public float gravityy = 0f;
145 public float gravityz = -9.8f; 145 public float gravityz = -9.8f;
146 146
147 public float AvatarTerminalVelocity { get; set; }
148
147 private float contactsurfacelayer = 0.001f; 149 private float contactsurfacelayer = 0.001f;
148 150
149 private int worldHashspaceLow = -4; 151 private int worldHashspaceLow = -4;
@@ -459,6 +461,15 @@ namespace OpenSim.Region.Physics.OdePlugin
459 gravityy = physicsconfig.GetFloat("world_gravityy", 0f); 461 gravityy = physicsconfig.GetFloat("world_gravityy", 0f);
460 gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); 462 gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f);
461 463
464 float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 54f);
465 AvatarTerminalVelocity = Util.Clamp<float>(avatarTerminalVelocity, 0, 255f);
466 if (AvatarTerminalVelocity != avatarTerminalVelocity)
467 {
468 m_log.WarnFormat(
469 "[ODE SCENE]: avatar_terminal_velocity of {0} is invalid. Clamping to {1}",
470 avatarTerminalVelocity, AvatarTerminalVelocity);
471 }
472
462 worldHashspaceLow = physicsconfig.GetInt("world_hashspace_size_low", -4); 473 worldHashspaceLow = physicsconfig.GetInt("world_hashspace_size_low", -4);
463 worldHashspaceHigh = physicsconfig.GetInt("world_hashspace_size_high", 128); 474 worldHashspaceHigh = physicsconfig.GetInt("world_hashspace_size_high", 128);
464 475
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index b0b1b16..1529140 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2188,7 +2188,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 if (part.ParentGroup.RootPart == part) 2188 if (part.ParentGroup.RootPart == part)
2189 { 2189 {
2190 SceneObjectGroup parent = part.ParentGroup; 2190 SceneObjectGroup parent = part.ParentGroup;
2191 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z)); 2191 Util.FireAndForget(delegate(object x) {
2192 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
2193 });
2192 } 2194 }
2193 else 2195 else
2194 { 2196 {
@@ -7973,7 +7975,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7973 if (part.ParentGroup.RootPart == part) 7975 if (part.ParentGroup.RootPart == part)
7974 { 7976 {
7975 SceneObjectGroup parent = part.ParentGroup; 7977 SceneObjectGroup parent = part.ParentGroup;
7976 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 7978 Util.FireAndForget(delegate(object x) {
7979 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7980 });
7977 } 7981 }
7978 else 7982 else
7979 { 7983 {
@@ -7990,7 +7994,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7990 if (part.ParentGroup.RootPart == part) 7994 if (part.ParentGroup.RootPart == part)
7991 { 7995 {
7992 SceneObjectGroup parent = part.ParentGroup; 7996 SceneObjectGroup parent = part.ParentGroup;
7993 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 7997 Util.FireAndForget(delegate(object x) {
7998 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7999 });
7994 } 8000 }
7995 else 8001 else
7996 { 8002 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 2a0ce44..5c200d6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -450,17 +450,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
450 Vector3 toRegionPos; 450 Vector3 toRegionPos;
451 double dis; 451 double dis;
452 452
453 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence) 453 Action<ScenePresence> senseEntity = new Action<ScenePresence>(presence =>
454 { 454 {
455 if ((ts.type & NPC) == 0 455 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
456 && presence.PresenceType == PresenceType.Npc 456 {
457 && !npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent) 457 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
458 return; 458 if (npcData == null || !npcData.SenseAsAgent)
459 return;
460 }
459 461
460 if ((ts.type & AGENT) == 0 462 if ((ts.type & AGENT) == 0)
461 && (presence.PresenceType == PresenceType.User 463 {
462 || npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent)) 464 if (presence.PresenceType == PresenceType.User)
463 return; 465 {
466 return;
467 }
468 else
469 {
470 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
471 if (npcData != null && npcData.SenseAsAgent)
472 return;
473 }
474 }
464 475
465 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) 476 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
466 return; 477 return;