diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
5 files changed, 362 insertions, 288 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index 8329af0..7f30e5a 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs | |||
@@ -102,7 +102,8 @@ namespace OpenSim.Region.CoreModules.Framework | |||
102 | 102 | ||
103 | public void CreateCaps(UUID agentId) | 103 | public void CreateCaps(UUID agentId) |
104 | { | 104 | { |
105 | if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) | 105 | int flags = m_scene.GetUserFlags(agentId); |
106 | if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) | ||
106 | return; | 107 | return; |
107 | 108 | ||
108 | String capsObjectPath = GetCapsPath(agentId); | 109 | String capsObjectPath = GetCapsPath(agentId); |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 3cb1901..7e72d47 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
148 | 148 | ||
149 | protected virtual void OnNewClient(IClientAPI client) | 149 | protected virtual void OnNewClient(IClientAPI client) |
150 | { | 150 | { |
151 | client.OnTeleportHomeRequest += TeleportHome; | 151 | client.OnTeleportHomeRequest += TriggerTeleportHome; |
152 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; | 152 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; |
153 | } | 153 | } |
154 | 154 | ||
@@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
222 | /// <param name="sp"></param> | 222 | /// <param name="sp"></param> |
223 | /// <param name="position"></param> | 223 | /// <param name="position"></param> |
224 | /// <param name="lookAt"></param> | 224 | /// <param name="lookAt"></param> |
225 | /// <param name="teleportFlags"></param | 225 | /// <param name="teleportFlags"></param> |
226 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) | 226 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) |
227 | { | 227 | { |
228 | m_log.DebugFormat( | 228 | m_log.DebugFormat( |
@@ -266,11 +266,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
266 | position.Z = newPosZ; | 266 | position.Z = newPosZ; |
267 | } | 267 | } |
268 | 268 | ||
269 | if (sp.Flying) | ||
270 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
271 | |||
269 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | 272 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
270 | 273 | ||
271 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 274 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
272 | 275 | ||
273 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 276 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
277 | sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; | ||
274 | sp.Velocity = Vector3.Zero; | 278 | sp.Velocity = Vector3.Zero; |
275 | sp.Teleport(position); | 279 | sp.Teleport(position); |
276 | 280 | ||
@@ -446,8 +450,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
446 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, | 450 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, |
447 | // it's actually doing a lot of work. | 451 | // it's actually doing a lot of work. |
448 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; | 452 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; |
449 | 453 | if (endPoint == null || endPoint.Address == null) | |
450 | if (endPoint.Address == null) | ||
451 | { | 454 | { |
452 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 455 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
453 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | 456 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
@@ -487,6 +490,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
487 | // both regions | 490 | // both regions |
488 | if (sp.ParentID != (uint)0) | 491 | if (sp.ParentID != (uint)0) |
489 | sp.StandUp(); | 492 | sp.StandUp(); |
493 | else if (sp.Flying) | ||
494 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
490 | 495 | ||
491 | // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to | 496 | // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to |
492 | // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). | 497 | // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). |
@@ -664,7 +669,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
664 | // | 669 | // |
665 | // This sleep can be increased if necessary. However, whilst it's active, | 670 | // This sleep can be increased if necessary. However, whilst it's active, |
666 | // an agent cannot teleport back to this region if it has teleported away. | 671 | // an agent cannot teleport back to this region if it has teleported away. |
667 | Thread.Sleep(2000); | 672 | Thread.Sleep(3000); |
668 | 673 | ||
669 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 674 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
670 | } | 675 | } |
@@ -804,7 +809,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
804 | 809 | ||
805 | #region Teleport Home | 810 | #region Teleport Home |
806 | 811 | ||
807 | public virtual void TeleportHome(UUID id, IClientAPI client) | 812 | public virtual void TriggerTeleportHome(UUID id, IClientAPI client) |
813 | { | ||
814 | TeleportHome(id, client); | ||
815 | } | ||
816 | |||
817 | public virtual bool TeleportHome(UUID id, IClientAPI client) | ||
808 | { | 818 | { |
809 | m_log.DebugFormat( | 819 | m_log.DebugFormat( |
810 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | 820 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); |
@@ -814,12 +824,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
814 | 824 | ||
815 | if (uinfo != null) | 825 | if (uinfo != null) |
816 | { | 826 | { |
827 | if (uinfo.HomeRegionID == UUID.Zero) | ||
828 | { | ||
829 | // can't find the Home region: Tell viewer and abort | ||
830 | client.SendTeleportFailed("You don't have a home position set."); | ||
831 | return false; | ||
832 | } | ||
817 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); | 833 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); |
818 | if (regionInfo == null) | 834 | if (regionInfo == null) |
819 | { | 835 | { |
820 | // can't find the Home region: Tell viewer and abort | 836 | // can't find the Home region: Tell viewer and abort |
821 | client.SendTeleportFailed("Your home region could not be found."); | 837 | client.SendTeleportFailed("Your home region could not be found."); |
822 | return; | 838 | return false; |
823 | } | 839 | } |
824 | 840 | ||
825 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", | 841 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", |
@@ -832,10 +848,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
832 | } | 848 | } |
833 | else | 849 | else |
834 | { | 850 | { |
835 | m_log.ErrorFormat( | 851 | // can't find the Home region: Tell viewer and abort |
836 | "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", | 852 | client.SendTeleportFailed("Your home region could not be found."); |
837 | client.Name, client.AgentId); | 853 | return false; |
838 | } | 854 | } |
855 | return true; | ||
839 | } | 856 | } |
840 | 857 | ||
841 | #endregion | 858 | #endregion |
@@ -843,11 +860,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
843 | 860 | ||
844 | #region Agent Crossings | 861 | #region Agent Crossings |
845 | 862 | ||
846 | public bool Cross(ScenePresence agent, bool isFlying) | 863 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) |
847 | { | 864 | { |
848 | Scene scene = agent.Scene; | 865 | version = String.Empty; |
849 | Vector3 pos = agent.AbsolutePosition; | 866 | newpos = new Vector3(pos.X, pos.Y, pos.Z); |
850 | Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); | ||
851 | uint neighbourx = scene.RegionInfo.RegionLocX; | 867 | uint neighbourx = scene.RegionInfo.RegionLocX; |
852 | uint neighboury = scene.RegionInfo.RegionLocY; | 868 | uint neighboury = scene.RegionInfo.RegionLocY; |
853 | const float boundaryDistance = 1.7f; | 869 | const float boundaryDistance = 1.7f; |
@@ -868,52 +884,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
868 | } | 884 | } |
869 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 885 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
870 | { | 886 | { |
871 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 887 | neighboury--; |
872 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 888 | newpos.Y = Constants.RegionSize - enterDistance; |
873 | { | ||
874 | neighboury--; | ||
875 | newpos.Y = Constants.RegionSize - enterDistance; | ||
876 | } | ||
877 | else | ||
878 | { | ||
879 | agent.IsInTransit = true; | ||
880 | |||
881 | neighboury = b.TriggerRegionY; | ||
882 | neighbourx = b.TriggerRegionX; | ||
883 | |||
884 | Vector3 newposition = pos; | ||
885 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
886 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
887 | agent.ControllingClient.SendAgentAlertMessage( | ||
888 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
889 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
890 | return true; | ||
891 | } | ||
892 | } | ||
893 | |||
894 | Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); | ||
895 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | ||
896 | { | ||
897 | neighbourx--; | ||
898 | newpos.X = Constants.RegionSize - enterDistance; | ||
899 | } | ||
900 | else | ||
901 | { | ||
902 | agent.IsInTransit = true; | ||
903 | |||
904 | neighboury = ba.TriggerRegionY; | ||
905 | neighbourx = ba.TriggerRegionX; | ||
906 | |||
907 | Vector3 newposition = pos; | ||
908 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
909 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
910 | agent.ControllingClient.SendAgentAlertMessage( | ||
911 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
912 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
913 | |||
914 | return true; | ||
915 | } | 889 | } |
916 | 890 | ||
891 | neighbourx--; | ||
892 | newpos.X = Constants.RegionSize - enterDistance; | ||
917 | } | 893 | } |
918 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) | 894 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) |
919 | { | 895 | { |
@@ -923,26 +899,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
923 | 899 | ||
924 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 900 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
925 | { | 901 | { |
926 | Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 902 | neighboury--; |
927 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | 903 | newpos.Y = Constants.RegionSize - enterDistance; |
928 | { | ||
929 | neighboury--; | ||
930 | newpos.Y = Constants.RegionSize - enterDistance; | ||
931 | } | ||
932 | else | ||
933 | { | ||
934 | agent.IsInTransit = true; | ||
935 | |||
936 | neighboury = ba.TriggerRegionY; | ||
937 | neighbourx = ba.TriggerRegionX; | ||
938 | Vector3 newposition = pos; | ||
939 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
940 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
941 | agent.ControllingClient.SendAgentAlertMessage( | ||
942 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
943 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
944 | return true; | ||
945 | } | ||
946 | } | 904 | } |
947 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 905 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
948 | { | 906 | { |
@@ -954,25 +912,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
954 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 912 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
955 | { | 913 | { |
956 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 914 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); |
957 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 915 | neighboury--; |
958 | { | 916 | newpos.Y = Constants.RegionSize - enterDistance; |
959 | neighboury--; | ||
960 | newpos.Y = Constants.RegionSize - enterDistance; | ||
961 | } | ||
962 | else | ||
963 | { | ||
964 | agent.IsInTransit = true; | ||
965 | |||
966 | neighboury = b.TriggerRegionY; | ||
967 | neighbourx = b.TriggerRegionX; | ||
968 | Vector3 newposition = pos; | ||
969 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
970 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
971 | agent.ControllingClient.SendAgentAlertMessage( | ||
972 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
973 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
974 | return true; | ||
975 | } | ||
976 | } | 917 | } |
977 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 918 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
978 | { | 919 | { |
@@ -1006,19 +947,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1006 | } | 947 | } |
1007 | */ | 948 | */ |
1008 | 949 | ||
1009 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 950 | xDest = neighbourx; |
951 | yDest = neighboury; | ||
1010 | 952 | ||
1011 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); | 953 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); |
1012 | 954 | ||
955 | ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); | ||
956 | |||
1013 | ExpiringCache<ulong, DateTime> r; | 957 | ExpiringCache<ulong, DateTime> r; |
1014 | DateTime banUntil; | 958 | DateTime banUntil; |
1015 | 959 | ||
1016 | if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) | 960 | if (m_bannedRegions.TryGetValue(agentID, out r)) |
1017 | { | 961 | { |
1018 | if (r.TryGetValue(neighbourHandle, out banUntil)) | 962 | if (r.TryGetValue(neighbourHandle, out banUntil)) |
1019 | { | 963 | { |
1020 | if (DateTime.Now < banUntil) | 964 | if (DateTime.Now < banUntil) |
1021 | return false; | 965 | return null; |
1022 | r.Remove(neighbourHandle); | 966 | r.Remove(neighbourHandle); |
1023 | } | 967 | } |
1024 | } | 968 | } |
@@ -1030,28 +974,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1030 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 974 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
1031 | 975 | ||
1032 | string reason; | 976 | string reason; |
1033 | string version; | 977 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) |
1034 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) | ||
1035 | { | 978 | { |
1036 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
1037 | if (r == null) | 979 | if (r == null) |
1038 | { | 980 | { |
1039 | r = new ExpiringCache<ulong, DateTime>(); | 981 | r = new ExpiringCache<ulong, DateTime>(); |
1040 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 982 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1041 | 983 | ||
1042 | m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); | 984 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); |
1043 | } | 985 | } |
1044 | else | 986 | else |
1045 | { | 987 | { |
1046 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 988 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1047 | } | 989 | } |
990 | return null; | ||
991 | } | ||
992 | |||
993 | return neighbourRegion; | ||
994 | } | ||
995 | |||
996 | public bool Cross(ScenePresence agent, bool isFlying) | ||
997 | { | ||
998 | uint x; | ||
999 | uint y; | ||
1000 | Vector3 newpos; | ||
1001 | string version; | ||
1002 | |||
1003 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); | ||
1004 | if (neighbourRegion == null) | ||
1005 | { | ||
1006 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
1048 | return false; | 1007 | return false; |
1049 | } | 1008 | } |
1050 | 1009 | ||
1051 | agent.IsInTransit = true; | 1010 | agent.IsInTransit = true; |
1052 | 1011 | ||
1053 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | 1012 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; |
1054 | d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); | 1013 | d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); |
1055 | 1014 | ||
1056 | return true; | 1015 | return true; |
1057 | } | 1016 | } |
@@ -1120,44 +1079,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1120 | icon.EndInvoke(iar); | 1079 | icon.EndInvoke(iar); |
1121 | } | 1080 | } |
1122 | 1081 | ||
1123 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); | 1082 | public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion) |
1083 | { | ||
1084 | if (neighbourRegion == null) | ||
1085 | return false; | ||
1086 | |||
1087 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1088 | |||
1089 | agent.RemoveFromPhysicalScene(); | ||
1090 | |||
1091 | return true; | ||
1092 | } | ||
1124 | 1093 | ||
1125 | /// <summary> | 1094 | /// <summary> |
1126 | /// This Closes child agents on neighbouring regions | 1095 | /// This Closes child agents on neighbouring regions |
1127 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 1096 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
1128 | /// </summary> | 1097 | /// </summary> |
1129 | protected ScenePresence CrossAgentToNewRegionAsync( | 1098 | public ScenePresence CrossAgentToNewRegionAsync( |
1130 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | 1099 | ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1131 | bool isFlying, string version) | 1100 | bool isFlying, string version) |
1132 | { | 1101 | { |
1133 | if (neighbourRegion == null) | 1102 | if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) |
1134 | return agent; | 1103 | return agent; |
1135 | 1104 | ||
1136 | try | 1105 | if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) |
1137 | { | 1106 | return agent; |
1138 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1139 | |||
1140 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | ||
1141 | |||
1142 | m_log.DebugFormat( | ||
1143 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", | ||
1144 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | ||
1145 | |||
1146 | Scene m_scene = agent.Scene; | ||
1147 | |||
1148 | if (!agent.ValidateAttachments()) | ||
1149 | m_log.DebugFormat( | ||
1150 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
1151 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
1152 | |||
1153 | pos = pos + agent.Velocity; | ||
1154 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1155 | 1107 | ||
1156 | agent.RemoveFromPhysicalScene(); | 1108 | CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); |
1109 | return agent; | ||
1110 | } | ||
1157 | 1111 | ||
1112 | public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) | ||
1113 | { | ||
1114 | try | ||
1115 | { | ||
1158 | AgentData cAgent = new AgentData(); | 1116 | AgentData cAgent = new AgentData(); |
1159 | agent.CopyTo(cAgent); | 1117 | agent.CopyTo(cAgent); |
1160 | cAgent.Position = pos; | 1118 | cAgent.Position = pos + agent.Velocity; |
1161 | if (isFlying) | 1119 | if (isFlying) |
1162 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | 1120 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; |
1163 | 1121 | ||
@@ -1167,7 +1125,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1167 | // Beyond this point, extra cleanup is needed beyond removing transit state | 1125 | // Beyond this point, extra cleanup is needed beyond removing transit state |
1168 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); | 1126 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); |
1169 | 1127 | ||
1170 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | 1128 | if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) |
1171 | { | 1129 | { |
1172 | // region doesn't take it | 1130 | // region doesn't take it |
1173 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | 1131 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
@@ -1176,93 +1134,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1176 | agent.AddToPhysicalScene(isFlying); | 1134 | agent.AddToPhysicalScene(isFlying); |
1177 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1135 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
1178 | 1136 | ||
1179 | return agent; | 1137 | return false; |
1180 | } | 1138 | } |
1181 | 1139 | ||
1182 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); | 1140 | } |
1183 | agent.ControllingClient.RequestClientInfo(); | 1141 | catch (Exception e) |
1142 | { | ||
1143 | m_log.ErrorFormat( | ||
1144 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | ||
1145 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | ||
1184 | 1146 | ||
1185 | //m_log.Debug("BEFORE CROSS"); | 1147 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. |
1186 | //Scene.DumpChildrenSeeds(UUID); | 1148 | return false; |
1187 | //DumpKnownRegions(); | 1149 | } |
1188 | string agentcaps; | ||
1189 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1190 | { | ||
1191 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
1192 | neighbourRegion.RegionHandle); | ||
1193 | return agent; | ||
1194 | } | ||
1195 | // No turning back | ||
1196 | agent.IsChildAgent = true; | ||
1197 | 1150 | ||
1198 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); | 1151 | return true; |
1152 | } | ||
1199 | 1153 | ||
1200 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | 1154 | public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1155 | bool isFlying, string version) | ||
1156 | { | ||
1157 | agent.ControllingClient.RequestClientInfo(); | ||
1201 | 1158 | ||
1202 | if (m_eqModule != null) | 1159 | string agentcaps; |
1203 | { | 1160 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) |
1204 | m_eqModule.CrossRegion( | 1161 | { |
1205 | neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | 1162 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", |
1206 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | 1163 | neighbourRegion.RegionHandle); |
1207 | } | 1164 | return; |
1208 | else | 1165 | } |
1209 | { | ||
1210 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1211 | capsPath); | ||
1212 | } | ||
1213 | 1166 | ||
1214 | // SUCCESS! | 1167 | // No turning back |
1215 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); | 1168 | agent.IsChildAgent = true; |
1216 | 1169 | ||
1217 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. | 1170 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); |
1218 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | ||
1219 | 1171 | ||
1220 | agent.MakeChildAgent(); | 1172 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); |
1173 | |||
1174 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1175 | |||
1176 | if (m_eqModule != null) | ||
1177 | { | ||
1178 | m_eqModule.CrossRegion( | ||
1179 | neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | ||
1180 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | ||
1181 | } | ||
1182 | else | ||
1183 | { | ||
1184 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1185 | capsPath); | ||
1186 | } | ||
1221 | 1187 | ||
1222 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | 1188 | // SUCCESS! |
1223 | // but not sure yet what the side effects would be. | 1189 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); |
1224 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1225 | 1190 | ||
1226 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1191 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. |
1227 | agent.SendOtherAgentsAvatarDataToMe(); | 1192 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
1228 | agent.SendOtherAgentsAppearanceToMe(); | ||
1229 | 1193 | ||
1230 | // Backwards compatibility. Best effort | 1194 | agent.MakeChildAgent(); |
1231 | if (version == "Unknown" || version == string.Empty) | ||
1232 | { | ||
1233 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1234 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1235 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1236 | } | ||
1237 | 1195 | ||
1238 | // Next, let's close the child agent connections that are too far away. | 1196 | // FIXME: Possibly this should occur lower down after other commands to close other agents, |
1239 | agent.CloseChildAgents(neighbourx, neighboury); | 1197 | // but not sure yet what the side effects would be. |
1198 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1240 | 1199 | ||
1241 | AgentHasMovedAway(agent, false); | 1200 | // now we have a child agent in this region. Request all interesting data about other (root) agents |
1201 | agent.SendOtherAgentsAvatarDataToMe(); | ||
1202 | agent.SendOtherAgentsAppearanceToMe(); | ||
1242 | 1203 | ||
1243 | // // the user may change their profile information in other region, | 1204 | // Backwards compatibility. Best effort |
1244 | // // so the userinfo in UserProfileCache is not reliable any more, delete it | 1205 | if (version == "Unknown" || version == string.Empty) |
1245 | // // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1246 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1247 | // { | ||
1248 | // m_log.DebugFormat( | ||
1249 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1250 | // } | ||
1251 | |||
1252 | //m_log.Debug("AFTER CROSS"); | ||
1253 | //Scene.DumpChildrenSeeds(UUID); | ||
1254 | //DumpKnownRegions(); | ||
1255 | } | ||
1256 | catch (Exception e) | ||
1257 | { | 1206 | { |
1258 | m_log.ErrorFormat( | 1207 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); |
1259 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | 1208 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback |
1260 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | 1209 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); |
1261 | |||
1262 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. | ||
1263 | } | 1210 | } |
1264 | 1211 | ||
1265 | return agent; | 1212 | // Next, let's close the child agent connections that are too far away. |
1213 | uint neighbourx; | ||
1214 | uint neighboury; | ||
1215 | |||
1216 | Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury); | ||
1217 | |||
1218 | neighbourx /= Constants.RegionSize; | ||
1219 | neighboury /= Constants.RegionSize; | ||
1220 | |||
1221 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1222 | |||
1223 | AgentHasMovedAway(agent, false); | ||
1224 | |||
1225 | // the user may change their profile information in other region, | ||
1226 | // so the userinfo in UserProfileCache is not reliable any more, delete it | ||
1227 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1228 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1229 | // { | ||
1230 | // m_log.DebugFormat( | ||
1231 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1232 | // } | ||
1233 | |||
1234 | //m_log.Debug("AFTER CROSS"); | ||
1235 | //Scene.DumpChildrenSeeds(UUID); | ||
1236 | //DumpKnownRegions(); | ||
1237 | |||
1238 | return; | ||
1266 | } | 1239 | } |
1267 | 1240 | ||
1268 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | 1241 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) |
@@ -1333,10 +1306,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1333 | agent.Id0 = currentAgentCircuit.Id0; | 1306 | agent.Id0 = currentAgentCircuit.Id0; |
1334 | } | 1307 | } |
1335 | 1308 | ||
1336 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | 1309 | IPEndPoint external = region.ExternalEndPoint; |
1337 | d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, | 1310 | if (external != null) |
1311 | { | ||
1312 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
1313 | d.BeginInvoke(sp, agent, region, external, true, | ||
1338 | InformClientOfNeighbourCompleted, | 1314 | InformClientOfNeighbourCompleted, |
1339 | d); | 1315 | d); |
1316 | } | ||
1340 | } | 1317 | } |
1341 | #endregion | 1318 | #endregion |
1342 | 1319 | ||
@@ -1917,27 +1894,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1917 | Utils.LongToUInts(newRegionHandle, out x, out y); | 1894 | Utils.LongToUInts(newRegionHandle, out x, out y); |
1918 | GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 1895 | GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
1919 | 1896 | ||
1920 | if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) | 1897 | if (destination != null) |
1921 | { | 1898 | { |
1922 | m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); | 1899 | if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) |
1900 | return; // we did it | ||
1901 | } | ||
1923 | 1902 | ||
1924 | // We are going to move the object back to the old position so long as the old position | 1903 | // no one or failed lets go back and tell physics to go on |
1925 | // is in the region | 1904 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f); |
1926 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); | 1905 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f); |
1927 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); | 1906 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f); |
1928 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f); | ||
1929 | 1907 | ||
1930 | grp.RootPart.GroupPosition = oldGroupPosition; | 1908 | grp.AbsolutePosition = oldGroupPosition; |
1909 | grp.Velocity = Vector3.Zero; | ||
1931 | 1910 | ||
1932 | // Need to turn off the physics flags, otherwise the object will continue to attempt to | 1911 | if (grp.RootPart.PhysActor != null) |
1933 | // move out of the region creating an infinite loop of failed attempts to cross | 1912 | grp.RootPart.PhysActor.CrossingFailure(); |
1934 | grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); | ||
1935 | 1913 | ||
1936 | grp.ScheduleGroupForFullUpdate(); | 1914 | if (grp.RootPart.KeyframeMotion != null) |
1937 | } | 1915 | grp.RootPart.KeyframeMotion.CrossingFailure(); |
1916 | |||
1917 | grp.ScheduleGroupForFullUpdate(); | ||
1938 | } | 1918 | } |
1939 | 1919 | ||
1940 | 1920 | ||
1921 | |||
1941 | /// <summary> | 1922 | /// <summary> |
1942 | /// Move the given scene object into a new region | 1923 | /// Move the given scene object into a new region |
1943 | /// </summary> | 1924 | /// </summary> |
@@ -1988,17 +1969,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1988 | grp, e); | 1969 | grp, e); |
1989 | } | 1970 | } |
1990 | } | 1971 | } |
1972 | /* | ||
1973 | * done on caller ( not in attachments crossing for now) | ||
1991 | else | 1974 | else |
1992 | { | 1975 | { |
1976 | |||
1993 | if (!grp.IsDeleted) | 1977 | if (!grp.IsDeleted) |
1994 | { | 1978 | { |
1995 | PhysicsActor pa = grp.RootPart.PhysActor; | 1979 | PhysicsActor pa = grp.RootPart.PhysActor; |
1996 | if (pa != null) | 1980 | if (pa != null) |
1981 | { | ||
1997 | pa.CrossingFailure(); | 1982 | pa.CrossingFailure(); |
1983 | if (grp.RootPart.KeyframeMotion != null) | ||
1984 | { | ||
1985 | // moved to KeyframeMotion.CrossingFailure | ||
1986 | // grp.RootPart.Velocity = Vector3.Zero; | ||
1987 | grp.RootPart.KeyframeMotion.CrossingFailure(); | ||
1988 | // grp.SendGroupRootTerseUpdate(); | ||
1989 | } | ||
1990 | } | ||
1998 | } | 1991 | } |
1999 | 1992 | ||
2000 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); | 1993 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); |
2001 | } | 1994 | } |
1995 | */ | ||
2002 | } | 1996 | } |
2003 | else | 1997 | else |
2004 | { | 1998 | { |
@@ -2083,4 +2077,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2083 | #endregion | 2077 | #endregion |
2084 | 2078 | ||
2085 | } | 2079 | } |
2086 | } \ No newline at end of file | 2080 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs index d0cab49..70dd1bc 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs | |||
@@ -218,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
218 | id, m_mod.Scene.RegionInfo.RegionName, currentState)); | 218 | id, m_mod.Scene.RegionInfo.RegionName, currentState)); |
219 | } | 219 | } |
220 | 220 | ||
221 | int count = 200; | 221 | int count = 400; |
222 | 222 | ||
223 | // There should be no race condition here since no other code should be removing the agent transfer or | 223 | // There should be no race condition here since no other code should be removing the agent transfer or |
224 | // changing the state to another other than Transferring => ReceivedAtDestination. | 224 | // changing the state to another other than Transferring => ReceivedAtDestination. |
@@ -266,4 +266,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
266 | } | 266 | } |
267 | } | 267 | } |
268 | } | 268 | } |
269 | } \ No newline at end of file | 269 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 41ca13b..f3a0b01 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -184,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
184 | 184 | ||
185 | protected override void OnNewClient(IClientAPI client) | 185 | protected override void OnNewClient(IClientAPI client) |
186 | { | 186 | { |
187 | client.OnTeleportHomeRequest += TeleportHome; | 187 | client.OnTeleportHomeRequest += TriggerTeleportHome; |
188 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; | 188 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; |
189 | client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); | 189 | client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); |
190 | } | 190 | } |
@@ -291,6 +291,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
291 | return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); | 291 | return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); |
292 | } | 292 | } |
293 | 293 | ||
294 | public void TriggerTeleportHome(UUID id, IClientAPI client) | ||
295 | { | ||
296 | TeleportHome(id, client); | ||
297 | } | ||
298 | |||
294 | protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) | 299 | protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) |
295 | { | 300 | { |
296 | reason = "Please wear your grid's allowed appearance before teleporting to another grid"; | 301 | reason = "Please wear your grid's allowed appearance before teleporting to another grid"; |
@@ -409,7 +414,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
409 | // return base.UpdateAgent(reg, finalDestination, agentData, sp); | 414 | // return base.UpdateAgent(reg, finalDestination, agentData, sp); |
410 | //} | 415 | //} |
411 | 416 | ||
412 | public override void TeleportHome(UUID id, IClientAPI client) | 417 | public override bool TeleportHome(UUID id, IClientAPI client) |
413 | { | 418 | { |
414 | m_log.DebugFormat( | 419 | m_log.DebugFormat( |
415 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | 420 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); |
@@ -420,8 +425,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
420 | { | 425 | { |
421 | // local grid user | 426 | // local grid user |
422 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); | 427 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); |
423 | base.TeleportHome(id, client); | 428 | return base.TeleportHome(id, client); |
424 | return; | ||
425 | } | 429 | } |
426 | 430 | ||
427 | // Foreign user wants to go home | 431 | // Foreign user wants to go home |
@@ -431,7 +435,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
431 | { | 435 | { |
432 | client.SendTeleportFailed("Your information has been lost"); | 436 | client.SendTeleportFailed("Your information has been lost"); |
433 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); | 437 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); |
434 | return; | 438 | return false; |
435 | } | 439 | } |
436 | 440 | ||
437 | IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); | 441 | IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); |
@@ -441,7 +445,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
441 | { | 445 | { |
442 | client.SendTeleportFailed("Your home region could not be found"); | 446 | client.SendTeleportFailed("Your home region could not be found"); |
443 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); | 447 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); |
444 | return; | 448 | return false; |
445 | } | 449 | } |
446 | 450 | ||
447 | ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); | 451 | ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); |
@@ -449,7 +453,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
449 | { | 453 | { |
450 | client.SendTeleportFailed("Internal error"); | 454 | client.SendTeleportFailed("Internal error"); |
451 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); | 455 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); |
452 | return; | 456 | return false; |
453 | } | 457 | } |
454 | 458 | ||
455 | GridRegion homeGatekeeper = MakeRegion(aCircuit); | 459 | GridRegion homeGatekeeper = MakeRegion(aCircuit); |
@@ -457,9 +461,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
457 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", | 461 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", |
458 | aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); | 462 | aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); |
459 | 463 | ||
460 | DoTeleport( | 464 | DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); |
461 | sp, homeGatekeeper, finalDestination, | 465 | return true; |
462 | position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); | ||
463 | } | 466 | } |
464 | 467 | ||
465 | /// <summary> | 468 | /// <summary> |
@@ -586,4 +589,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
586 | return region; | 589 | return region; |
587 | } | 590 | } |
588 | } | 591 | } |
589 | } \ No newline at end of file | 592 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 8b7c16e..6e5a4a5 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -182,44 +182,49 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
182 | if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) | 182 | if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) |
183 | return; | 183 | return; |
184 | 184 | ||
185 | if (transactionID == UUID.Zero) | 185 | InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId); |
186 | InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f); | ||
187 | |||
188 | if (folder == null || folder.Owner != remoteClient.AgentId) | ||
189 | return; | ||
190 | |||
191 | if (transactionID != UUID.Zero) | ||
186 | { | 192 | { |
187 | ScenePresence presence; | 193 | IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; |
188 | if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 194 | if (agentTransactions != null) |
189 | { | 195 | { |
190 | byte[] data = null; | 196 | if (agentTransactions.HandleItemCreationFromTransaction( |
197 | remoteClient, transactionID, folderID, callbackID, description, | ||
198 | name, invType, assetType, wearableType, nextOwnerMask)) | ||
199 | return; | ||
200 | } | ||
201 | } | ||
191 | 202 | ||
192 | if (invType == (sbyte)InventoryType.Landmark && presence != null) | 203 | ScenePresence presence; |
193 | { | 204 | if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) |
194 | string suffix = string.Empty, prefix = string.Empty; | 205 | { |
195 | string strdata = GenerateLandmark(presence, out prefix, out suffix); | 206 | byte[] data = null; |
196 | data = Encoding.ASCII.GetBytes(strdata); | ||
197 | name = prefix + name; | ||
198 | description += suffix; | ||
199 | } | ||
200 | 207 | ||
201 | AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); | 208 | if (invType == (sbyte)InventoryType.Landmark && presence != null) |
202 | m_Scene.AssetService.Store(asset); | ||
203 | m_Scene.CreateNewInventoryItem( | ||
204 | remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, | ||
205 | name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate); | ||
206 | } | ||
207 | else | ||
208 | { | 209 | { |
209 | m_log.ErrorFormat( | 210 | string suffix = string.Empty, prefix = string.Empty; |
210 | "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", | 211 | string strdata = GenerateLandmark(presence, out prefix, out suffix); |
211 | remoteClient.AgentId); | 212 | data = Encoding.ASCII.GetBytes(strdata); |
213 | name = prefix + name; | ||
214 | description += suffix; | ||
212 | } | 215 | } |
216 | |||
217 | AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); | ||
218 | m_Scene.AssetService.Store(asset); | ||
219 | m_Scene.CreateNewInventoryItem( | ||
220 | remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, | ||
221 | name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID); | ||
213 | } | 222 | } |
214 | else | 223 | else |
215 | { | 224 | { |
216 | IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; | 225 | m_log.ErrorFormat( |
217 | if (agentTransactions != null) | 226 | "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", |
218 | { | 227 | remoteClient.AgentId); |
219 | agentTransactions.HandleItemCreationFromTransaction( | ||
220 | remoteClient, transactionID, folderID, callbackID, description, | ||
221 | name, invType, assetType, wearableType, nextOwnerMask); | ||
222 | } | ||
223 | } | 228 | } |
224 | } | 229 | } |
225 | 230 | ||
@@ -356,6 +361,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
356 | 361 | ||
357 | foreach (SceneObjectGroup objectGroup in objlist) | 362 | foreach (SceneObjectGroup objectGroup in objlist) |
358 | { | 363 | { |
364 | if (objectGroup.RootPart.KeyframeMotion != null) | ||
365 | objectGroup.RootPart.KeyframeMotion.Stop(); | ||
366 | objectGroup.RootPart.SetForce(Vector3.Zero); | ||
367 | objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false); | ||
368 | objectGroup.RootPart.KeyframeMotion = null; | ||
369 | |||
359 | Vector3 inventoryStoredPosition = new Vector3 | 370 | Vector3 inventoryStoredPosition = new Vector3 |
360 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | 371 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) |
361 | ? 250 | 372 | ? 250 |
@@ -366,9 +377,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
366 | : objectGroup.AbsolutePosition.Y, | 377 | : objectGroup.AbsolutePosition.Y, |
367 | objectGroup.AbsolutePosition.Z); | 378 | objectGroup.AbsolutePosition.Z); |
368 | 379 | ||
380 | Quaternion inventoryStoredRotation = objectGroup.GroupRotation; | ||
369 | originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; | 381 | originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; |
370 | 382 | ||
383 | // Restore attachment data after trip through the sim | ||
384 | if (objectGroup.RootPart.AttachPoint > 0) | ||
385 | { | ||
386 | inventoryStoredPosition = objectGroup.RootPart.AttachOffset; | ||
387 | inventoryStoredRotation = objectGroup.RootPart.AttachRotation; | ||
388 | } | ||
389 | objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; | ||
390 | |||
371 | objectGroup.AbsolutePosition = inventoryStoredPosition; | 391 | objectGroup.AbsolutePosition = inventoryStoredPosition; |
392 | objectGroup.RootPart.RotationOffset = inventoryStoredRotation; | ||
372 | 393 | ||
373 | // Make sure all bits but the ones we want are clear | 394 | // Make sure all bits but the ones we want are clear |
374 | // on take. | 395 | // on take. |
@@ -486,8 +507,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
486 | IClientAPI remoteClient) | 507 | IClientAPI remoteClient) |
487 | { | 508 | { |
488 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; | 509 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; |
510 | // For the porposes of inventory, an object is modify if the prims | ||
511 | // are modify. This allows renaming an object that contains no | ||
512 | // mod items. | ||
489 | foreach (SceneObjectGroup grp in objsForEffectivePermissions) | 513 | foreach (SceneObjectGroup grp in objsForEffectivePermissions) |
490 | effectivePerms &= grp.GetEffectivePermissions(); | 514 | { |
515 | uint groupPerms = grp.GetEffectivePermissions(true); | ||
516 | if ((grp.RootPart.BaseMask & (uint)PermissionMask.Modify) != 0) | ||
517 | groupPerms |= (uint)PermissionMask.Modify; | ||
518 | |||
519 | effectivePerms &= groupPerms; | ||
520 | } | ||
491 | effectivePerms |= (uint)PermissionMask.Move; | 521 | effectivePerms |= (uint)PermissionMask.Move; |
492 | 522 | ||
493 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | 523 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) |
@@ -666,7 +696,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
666 | if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) | 696 | if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) |
667 | { | 697 | { |
668 | InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); | 698 | InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); |
669 | folder = m_Scene.InventoryService.GetFolder(f); | 699 | if (f != null) |
700 | folder = m_Scene.InventoryService.GetFolder(f); | ||
670 | } | 701 | } |
671 | } | 702 | } |
672 | 703 | ||
@@ -696,16 +727,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
696 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | 727 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) |
697 | { | 728 | { |
698 | // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); | 729 | // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); |
699 | |||
700 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | 730 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); |
701 | item = m_Scene.InventoryService.GetItem(item); | 731 | item = m_Scene.InventoryService.GetItem(item); |
702 | 732 | ||
703 | if (item == null) | 733 | if (item == null) |
704 | { | 734 | { |
705 | m_log.WarnFormat( | ||
706 | "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()", | ||
707 | itemID, remoteClient.Name); | ||
708 | |||
709 | return null; | 735 | return null; |
710 | } | 736 | } |
711 | 737 | ||
@@ -756,6 +782,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
756 | if (e == null || attachment) // Single | 782 | if (e == null || attachment) // Single |
757 | { | 783 | { |
758 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 784 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
785 | if (!attachment) | ||
786 | { | ||
787 | g.RootPart.AttachPoint = g.RootPart.Shape.State; | ||
788 | g.RootPart.AttachOffset = g.AbsolutePosition; | ||
789 | g.RootPart.AttachRotation = g.GroupRotation; | ||
790 | g.RootPart.Shape.State = 0; | ||
791 | } | ||
759 | 792 | ||
760 | objlist.Add(g); | 793 | objlist.Add(g); |
761 | veclist.Add(new Vector3(0, 0, 0)); | 794 | veclist.Add(new Vector3(0, 0, 0)); |
@@ -785,6 +818,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
785 | foreach (XmlNode n in groups) | 818 | foreach (XmlNode n in groups) |
786 | { | 819 | { |
787 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | 820 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); |
821 | g.RootPart.AttachPoint = g.RootPart.Shape.State; | ||
822 | g.RootPart.AttachOffset = g.AbsolutePosition; | ||
823 | g.RootPart.AttachRotation = g.GroupRotation; | ||
824 | g.RootPart.Shape.State = 0; | ||
788 | 825 | ||
789 | objlist.Add(g); | 826 | objlist.Add(g); |
790 | XmlElement el = (XmlElement)n; | 827 | XmlElement el = (XmlElement)n; |
@@ -804,12 +841,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
804 | } | 841 | } |
805 | } | 842 | } |
806 | 843 | ||
844 | int primcount = 0; | ||
845 | foreach (SceneObjectGroup g in objlist) | ||
846 | primcount += g.PrimCount; | ||
847 | |||
848 | if (!m_Scene.Permissions.CanRezObject( | ||
849 | primcount, remoteClient.AgentId, pos) | ||
850 | && !attachment) | ||
851 | { | ||
852 | // The client operates in no fail mode. It will | ||
853 | // have already removed the item from the folder | ||
854 | // if it's no copy. | ||
855 | // Put it back if it's not an attachment | ||
856 | // | ||
857 | if (item != null) | ||
858 | { | ||
859 | if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) | ||
860 | remoteClient.SendBulkUpdateInventory(item); | ||
861 | } | ||
862 | |||
863 | return null; | ||
864 | } | ||
865 | |||
807 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) | 866 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) |
808 | return null; | 867 | return null; |
809 | 868 | ||
810 | for (int i = 0; i < objlist.Count; i++) | 869 | for (int i = 0; i < objlist.Count; i++) |
811 | { | 870 | { |
812 | group = objlist[i]; | 871 | group = objlist[i]; |
872 | SceneObjectPart rootPart = group.RootPart; | ||
813 | 873 | ||
814 | // m_log.DebugFormat( | 874 | // m_log.DebugFormat( |
815 | // "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", | 875 | // "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", |
@@ -870,8 +930,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
870 | 930 | ||
871 | if (!attachment) | 931 | if (!attachment) |
872 | { | 932 | { |
873 | SceneObjectPart rootPart = group.RootPart; | ||
874 | |||
875 | if (rootPart.Shape.PCode == (byte)PCode.Prim) | 933 | if (rootPart.Shape.PCode == (byte)PCode.Prim) |
876 | group.ClearPartAttachmentData(); | 934 | group.ClearPartAttachmentData(); |
877 | 935 | ||
@@ -889,6 +947,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
889 | // remoteClient.Name); | 947 | // remoteClient.Name); |
890 | } | 948 | } |
891 | 949 | ||
950 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | ||
951 | |||
892 | if (item != null) | 952 | if (item != null) |
893 | DoPostRezWhenFromItem(item, attachment); | 953 | DoPostRezWhenFromItem(item, attachment); |
894 | 954 | ||
@@ -967,8 +1027,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
967 | { | 1027 | { |
968 | rootPart.Name = item.Name; | 1028 | rootPart.Name = item.Name; |
969 | rootPart.Description = item.Description; | 1029 | rootPart.Description = item.Description; |
970 | rootPart.ObjectSaleType = item.SaleType; | 1030 | if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) |
971 | rootPart.SalePrice = item.SalePrice; | 1031 | { |
1032 | rootPart.ObjectSaleType = item.SaleType; | ||
1033 | rootPart.SalePrice = item.SalePrice; | ||
1034 | } | ||
972 | } | 1035 | } |
973 | 1036 | ||
974 | so.FromFolderID = item.Folder; | 1037 | so.FromFolderID = item.Folder; |
@@ -978,7 +1041,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
978 | // rootPart.OwnerID, item.Owner, item.CurrentPermissions); | 1041 | // rootPart.OwnerID, item.Owner, item.CurrentPermissions); |
979 | 1042 | ||
980 | if ((rootPart.OwnerID != item.Owner) || | 1043 | if ((rootPart.OwnerID != item.Owner) || |
981 | (item.CurrentPermissions & 16) != 0) | 1044 | (item.CurrentPermissions & 16) != 0 || |
1045 | (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) | ||
982 | { | 1046 | { |
983 | //Need to kill the for sale here | 1047 | //Need to kill the for sale here |
984 | rootPart.ObjectSaleType = 0; | 1048 | rootPart.ObjectSaleType = 0; |
@@ -988,31 +1052,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
988 | { | 1052 | { |
989 | foreach (SceneObjectPart part in so.Parts) | 1053 | foreach (SceneObjectPart part in so.Parts) |
990 | { | 1054 | { |
991 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) | ||
992 | { | ||
993 | part.EveryoneMask = item.EveryOnePermissions; | ||
994 | part.NextOwnerMask = item.NextPermissions; | ||
995 | } | ||
996 | part.GroupMask = 0; // DO NOT propagate here | 1055 | part.GroupMask = 0; // DO NOT propagate here |
1056 | |||
1057 | part.LastOwnerID = part.OwnerID; | ||
1058 | part.OwnerID = item.Owner; | ||
1059 | part.Inventory.ChangeInventoryOwner(item.Owner); | ||
997 | } | 1060 | } |
998 | 1061 | ||
999 | so.ApplyNextOwnerPermissions(); | 1062 | so.ApplyNextOwnerPermissions(); |
1063 | |||
1064 | // In case the user has changed flags on a received item | ||
1065 | // we have to apply those changes after the slam. Else we | ||
1066 | // get a net loss of permissions | ||
1067 | foreach (SceneObjectPart part in so.Parts) | ||
1068 | { | ||
1069 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) | ||
1070 | { | ||
1071 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | ||
1072 | part.EveryoneMask = item.EveryOnePermissions & part.BaseMask; | ||
1073 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | ||
1074 | part.NextOwnerMask = item.NextPermissions & part.BaseMask; | ||
1075 | } | ||
1076 | } | ||
1000 | } | 1077 | } |
1001 | } | 1078 | } |
1002 | 1079 | else | |
1003 | foreach (SceneObjectPart part in so.Parts) | ||
1004 | { | 1080 | { |
1005 | part.FromUserInventoryItemID = fromUserInventoryItemId; | 1081 | foreach (SceneObjectPart part in so.Parts) |
1006 | |||
1007 | if ((part.OwnerID != item.Owner) || | ||
1008 | (item.CurrentPermissions & 16) != 0) | ||
1009 | { | 1082 | { |
1010 | part.Inventory.ChangeInventoryOwner(item.Owner); | 1083 | part.FromUserInventoryItemID = fromUserInventoryItemId; |
1011 | part.GroupMask = 0; // DO NOT propagate here | 1084 | |
1085 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | ||
1086 | part.EveryoneMask = item.EveryOnePermissions; | ||
1087 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | ||
1088 | part.NextOwnerMask = item.NextPermissions; | ||
1089 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | ||
1090 | part.GroupMask = item.GroupPermissions; | ||
1012 | } | 1091 | } |
1013 | |||
1014 | part.EveryoneMask = item.EveryOnePermissions; | ||
1015 | part.NextOwnerMask = item.NextPermissions; | ||
1016 | } | 1092 | } |
1017 | 1093 | ||
1018 | rootPart.TrimPermissions(); | 1094 | rootPart.TrimPermissions(); |
@@ -1150,4 +1226,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1150 | 1226 | ||
1151 | #endregion | 1227 | #endregion |
1152 | } | 1228 | } |
1153 | } \ No newline at end of file | 1229 | } |