aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJustin Clark-Casey2014-05-06 19:57:31 +0100
committerJustin Clark-Casey2014-05-06 19:57:31 +0100
commitc38736de82321154252d9d3fcb3fd3d2250d633a (patch)
treeebbf281ce9a309aec6b598213c210438b473e6e7 /OpenSim/Region
parentChange version flavour to RC1. Make version number more normal "0.8" rather ... (diff)
parentRevert "fix infinite recursion loop in SendGridInstantMessageViaXMLRPCAsync()" (diff)
downloadopensim-SC_OLD-c38736de82321154252d9d3fcb3fd3d2250d633a.zip
opensim-SC_OLD-c38736de82321154252d9d3fcb3fd3d2250d633a.tar.gz
opensim-SC_OLD-c38736de82321154252d9d3fcb3fd3d2250d633a.tar.bz2
opensim-SC_OLD-c38736de82321154252d9d3fcb3fd3d2250d633a.tar.xz
Merge branch 'master' into 0.8-post-fixes0.8-rc1
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs113
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs178
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs63
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateModule.cs3
4 files changed, 278 insertions, 79 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index cc505f8..59b4614 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -402,6 +402,12 @@ namespace OpenSim
402 "Delete a region from disk", 402 "Delete a region from disk",
403 RunCommand); 403 RunCommand);
404 404
405 m_console.Commands.AddCommand("Estates", false, "estate create",
406 "estate create <owner UUID> <estate name>",
407 "Creates a new estate with the specified name, owned by the specified user."
408 + " Estate name must be unique.",
409 CreateEstateCommand);
410
405 m_console.Commands.AddCommand("Estates", false, "estate set owner", 411 m_console.Commands.AddCommand("Estates", false, "estate set owner",
406 "estate set owner <estate-id>[ <UUID> | <Firstname> <Lastname> ]", 412 "estate set owner <estate-id>[ <UUID> | <Firstname> <Lastname> ]",
407 "Sets the owner of the specified estate to the specified UUID or user. ", 413 "Sets the owner of the specified estate to the specified UUID or user. ",
@@ -411,6 +417,11 @@ namespace OpenSim
411 "estate set name <estate-id> <new name>", 417 "estate set name <estate-id> <new name>",
412 "Sets the name of the specified estate to the specified value. New name must be unique.", 418 "Sets the name of the specified estate to the specified value. New name must be unique.",
413 SetEstateNameCommand); 419 SetEstateNameCommand);
420
421 m_console.Commands.AddCommand("Estates", false, "estate link region",
422 "estate link region <estate ID> <region ID>",
423 "Attaches the specified region to the specified estate.",
424 EstateLinkRegionCommand);
414 } 425 }
415 426
416 protected override void ShutdownSpecific() 427 protected override void ShutdownSpecific()
@@ -1177,6 +1188,58 @@ namespace OpenSim
1177 SceneManager.SaveCurrentSceneToArchive(cmdparams); 1188 SceneManager.SaveCurrentSceneToArchive(cmdparams);
1178 } 1189 }
1179 1190
1191 protected void CreateEstateCommand(string module, string[] args)
1192 {
1193 string response = null;
1194 UUID userID;
1195
1196 if (args.Length == 2)
1197 {
1198 response = "No user specified.";
1199 }
1200 else if (!UUID.TryParse(args[2], out userID))
1201 {
1202 response = String.Format("{0} is not a valid UUID", args[2]);
1203 }
1204 else if (args.Length == 3)
1205 {
1206 response = "No estate name specified.";
1207 }
1208 else
1209 {
1210 Scene scene = SceneManager.CurrentOrFirstScene;
1211
1212 // TODO: Is there a better choice here?
1213 UUID scopeID = UUID.Zero;
1214 UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, userID);
1215 if (account == null)
1216 {
1217 response = String.Format("Could not find user {0}", userID);
1218 }
1219 else
1220 {
1221 // concatenate it all to "name"
1222 StringBuilder sb = new StringBuilder(args[3]);
1223 for (int i = 4; i < args.Length; i++)
1224 sb.Append (" " + args[i]);
1225 string estateName = sb.ToString().Trim();
1226
1227 // send it off for processing.
1228 IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
1229 response = estateModule.CreateEstate(estateName, userID);
1230 if (response == String.Empty)
1231 {
1232 List<int> estates = scene.EstateDataService.GetEstates(estateName);
1233 response = String.Format("Estate {0} created as \"{1}\"", estates.ElementAt(0), estateName);
1234 }
1235 }
1236 }
1237
1238 // give the user some feedback
1239 if (response != null)
1240 MainConsole.Instance.Output(response);
1241 }
1242
1180 protected void SetEstateOwnerCommand(string module, string[] args) 1243 protected void SetEstateOwnerCommand(string module, string[] args)
1181 { 1244 {
1182 string response = null; 1245 string response = null;
@@ -1299,6 +1362,56 @@ namespace OpenSim
1299 MainConsole.Instance.Output(response); 1362 MainConsole.Instance.Output(response);
1300 } 1363 }
1301 1364
1365 private void EstateLinkRegionCommand(string module, string[] args)
1366 {
1367 int estateId =-1;
1368 UUID regionId = UUID.Zero;
1369 Scene scene = null;
1370 string response = null;
1371
1372 if (args.Length == 3)
1373 {
1374 response = "No estate specified.";
1375 }
1376 else if (!int.TryParse(args [3], out estateId))
1377 {
1378 response = String.Format("\"{0}\" is not a valid ID for an Estate", args [3]);
1379 }
1380 else if (args.Length == 4)
1381 {
1382 response = "No region specified.";
1383 }
1384 else if (!UUID.TryParse(args[4], out regionId))
1385 {
1386 response = String.Format("\"{0}\" is not a valid UUID for a Region", args [4]);
1387 }
1388 else if (!SceneManager.TryGetScene(regionId, out scene))
1389 {
1390 // region may exist, but on a different sim.
1391 response = String.Format("No access to Region \"{0}\"", args [4]);
1392 }
1393
1394 if (response != null)
1395 {
1396 MainConsole.Instance.Output(response);
1397 return;
1398 }
1399
1400 // send it off for processing.
1401 IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
1402 response = estateModule.SetRegionEstate(scene.RegionInfo, estateId);
1403 if (response == String.Empty)
1404 {
1405 estateModule.TriggerRegionInfoChange();
1406 estateModule.sendRegionHandshakeToAll();
1407 response = String.Format ("Region {0} is now attached to estate {1}", regionId, estateId);
1408 }
1409
1410 // give the user some feedback
1411 if (response != null)
1412 MainConsole.Instance.Output (response);
1413 }
1414
1302 #endregion 1415 #endregion
1303 1416
1304 private static string CombineParams(string[] commandParams, int pos) 1417 private static string CombineParams(string[] commandParams, int pos)
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 4f8e2cd..40a400f 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
428 /// <summary> 428 /// <summary>
429 /// delegate for sending a grid instant message asynchronously 429 /// delegate for sending a grid instant message asynchronously
430 /// </summary> 430 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); 431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
432 432
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
434 { 434 {
@@ -442,118 +442,138 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
442 { 442 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
444 444
445 d.BeginInvoke(im, result, GridInstantMessageCompleted, d); 445 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d);
446 } 446 }
447 447
448 /// <summary> 448 /// <summary>
449 /// Internal SendGridInstantMessage over XMLRPC method. 449 /// Recursive SendGridInstantMessage over XMLRPC method.
450 /// This is called from within a dedicated thread. 450 /// This is called from within a dedicated thread.
451 /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from
452 /// itself, prevRegionHandle will be the last region handle that we tried to send.
453 /// If the handles are the same, we look up the user's location using the grid.
454 /// If the handles are still the same, we end. The send failed.
451 /// </summary> 455 /// </summary>
452 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result) 456 /// <param name="prevRegionHandle">
457 /// Pass in 0 the first time this method is called. It will be called recursively with the last
458 /// regionhandle tried
459 /// </param>
460 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
453 { 461 {
454 UUID toAgentID = new UUID(im.toAgentID); 462 UUID toAgentID = new UUID(im.toAgentID);
455 UUID regionID;
456 bool lookupAgent;
457 463
458 /* 464 PresenceInfo upd = null;
459 * Try to get what region the agent is in from the cache. 465
460 */ 466 bool lookupAgent = false;
467
461 lock (m_UserRegionMap) 468 lock (m_UserRegionMap)
462 { 469 {
463 lookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID); 470 if (m_UserRegionMap.ContainsKey(toAgentID))
471 {
472 upd = new PresenceInfo();
473 upd.RegionID = m_UserRegionMap[toAgentID];
474
475 // We need to compare the current regionhandle with the previous region handle
476 // or the recursive loop will never end because it will never try to lookup the agent again
477 if (prevRegionID == upd.RegionID)
478 {
479 lookupAgent = true;
480 }
481 }
482 else
483 {
484 lookupAgent = true;
485 }
464 } 486 }
487
465 488
466 while (true) 489 // Are we needing to look-up an agent?
490 if (lookupAgent)
467 { 491 {
468 492 // Non-cached user agent lookup.
469 /* 493 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
470 * If not in cache, try to find out what region the agent is in. 494 if (presences != null && presences.Length > 0)
471 * Also do this if we know the existing cache entry is bad.
472 */
473 if (lookupAgent)
474 { 495 {
475 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); 496 foreach (PresenceInfo p in presences)
476
477 regionID = UUID.Zero;
478 if (presences != null)
479 { 497 {
480 foreach (PresenceInfo p in presences) 498 if (p.RegionID != UUID.Zero)
481 { 499 {
482 if (p.RegionID != UUID.Zero) 500 upd = p;
483 { 501 break;
484 regionID = p.RegionID;
485 break;
486 }
487 } 502 }
488 } 503 }
504 }
489 505
490 // If not found, message is undeliverable 506 if (upd != null)
491 if (regionID == UUID.Zero) 507 {
508 // check if we've tried this before..
509 // This is one way to end the recursive loop
510 //
511 if (upd.RegionID == prevRegionID)
492 { 512 {
493 break; 513 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
514 HandleUndeliveredMessage(im, result);
515 return;
494 } 516 }
495 } 517 }
496 518 else
497 /*
498 * Try to find out about region.
499 * If unable, message is undeliverable.
500 */
501 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
502 if (reginfo == null)
503 { 519 {
504 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID); 520 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
505 break; 521 HandleUndeliveredMessage(im, result);
522 return;
506 } 523 }
524 }
507 525
508 /* 526 if (upd != null)
509 * Try to send message to agent in the region. 527 {
510 */ 528 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
511 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); 529 upd.RegionID);
512 msgdata["region_handle"] = 0; 530 if (reginfo != null)
513 bool imresult = doIMSending(reginfo, msgdata);
514
515 /*
516 * If message delivery successful, save cache entry because we know it is good.
517 * Then tell caller message has been delivered and we are done.
518 */
519 if (imresult)
520 { 531 {
521 lock (m_UserRegionMap) 532 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
533 // Not actually used anymore, left in for compatibility
534 // Remove at next interface change
535 //
536 msgdata["region_handle"] = 0;
537 bool imresult = doIMSending(reginfo, msgdata);
538 if (imresult)
539 {
540 // IM delivery successful, so store the Agent's location in our local cache.
541 lock (m_UserRegionMap)
542 {
543 if (m_UserRegionMap.ContainsKey(toAgentID))
544 {
545 m_UserRegionMap[toAgentID] = upd.RegionID;
546 }
547 else
548 {
549 m_UserRegionMap.Add(toAgentID, upd.RegionID);
550 }
551 }
552 result(true);
553 }
554 else
522 { 555 {
523 m_UserRegionMap[toAgentID] = regionID; 556 // try again, but lookup user this time.
557 // Warning, this must call the Async version
558 // of this method or we'll be making thousands of threads
559 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
560 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
561
562 // This is recursive!!!!!
563 SendGridInstantMessageViaXMLRPCAsync(im, result,
564 upd.RegionID);
524 } 565 }
525 result(true);
526 return;
527 } 566 }
528 567 else
529 /*
530 * Message delivery failed.
531 * If we just looked up what region the agent is in, message is undeliverable.
532 */
533 if (lookupAgent)
534 { 568 {
535 break; 569 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
570 HandleUndeliveredMessage(im, result);
536 } 571 }
537
538 /*
539 * We used a cached entry that we now know is bad.
540 * Try again by searching the grid for the user.
541 */
542 lookupAgent = true;
543 } 572 }
544 573 else
545 /*
546 * Message is undeliverable for one reason or another.
547 * Remove possible bad entry from cache.
548 * Then inform caller that the message is undeliverable.
549 */
550 lock (m_UserRegionMap)
551 { 574 {
552 m_UserRegionMap.Remove(toAgentID); 575 HandleUndeliveredMessage(im, result);
553 } 576 }
554
555 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
556 HandleUndeliveredMessage(im, result);
557 } 577 }
558 578
559 /// <summary> 579 /// <summary>
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 54a7302..a032bc7 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -313,6 +313,69 @@ namespace OpenSim.Region.CoreModules.World.Estate
313 return response; 313 return response;
314 } 314 }
315 315
316 public string SetRegionEstate(RegionInfo regionInfo, int estateID)
317 {
318 string response;
319
320 if (regionInfo.EstateSettings.EstateID == estateID)
321 {
322 response = String.Format("\"{0}\" is already part of estate {1}", regionInfo.RegionName, estateID);
323 }
324 else
325 {
326 // get the current settings from DB
327 EstateSettings dbSettings = Scene.EstateDataService.LoadEstateSettings(estateID);
328 if (dbSettings.EstateID == 0)
329 {
330 response = String.Format("No estate found with ID {0}", estateID);
331 }
332 else if (Scene.EstateDataService.LinkRegion(regionInfo.RegionID, estateID))
333 {
334 // make sure there's a log entry to document the change
335 m_log.InfoFormat("[ESTATE]: Region {0} ({1}) moved to Estate {2} ({3}).", regionInfo.RegionID, regionInfo.RegionName, estateID, dbSettings.EstateName);
336
337 // propagate the change
338 ChangeDelegate change = OnEstateInfoChange;
339
340 if (change != null)
341 change(regionInfo.RegionID);
342
343 response = String.Empty;
344 }
345 else
346 {
347 response = String.Format("Could not move \"{0}\" to estate {1}", regionInfo.RegionName, estateID);
348 }
349 }
350 return response;
351 }
352
353 public string CreateEstate(string estateName, UUID ownerID)
354 {
355 string response;
356 if (string.IsNullOrEmpty(estateName))
357 {
358 response = "No estate name specified.";
359 }
360 else
361 {
362 List<int> estates = Scene.EstateDataService.GetEstates(estateName);
363 if (estates.Count() > 0)
364 {
365 response = String.Format("An estate named \"{0}\" already exists.", estateName);
366 }
367 else
368 {
369 EstateSettings settings = Scene.EstateDataService.CreateNewEstate();
370 settings.EstateOwner = ownerID;
371 settings.EstateName = estateName;
372 settings.Save();
373 response = String.Empty;
374 }
375 }
376 return response;
377 }
378
316 #endregion 379 #endregion
317 380
318 #region Packet Data Responders 381 #region Packet Data Responders
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
index 600ecfe..461c880 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using OpenMetaverse; 28using OpenMetaverse;
29using OpenSim.Framework;
29using OpenSim.Services.Interfaces; 30using OpenSim.Services.Interfaces;
30 31
31namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
@@ -44,6 +45,8 @@ namespace OpenSim.Region.Framework.Interfaces
44 45
45 string SetEstateOwner(int estateID, UserAccount account); 46 string SetEstateOwner(int estateID, UserAccount account);
46 string SetEstateName(int estateID, string newName); 47 string SetEstateName(int estateID, string newName);
48 string SetRegionEstate(RegionInfo regionInfo, int estateID);
49 string CreateEstate(string estateName, UUID ownerID);
47 50
48 /// <summary> 51 /// <summary>
49 /// Tell all clients about the current state of the region (terrain textures, water height, etc.). 52 /// Tell all clients about the current state of the region (terrain textures, water height, etc.).