diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index bef57a0..98b0f97 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | |||
@@ -35,6 +35,7 @@ using OpenMetaverse.StructuredData; | |||
35 | using log4net; | 35 | using log4net; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Communications; | 37 | using OpenSim.Framework.Communications; |
38 | using OpenSim.Framework.Communications.Cache; | ||
38 | using OpenSim.Framework.Communications.Capabilities; | 39 | using OpenSim.Framework.Communications.Capabilities; |
39 | using OpenSim.Region.Framework.Interfaces; | 40 | using OpenSim.Region.Framework.Interfaces; |
40 | using OSD = OpenMetaverse.StructuredData.OSD; | 41 | using OSD = OpenMetaverse.StructuredData.OSD; |
@@ -1018,6 +1019,175 @@ namespace OpenSim.Region.Framework.Scenes | |||
1018 | return m_commsProvider.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying); | 1019 | return m_commsProvider.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying); |
1019 | } | 1020 | } |
1020 | 1021 | ||
1022 | public void CrossAgentToNewRegion(Scene scene, ScenePresence agent, bool isFlying) | ||
1023 | { | ||
1024 | Vector3 pos = agent.AbsolutePosition; | ||
1025 | Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); | ||
1026 | uint neighbourx = m_regionInfo.RegionLocX; | ||
1027 | uint neighboury = m_regionInfo.RegionLocY; | ||
1028 | |||
1029 | // distance to edge that will trigger crossing | ||
1030 | const float boundaryDistance = 1.7f; | ||
1031 | |||
1032 | // distance into new region to place avatar | ||
1033 | const float enterDistance = 0.1f; | ||
1034 | |||
1035 | if (pos.X < boundaryDistance) | ||
1036 | { | ||
1037 | neighbourx--; | ||
1038 | newpos.X = Constants.RegionSize - enterDistance; | ||
1039 | } | ||
1040 | else if (pos.X > Constants.RegionSize - boundaryDistance) | ||
1041 | { | ||
1042 | neighbourx++; | ||
1043 | newpos.X = enterDistance; | ||
1044 | } | ||
1045 | |||
1046 | if (pos.Y < boundaryDistance) | ||
1047 | { | ||
1048 | neighboury--; | ||
1049 | newpos.Y = Constants.RegionSize - enterDistance; | ||
1050 | } | ||
1051 | else if (pos.Y > Constants.RegionSize - boundaryDistance) | ||
1052 | { | ||
1053 | neighboury++; | ||
1054 | newpos.Y = enterDistance; | ||
1055 | } | ||
1056 | |||
1057 | Vector3 vel = agent.Velocity; | ||
1058 | |||
1059 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | ||
1060 | d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d); | ||
1061 | |||
1062 | |||
1063 | } | ||
1064 | |||
1065 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying); | ||
1066 | |||
1067 | /// <summary> | ||
1068 | /// This Closes child agents on neighboring regions | ||
1069 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | ||
1070 | /// </summary> | ||
1071 | protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying) | ||
1072 | { | ||
1073 | m_log.DebugFormat("[SCENE COMM]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); | ||
1074 | |||
1075 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | ||
1076 | SimpleRegionInfo neighbourRegion = RequestNeighbouringRegionInfo(neighbourHandle); | ||
1077 | if (neighbourRegion != null && agent.ValidateAttachments()) | ||
1078 | { | ||
1079 | pos = pos + (agent.Velocity); | ||
1080 | |||
1081 | CachedUserInfo userInfo = m_commsProvider.UserProfileCacheService.GetUserDetails(agent.UUID); | ||
1082 | if (userInfo != null) | ||
1083 | { | ||
1084 | userInfo.DropInventory(); | ||
1085 | } | ||
1086 | else | ||
1087 | { | ||
1088 | m_log.WarnFormat("[SCENE COMM]: No cached user info found for {0} {1} on leaving region {2}", | ||
1089 | agent.Name, agent.UUID, agent.Scene.RegionInfo.RegionName); | ||
1090 | } | ||
1091 | |||
1092 | bool crossingSuccessful = | ||
1093 | CrossToNeighbouringRegion(neighbourHandle, agent.ControllingClient.AgentId, pos, | ||
1094 | isFlying); | ||
1095 | if (crossingSuccessful) | ||
1096 | { | ||
1097 | // Next, let's close the child agent connections that are too far away. | ||
1098 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1099 | |||
1100 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); | ||
1101 | agent.ControllingClient.RequestClientInfo(); | ||
1102 | |||
1103 | //Console.WriteLine("BEFORE CROSS"); | ||
1104 | //Scene.DumpChildrenSeeds(UUID); | ||
1105 | //DumpKnownRegions(); | ||
1106 | string agentcaps; | ||
1107 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1108 | { | ||
1109 | m_log.ErrorFormat("[SCENE COMM]: No CAPS information for region handle {0}, exiting CrossToNewRegion.", | ||
1110 | neighbourRegion.RegionHandle); | ||
1111 | return agent; | ||
1112 | } | ||
1113 | // TODO Should construct this behind a method | ||
1114 | string capsPath = | ||
1115 | "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort | ||
1116 | + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/"; | ||
1117 | |||
1118 | m_log.DebugFormat("[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | ||
1119 | |||
1120 | IEventQueue eq = agent.Scene.RequestModuleInterface<IEventQueue>(); | ||
1121 | if (eq != null) | ||
1122 | { | ||
1123 | eq.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1124 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | ||
1125 | } | ||
1126 | else | ||
1127 | { | ||
1128 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1129 | capsPath); | ||
1130 | } | ||
1131 | |||
1132 | agent.MakeChildAgent(); | ||
1133 | // now we have a child agent in this region. Request all interesting data about other (root) agents | ||
1134 | agent.SendInitialFullUpdateToAllClients(); | ||
1135 | |||
1136 | agent.CrossAttachmentsIntoNewRegion(neighbourHandle, true); | ||
1137 | |||
1138 | // m_scene.SendKillObject(m_localId); | ||
1139 | |||
1140 | agent.Scene.NotifyMyCoarseLocationChange(); | ||
1141 | // the user may change their profile information in other region, | ||
1142 | // so the userinfo in UserProfileCache is not reliable any more, delete it | ||
1143 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1144 | { | ||
1145 | agent.Scene.CommsManager.UserProfileCacheService.RemoveUser(agent.UUID); | ||
1146 | m_log.DebugFormat( | ||
1147 | "[SCENE COMM]: User {0} is going to another region, profile cache removed", agent.UUID); | ||
1148 | } | ||
1149 | } | ||
1150 | else | ||
1151 | { | ||
1152 | //// Restore the user structures that we needed to delete before asking the receiving region | ||
1153 | //// to complete the crossing | ||
1154 | //userInfo.FetchInventory(); | ||
1155 | //agent.Scene.CapsModule.AddCapsHandler(agent.UUID); | ||
1156 | } | ||
1157 | } | ||
1158 | |||
1159 | //Console.WriteLine("AFTER CROSS"); | ||
1160 | //Scene.DumpChildrenSeeds(UUID); | ||
1161 | //DumpKnownRegions(); | ||
1162 | return agent; | ||
1163 | } | ||
1164 | |||
1165 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | ||
1166 | { | ||
1167 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; | ||
1168 | ScenePresence agent = icon.EndInvoke(iar); | ||
1169 | |||
1170 | // If the cross was successful, this agent is a child agent | ||
1171 | if (agent.IsChildAgent) | ||
1172 | { | ||
1173 | // Put the child agent back at the center | ||
1174 | agent.AbsolutePosition = new Vector3(128, 128, 70); | ||
1175 | } | ||
1176 | else // Not successful | ||
1177 | { | ||
1178 | CachedUserInfo userInfo = m_commsProvider.UserProfileCacheService.GetUserDetails(agent.UUID); | ||
1179 | if (userInfo != null) | ||
1180 | { | ||
1181 | userInfo.FetchInventory(); | ||
1182 | } | ||
1183 | agent.RestoreInCurrentScene(); | ||
1184 | } | ||
1185 | agent.IsInTransit = false; | ||
1186 | |||
1187 | //m_log.DebugFormat("[SCENE COMM]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); | ||
1188 | } | ||
1189 | |||
1190 | |||
1021 | public bool PrimCrossToNeighboringRegion(ulong regionhandle, UUID primID, string objData, int XMLMethod) | 1191 | public bool PrimCrossToNeighboringRegion(ulong regionhandle, UUID primID, string objData, int XMLMethod) |
1022 | { | 1192 | { |
1023 | return m_commsProvider.InterRegion.InformRegionOfPrimCrossing(regionhandle, primID, objData, XMLMethod); | 1193 | return m_commsProvider.InterRegion.InformRegionOfPrimCrossing(regionhandle, primID, objData, XMLMethod); |