aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Communications/Local/LocalLoginService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Communications/Local/LocalLoginService.cs')
-rw-r--r--OpenSim/Region/Communications/Local/LocalLoginService.cs257
1 files changed, 128 insertions, 129 deletions
diff --git a/OpenSim/Region/Communications/Local/LocalLoginService.cs b/OpenSim/Region/Communications/Local/LocalLoginService.cs
index 93a1e46..2f7fdb7 100644
--- a/OpenSim/Region/Communications/Local/LocalLoginService.cs
+++ b/OpenSim/Region/Communications/Local/LocalLoginService.cs
@@ -41,8 +41,7 @@ namespace OpenSim.Region.Communications.Local
41 41
42 public class LocalLoginService : LoginService 42 public class LocalLoginService : LoginService
43 { 43 {
44 private static readonly ILog m_log 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 45
47 private CommunicationsLocal m_Parent; 46 private CommunicationsLocal m_Parent;
48 47
@@ -120,167 +119,167 @@ namespace OpenSim.Region.Communications.Local
120 } 119 }
121 } 120 }
122 121
123 private Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$"); 122 /// <summary>
124 123 /// Customises the login response and fills in missing values.
124 /// </summary>
125 /// <param name="response">The existing response</param>
126 /// <param name="theUser">The user profile</param>
127 /// <param name="startLocationRequest">The requested start location</param>
125 public override bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest) 128 public override bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest)
126 { 129 {
127 ulong currentRegion = 0; 130 // HomeLocation
128 131 RegionInfo homeInfo = null;
129 uint locX = 0; 132 // use the homeRegionID if it is stored already. If not, use the regionHandle as before
130 uint locY = 0; 133 if (theUser.HomeRegionID != UUID.Zero)
131 uint locZ = 0; 134 homeInfo = m_Parent.GridService.RequestNeighbourInfo(theUser.HomeRegionID);
132 bool specificStartLocation = false; 135 else
136 homeInfo = m_Parent.GridService.RequestNeighbourInfo(theUser.HomeRegion);
137 if (homeInfo != null)
138 {
139 response.Home =
140 string.Format(
141 "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
142 (homeInfo.RegionLocX*Constants.RegionSize),
143 (homeInfo.RegionLocY*Constants.RegionSize),
144 theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z,
145 theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z);
146 }
147 else
148 {
149 // Emergency mode: Home-region isn't available, so we can't request the region info.
150 // Use the stored home regionHandle instead.
151 // NOTE: If the home-region moves, this will be wrong until the users update their user-profile again
152 ulong regionX = theUser.HomeRegion >> 32;
153 ulong regionY = theUser.HomeRegion & 0xffffffff;
154 response.Home =
155 string.Format(
156 "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
157 regionX, regionY,
158 theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z,
159 theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z);
160 m_log.InfoFormat("[LOGIN] Home region of user {0} {1} is not available; using computed region position {2} {3}",
161 theUser.FirstName, theUser.SurName,
162 regionX, regionY);
163 }
133 164
134 // get start location 165 // StartLocation
135 if (startLocationRequest == "last") 166 RegionInfo regionInfo = null;
167 if (startLocationRequest == "home")
136 { 168 {
137 currentRegion = theUser.CurrentAgent.Handle; 169 regionInfo = homeInfo;
138 locX = (UInt32)theUser.CurrentAgent.Position.X; 170 theUser.CurrentAgent.Position = theUser.HomeLocation;
139 locY = (UInt32)theUser.CurrentAgent.Position.Y; 171 response.LookAt = "[r" + theUser.HomeLookAt.X.ToString() + ",r" + theUser.HomeLookAt.Y.ToString() + ",r" + theUser.HomeLookAt.Z.ToString() + "]";
140 locZ = (UInt32)theUser.CurrentAgent.Position.Z;
141 response.StartLocation = "last";
142 specificStartLocation = true;
143 } 172 }
144 else if (startLocationRequest == "home") 173 else if (startLocationRequest == "last")
145 { 174 {
146 currentRegion = theUser.HomeRegion; 175 regionInfo = m_Parent.GridService.RequestNeighbourInfo(theUser.CurrentAgent.Region);
147 response.StartLocation = "home"; 176 response.LookAt = "[r" + theUser.CurrentAgent.LookAt.X.ToString() + ",r" + theUser.CurrentAgent.LookAt.Y.ToString() + ",r" + theUser.CurrentAgent.LookAt.Z.ToString() + "]";
148 } 177 }
149 else 178 else
150 { 179 {
151 // use last location as default 180 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
152 currentRegion = theUser.CurrentAgent.Handle;
153
154 Match uriMatch = reURI.Match(startLocationRequest); 181 Match uriMatch = reURI.Match(startLocationRequest);
155 if (null == uriMatch) 182 if (uriMatch == null)
156 { 183 {
157 m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, but can't process it", startLocationRequest); 184 m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, but can't process it", startLocationRequest);
158 } 185 }
159 else 186 else
160 { 187 {
161 string region = uriMatch.Groups["region"].ToString(); 188 string region = uriMatch.Groups["region"].ToString();
162 189 regionInfo = m_Parent.GridService.RequestClosestRegion(region);
163 RegionInfo r = m_Parent.GridService.RequestClosestRegion(region); 190 if (regionInfo == null)
164 if (null == r)
165 { 191 {
166 m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, can't locate region {1}", 192 m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, can't locate region {1}", startLocationRequest, region);
167 startLocationRequest, region);
168 } 193 }
169 else 194 else
170 { 195 {
171 currentRegion = r.RegionHandle; 196 theUser.CurrentAgent.Position = new Vector3(float.Parse(uriMatch.Groups["x"].Value),
172 locX = UInt32.Parse(uriMatch.Groups["x"].ToString()); 197 float.Parse(uriMatch.Groups["y"].Value), float.Parse(uriMatch.Groups["x"].Value));
173 locY = UInt32.Parse(uriMatch.Groups["y"].ToString());
174 locZ = UInt32.Parse(uriMatch.Groups["z"].ToString());
175 // can be: last, home, safe, url
176 response.StartLocation = "url";
177 specificStartLocation = true;
178 } 198 }
179 } 199 }
200 response.LookAt = "[r0,r1,r0]";
201 // can be: last, home, safe, url
202 response.StartLocation = "url";
180 } 203 }
181 204
182 RegionInfo homeReg = m_Parent.GridService.RequestNeighbourInfo(theUser.HomeRegion); 205 if ((regionInfo != null) && (PrepareLoginToRegion(regionInfo, theUser, response)))
183 RegionInfo reg = m_Parent.GridService.RequestNeighbourInfo(currentRegion);
184
185 if ((homeReg != null) || (reg != null))
186 { 206 {
187 if (homeReg != null) 207 return true;
188 { 208 }
189 response.Home = "{'region_handle':[r" +
190 (homeReg.RegionLocX * Constants.RegionSize).ToString() + ",r" +
191 (homeReg.RegionLocY * Constants.RegionSize).ToString() + "], " +
192 "'position':[r" +
193 theUser.HomeLocation.X.ToString() + ",r" +
194 theUser.HomeLocation.Y.ToString() + ",r" +
195 theUser.HomeLocation.Z.ToString() + "], " +
196 "'look_at':[r" +
197 theUser.HomeLocation.X.ToString() + ",r" +
198 theUser.HomeLocation.Y.ToString() + ",r" +
199 theUser.HomeLocation.Z.ToString() + "]}";
200 }
201 else
202 {
203 m_log.Warn("[LOGIN]: Your home region doesn't exist");
204 response.Home = "{'region_handle':[r" +
205 (reg.RegionLocX * Constants.RegionSize).ToString() + ",r" +
206 (reg.RegionLocY * Constants.RegionSize).ToString() + "], " +
207 "'position':[r" +
208 theUser.HomeLocation.X.ToString() + ",r" +
209 theUser.HomeLocation.Y.ToString() + ",r" +
210 theUser.HomeLocation.Z.ToString() + "], " +
211 "'look_at':[r" +
212 theUser.HomeLocation.X.ToString() + ",r" +
213 theUser.HomeLocation.Y.ToString() + ",r" +
214 theUser.HomeLocation.Z.ToString() + "]}";
215 }
216 string capsPath = Util.GetRandomCapsPath();
217 response.SimAddress = reg.ExternalEndPoint.Address.ToString();
218 response.SimPort = (uint) reg.ExternalEndPoint.Port;
219 response.RegionX = reg.RegionLocX;
220 response.RegionY = reg.RegionLocY;
221
222 m_log.DebugFormat(
223 "[CAPS][LOGIN]: RegionX {0} RegionY {0}", response.RegionX, response.RegionY);
224
225 response.SeedCapability = "http://" + reg.ExternalHostName + ":" +
226 serversInfo.HttpListenerPort.ToString() + "/CAPS/" + capsPath + "0000/";
227
228 m_log.DebugFormat(
229 "[CAPS]: Sending new CAPS seed url {0} to client {1}",
230 response.SeedCapability, response.AgentID);
231
232 theUser.CurrentAgent.Region = reg.RegionID;
233 theUser.CurrentAgent.Handle = reg.RegionHandle;
234
235 // LoginResponse.BuddyList buddyList = new LoginResponse.BuddyList();
236
237 response.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(theUser.ID));
238
239 Login _login = new Login();
240 //copy data to login object
241 _login.First = response.Firstname;
242 _login.Last = response.Lastname;
243 _login.Agent = response.AgentID;
244 _login.Session = response.SessionID;
245 _login.SecureSession = response.SecureSessionID;
246 _login.CircuitCode = (uint) response.CircuitCode;
247 if (specificStartLocation)
248 _login.StartPos = new Vector3(locX, locY, locZ);
249 else
250 _login.StartPos = new Vector3(128, 128, 128);
251 _login.CapsPath = capsPath;
252 209
253 m_log.InfoFormat( 210 // StartLocation not available, send him to a nearby region instead
254 "[LOGIN]: Telling region {0} @ {1},{2} ({3}:{4}) to expect user connection", 211 // regionInfo = m_Parent.GridService.RequestClosestRegion("");
255 reg.RegionName, response.RegionX, response.RegionY, response.SimAddress, response.SimPort); 212 //m_log.InfoFormat("[LOGIN]: StartLocation not available sending to region {0}", regionInfo.regionName);
256 213
257 handlerLoginToRegion = OnLoginToRegion; 214 // Send him to default region instead
258 if (handlerLoginToRegion != null) 215 ulong defaultHandle = (((ulong)defaultHomeX * Constants.RegionSize) << 32) |
259 { 216 ((ulong)defaultHomeY * Constants.RegionSize);
260 handlerLoginToRegion(currentRegion, _login); 217
261 } 218 if ((regionInfo != null) && (defaultHandle == regionInfo.RegionHandle))
262 }
263 else
264 { 219 {
265 m_log.Warn("[LOGIN]: Not found region " + currentRegion); 220 m_log.ErrorFormat("[LOGIN]: Not trying the default region since this is the same as the selected region");
266 return false; 221 return false;
267 } 222 }
268 223
269 return true; 224 m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead");
225 regionInfo = m_Parent.GridService.RequestNeighbourInfo(defaultHandle);
226
227 // Customise the response
228 //response.Home =
229 // string.Format(
230 // "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
231 // (SimInfo.regionLocX * Constants.RegionSize),
232 // (SimInfo.regionLocY*Constants.RegionSize),
233 // theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z,
234 // theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z);
235 theUser.CurrentAgent.Position = new Vector3(128,128,0);
236 response.StartLocation = "safe";
237
238 return PrepareLoginToRegion(regionInfo, theUser, response);
270 } 239 }
271 240
272 private LoginResponse.BuddyList ConvertFriendListItem(List<FriendListItem> LFL) 241 /// <summary>
242 /// Prepare a login to the given region. This involves both telling the region to expect a connection
243 /// and appropriately customising the response to the user.
244 /// </summary>
245 /// <param name="sim"></param>
246 /// <param name="user"></param>
247 /// <param name="response"></param>
248 /// <returns>true if the region was successfully contacted, false otherwise</returns>
249 private bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response)
273 { 250 {
274 LoginResponse.BuddyList buddylistreturn = new LoginResponse.BuddyList(); 251 response.SimAddress = regionInfo.ExternalEndPoint.Address.ToString();
275 foreach (FriendListItem fl in LFL) 252 response.SimPort = (uint)regionInfo.ExternalEndPoint.Port;
276 { 253 response.RegionX = regionInfo.RegionLocX;
277 LoginResponse.BuddyList.BuddyInfo buddyitem = new LoginResponse.BuddyList.BuddyInfo(fl.Friend); 254 response.RegionY = regionInfo.RegionLocY;
278 buddyitem.BuddyID = fl.Friend; 255
279 buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms; 256 string capsPath = Util.GetRandomCapsPath();
280 buddyitem.BuddyRightsGiven = (int)fl.FriendPerms; 257 response.SeedCapability = regionInfo.ServerURI + "/CAPS/" + capsPath + "0000/";
281 buddylistreturn.AddNewBuddy(buddyitem); 258
282 } 259 // Notify the target of an incoming user
283 return buddylistreturn; 260 m_log.InfoFormat(
261 "[LOGIN]: Telling {0} @ {1},{2} ({3}) to prepare for client connection",
262 regionInfo.RegionName, response.RegionX, response.RegionY, regionInfo.ServerURI);
263 // Update agent with target sim
264 user.CurrentAgent.Region = regionInfo.RegionID;
265 user.CurrentAgent.Handle = regionInfo.RegionHandle;
266 // Prepare notification
267 Login loginParams = new Login();
268 loginParams.Session = user.CurrentAgent.SessionID.ToString();
269 loginParams.SecureSession = user.CurrentAgent.SecureSessionID.ToString();
270 loginParams.First = user.FirstName;
271 loginParams.Last = user.SurName;
272 loginParams.Agent = user.ID.ToString();
273 loginParams.CircuitCode = Convert.ToUInt32(response.CircuitCode);
274 loginParams.StartPos = user.CurrentAgent.Position;
275 loginParams.CapsPath = capsPath;
276
277 handlerLoginToRegion = OnLoginToRegion;
278 if (handlerLoginToRegion == null)
279 return false;
280
281 handlerLoginToRegion(user.CurrentAgent.Handle, loginParams);
282 return true;
284 } 283 }
285 284
286 // See LoginService 285 // See LoginService