aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs170
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;
35using log4net; 35using log4net;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Communications; 37using OpenSim.Framework.Communications;
38using OpenSim.Framework.Communications.Cache;
38using OpenSim.Framework.Communications.Capabilities; 39using OpenSim.Framework.Communications.Capabilities;
39using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
40using OSD = OpenMetaverse.StructuredData.OSD; 41using 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);