Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

0.8.0.3
Diva Canto 2014-02-21 10:05:06 -08:00
commit 97c74afca8
35 changed files with 798 additions and 1166 deletions

View File

@ -106,7 +106,7 @@ namespace OpenSim.Groups
sendData["OP"] = "UPDATE"; sendData["OP"] = "UPDATE";
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData); Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL")) if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
return null; return null;
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
@ -127,7 +127,7 @@ namespace OpenSim.Groups
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData); Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL")) if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
return null; return null;
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
@ -267,6 +267,7 @@ namespace OpenSim.Groups
if (ret["RESULT"].ToString() == "NULL") if (ret["RESULT"].ToString() == "NULL")
return members; return members;
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
{ {
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v); ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
@ -357,6 +358,7 @@ namespace OpenSim.Groups
if (ret["RESULT"].ToString() == "NULL") if (ret["RESULT"].ToString() == "NULL")
return roles; return roles;
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
{ {
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v); GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
@ -667,7 +669,7 @@ namespace OpenSim.Groups
return replyData; return replyData;
} }
#endregion
#endregion
} }
} }

View File

@ -238,7 +238,15 @@ namespace OpenSim.Capabilities.Handlers
if (folderID != UUID.Zero) if (folderID != UUID.Zero)
{ {
contents = m_InventoryService.GetFolderContent(agentID, folderID); InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID);
if (fetchedContents == null)
{
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
return contents;
}
contents = fetchedContents;
InventoryFolderBase containingFolder = new InventoryFolderBase(); InventoryFolderBase containingFolder = new InventoryFolderBase();
containingFolder.ID = folderID; containingFolder.ID = folderID;
containingFolder.Owner = agentID; containingFolder.Owner = agentID;

View File

@ -1745,6 +1745,30 @@ namespace OpenSim.Framework
return data; return data;
} }
/// <summary>
/// Pretty format the hashtable contents to a single line.
/// </summary>
/// <remarks>
/// Used for debugging output.
/// </remarks>
/// <param name='ht'></param>
public static string PrettyFormatToSingleLine(Hashtable ht)
{
StringBuilder sb = new StringBuilder();
int i = 0;
foreach (string key in ht.Keys)
{
sb.AppendFormat("{0}:{1}", key, ht[key]);
if (++i < ht.Count)
sb.AppendFormat(", ");
}
return sb.ToString();
}
/// <summary> /// <summary>
/// Used to trigger an early library load on Windows systems. /// Used to trigger an early library load on Windows systems.
/// </summary> /// </summary>

View File

@ -559,7 +559,7 @@ namespace OpenSim
{ {
scene.ForEachSOG(delegate(SceneObjectGroup sog) scene.ForEachSOG(delegate(SceneObjectGroup sog)
{ {
if (sog.AttachmentPoint == 0) if (!sog.IsAttachment)
{ {
sog.RootPart.UpdateRotation(rot * sog.GroupRotation); sog.RootPart.UpdateRotation(rot * sog.GroupRotation);
Vector3 offset = sog.AbsolutePosition - center; Vector3 offset = sog.AbsolutePosition - center;
@ -588,7 +588,7 @@ namespace OpenSim
{ {
scene.ForEachSOG(delegate(SceneObjectGroup sog) scene.ForEachSOG(delegate(SceneObjectGroup sog)
{ {
if (sog.AttachmentPoint == 0) if (!sog.IsAttachment)
{ {
if (sog.RootPart.AbsolutePosition.Z < minZ) if (sog.RootPart.AbsolutePosition.Z < minZ)
minZ = sog.RootPart.AbsolutePosition.Z; minZ = sog.RootPart.AbsolutePosition.Z;
@ -600,7 +600,7 @@ namespace OpenSim
{ {
scene.ForEachSOG(delegate(SceneObjectGroup sog) scene.ForEachSOG(delegate(SceneObjectGroup sog)
{ {
if (sog.AttachmentPoint == 0) if (!sog.IsAttachment)
{ {
Vector3 tmpRootPos = sog.RootPart.AbsolutePosition; Vector3 tmpRootPos = sog.RootPart.AbsolutePosition;
tmpRootPos.Z -= minZ; tmpRootPos.Z -= minZ;
@ -640,7 +640,7 @@ namespace OpenSim
{ {
scene.ForEachSOG(delegate(SceneObjectGroup sog) scene.ForEachSOG(delegate(SceneObjectGroup sog)
{ {
if (sog.AttachmentPoint == 0) if (!sog.IsAttachment)
sog.UpdateGroupPosition(sog.AbsolutePosition + offset); sog.UpdateGroupPosition(sog.AbsolutePosition + offset);
}); });
}); });

View File

@ -229,12 +229,18 @@ namespace OpenSim.Region.ClientStack.Linden
lock (queue) lock (queue)
queue.Enqueue(ev); queue.Enqueue(ev);
} }
else else if (DebugLevel > 0)
{ {
OSDMap evMap = (OSDMap)ev; ScenePresence sp = m_scene.GetScenePresence(avatarID);
m_log.WarnFormat(
"[EVENTQUEUE]: (Enqueue) No queue found for agent {0} when placing message {1} in region {2}", // This assumes that an NPC should never have a queue.
avatarID, evMap["message"], m_scene.Name); if (sp != null && sp.PresenceType != PresenceType.Npc)
{
OSDMap evMap = (OSDMap)ev;
m_log.WarnFormat(
"[EVENTQUEUE]: (Enqueue) No queue found for agent {0} {1} when placing message {2} in region {3}",
sp.Name, sp.UUID, evMap["message"], m_scene.Name);
}
} }
} }
catch (NullReferenceException e) catch (NullReferenceException e)

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using log4net.Config; using log4net.Config;
@ -33,11 +34,14 @@ using Nini.Config;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.ClientStack.Linden; using OpenSim.Region.ClientStack.Linden;
using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.CoreModules.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.OptionalModules.World.NPC;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
@ -47,6 +51,8 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
public class EventQueueTests : OpenSimTestCase public class EventQueueTests : OpenSimTestCase
{ {
private TestScene m_scene; private TestScene m_scene;
private EventQueueGetModule m_eqgMod;
private NPCModule m_npcMod;
[SetUp] [SetUp]
public override void SetUp() public override void SetUp()
@ -69,10 +75,15 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
config.Configs["Startup"].Set("EventQueue", "true"); config.Configs["Startup"].Set("EventQueue", "true");
CapabilitiesModule capsModule = new CapabilitiesModule(); CapabilitiesModule capsModule = new CapabilitiesModule();
EventQueueGetModule eqgModule = new EventQueueGetModule(); m_eqgMod = new EventQueueGetModule();
// For NPC test support
config.AddConfig("NPC");
config.Configs["NPC"].Set("Enabled", "true");
m_npcMod = new NPCModule();
m_scene = new SceneHelpers().SetupScene(); m_scene = new SceneHelpers().SetupScene();
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule); SceneHelpers.SetupSceneModules(m_scene, config, capsModule, m_eqgMod, m_npcMod);
} }
[Test] [Test]
@ -101,5 +112,80 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
// TODO: Add more assertions for the other aspects of event queues // TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
} }
[Test]
public void TestEnqueueMessage()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
string messageName = "TestMessage";
m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), sp.UUID);
Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]);
OSDArray eventsOsd = (OSDArray)rawOsd["events"];
bool foundUpdate = false;
foreach (OSD osd in eventsOsd)
{
OSDMap eventOsd = (OSDMap)osd;
if (eventOsd["message"] == messageName)
foundUpdate = true;
}
Assert.That(foundUpdate, Is.True, string.Format("Did not find {0} in response", messageName));
}
/// <summary>
/// Test an attempt to put a message on the queue of a user that is not in the region.
/// </summary>
[Test]
public void TestEnqueueMessageNoUser()
{
TestHelpers.InMethod();
TestHelpers.EnableLogging();
string messageName = "TestMessage";
m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), TestHelpers.ParseTail(0x1));
Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, TestHelpers.ParseTail(0x1));
Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway));
}
/// <summary>
/// NPCs do not currently have an event queue but a caller may try to send a message anyway, so check behaviour.
/// </summary>
[Test]
public void TestEnqueueMessageToNpc()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID npcId
= m_npcMod.CreateNPC(
"John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, new AvatarAppearance());
ScenePresence npc = m_scene.GetScenePresence(npcId);
string messageName = "TestMessage";
m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), npc.UUID);
Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, npc.UUID);
Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway));
}
} }
} }

View File

@ -687,187 +687,238 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); m_scene.EventManager.TriggerAvatarAppearanceChanged(sp);
} }
/// <summary>
/// For a given set of appearance items, check whether the items are valid and add their asset IDs to
/// appearance data.
/// </summary>
/// <param name='userID'></param>
/// <param name='appearance'></param>
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
{ {
IInventoryService invService = m_scene.InventoryService; IInventoryService invService = m_scene.InventoryService;
bool resetwearable = false;
if (invService.GetRootFolder(userID) != null) if (invService.GetRootFolder(userID) != null)
{ {
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
{ {
for (int j = 0; j < appearance.Wearables[i].Count; j++) for (int j = 0; j < appearance.Wearables[i].Count; j++)
{ {
// Check if the default wearables are not set
if (appearance.Wearables[i][j].ItemID == UUID.Zero) if (appearance.Wearables[i][j].ItemID == UUID.Zero)
{ {
switch ((WearableType) i) m_log.WarnFormat(
{ "[AVFACTORY]: Wearable item {0}:{1} for user {2} unexpectedly UUID.Zero. Ignoring.",
case WearableType.Eyes: i, j, userID);
case WearableType.Hair:
case WearableType.Shape:
case WearableType.Skin:
//case WearableType.Underpants:
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
resetwearable = true;
m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
resetwearable = true;
break;
}
continue; continue;
} }
// Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1 // Ignore ruth's assets
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
{
switch ((WearableType)i)
{
case WearableType.Eyes:
case WearableType.Hair:
case WearableType.Shape:
case WearableType.Skin:
//case WearableType.Underpants:
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
resetwearable = true;
break;
}
continue; continue;
}
InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
baseItem = invService.GetItem(baseItem); baseItem = invService.GetItem(baseItem);
if (baseItem != null) if (baseItem != null)
{ {
appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
int unmodifiedWearableIndexForClosure = i;
m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
delegate(string x, object y, AssetBase z)
{
if (z == null)
{
TryAndRepairBrokenWearable(
(WearableType)unmodifiedWearableIndexForClosure, invService,
userID, appearance);
}
});
} }
else else
{ {
m_log.ErrorFormat( m_log.WarnFormat(
"[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
appearance.Wearables[i][j].ItemID, (WearableType)i); appearance.Wearables[i][j].ItemID, (WearableType)i);
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
resetwearable = true;
} }
} }
} }
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int) WearableType.Eyes] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
resetwearable = true;
}
}
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int)WearableType.Shape] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
appearance.Wearables[(int)WearableType.Shape][0].ItemID,
appearance.Wearables[(int)WearableType.Shape][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
resetwearable = true;
}
}
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int)WearableType.Hair] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
appearance.Wearables[(int)WearableType.Hair][0].ItemID,
appearance.Wearables[(int)WearableType.Hair][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
resetwearable = true;
}
}
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
if (appearance.Wearables[(int)WearableType.Skin] == null)
{
m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
resetwearable = true;
}
else
{
if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
{
m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
appearance.Wearables[(int)WearableType.Skin][0].ItemID,
appearance.Wearables[(int)WearableType.Skin][0].AssetID);
TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
resetwearable = true;
}
}
if (resetwearable)
{
ScenePresence presence = null;
if (m_scene.TryGetScenePresence(userID, out presence))
{
presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
presence.Appearance.Serial++);
}
}
} }
else else
{ {
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
} }
// IInventoryService invService = m_scene.InventoryService;
// bool resetwearable = false;
// if (invService.GetRootFolder(userID) != null)
// {
// for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
// {
// for (int j = 0; j < appearance.Wearables[i].Count; j++)
// {
// // Check if the default wearables are not set
// if (appearance.Wearables[i][j].ItemID == UUID.Zero)
// {
// switch ((WearableType) i)
// {
// case WearableType.Eyes:
// case WearableType.Hair:
// case WearableType.Shape:
// case WearableType.Skin:
// //case WearableType.Underpants:
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
// resetwearable = true;
// m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
// resetwearable = true;
// break;
//
// }
// continue;
// }
//
// // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
// if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
// {
// switch ((WearableType)i)
// {
// case WearableType.Eyes:
// case WearableType.Hair:
// case WearableType.Shape:
// case WearableType.Skin:
// //case WearableType.Underpants:
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
//
// m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
// resetwearable = true;
// break;
//
// }
// continue;
// }
//
// InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
// baseItem = invService.GetItem(baseItem);
//
// if (baseItem != null)
// {
// appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
// int unmodifiedWearableIndexForClosure = i;
// m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
// delegate(string x, object y, AssetBase z)
// {
// if (z == null)
// {
// TryAndRepairBrokenWearable(
// (WearableType)unmodifiedWearableIndexForClosure, invService,
// userID, appearance);
// }
// });
// }
// else
// {
// m_log.ErrorFormat(
// "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
// appearance.Wearables[i][j].ItemID, (WearableType)i);
//
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
// resetwearable = true;
//
// }
// }
// }
//
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int) WearableType.Eyes] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
//
// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
// appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
// appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Shape] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
//
// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Shape][0].ItemID,
// appearance.Wearables[(int)WearableType.Shape][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Hair] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
//
// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Hair][0].ItemID,
// appearance.Wearables[(int)WearableType.Hair][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Skin] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
//
// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Skin][0].ItemID,
// appearance.Wearables[(int)WearableType.Skin][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// if (resetwearable)
// {
// ScenePresence presence = null;
// if (m_scene.TryGetScenePresence(userID, out presence))
// {
// presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
// presence.Appearance.Serial++);
// }
// }
//
// }
// else
// {
// m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
// }
} }
private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance) private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
{ {
UUID defaultwearable = GetDefaultItem(type); UUID defaultwearable = GetDefaultItem(type);
@ -957,6 +1008,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
} }
} }
} }
private UUID GetDefaultItem(WearableType wearable) private UUID GetDefaultItem(WearableType wearable)
{ {
// These are ruth // These are ruth

View File

@ -282,7 +282,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
string uasURL = circuit.ServiceURLs["HomeURI"].ToString(); string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL); m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL); UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
return uasConn.GetUUI(fromAgent, toAgent);
string agentUUI = string.Empty;
try
{
agentUUI = uasConn.GetUUI(fromAgent, toAgent);
}
catch (Exception e) {
m_log.Debug("[HG MESSAGE TRANSFER]: GetUUI call failed ", e);
}
return agentUUI;
} }
} }
} }

View File

@ -1164,7 +1164,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url); UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url);
Dictionary<string, object> account = uConn.GetUserInfo(userID); Dictionary<string, object> account;
try
{
account = uConn.GetUserInfo(userID);
}
catch (Exception e)
{
m_log.Debug("[PROFILES]: GetUserInfo call failed ", e);
account = new Dictionary<string, object>();
}
if (account.Count > 0) if (account.Count > 0)
{ {

View File

@ -464,7 +464,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, position, sp.Scene.RegionInfo.RegionName); sp.Name, position, sp.Scene.RegionInfo.RegionName);
// Teleport within the same region // Teleport within the same region
if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) if (!sp.Scene.PositionIsInCurrentRegion(position) || position.Z < 0)
{ {
Vector3 emergencyPos = new Vector3(128, 128, 128); Vector3 emergencyPos = new Vector3(128, 128, 128);
@ -580,7 +580,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
MapBlockData block = new MapBlockData(); MapBlockData block = new MapBlockData();
block.X = (ushort)regX; block.X = (ushort)regX;
block.Y = (ushort)regY; block.Y = (ushort)regY;
block.Access = 254; // == not there block.Access = (byte)SimAccess.Down;
List<MapBlockData> blocks = new List<MapBlockData>(); List<MapBlockData> blocks = new List<MapBlockData>();
blocks.Add(block); blocks.Add(block);
@ -713,10 +713,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return; return;
} }
uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionX, newRegionY, oldRegionX, oldRegionY;
uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY);
uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY);
uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8);
ulong destinationHandle = finalDestination.RegionHandle; ulong destinationHandle = finalDestination.RegionHandle;
@ -1333,6 +1332,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return region; return region;
} }
// This returns 'true' if the new region already has a child agent for our
// incoming agent. The implication is that, if 'false', we have to create the
// child and then teleport into the region.
protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY)
{ {
if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
@ -1357,20 +1359,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
} }
protected virtual bool IsOutsideRegion(Scene s, Vector3 pos)
{
if (s.TestBorderCross(pos, Cardinals.N))
return true;
if (s.TestBorderCross(pos, Cardinals.S))
return true;
if (s.TestBorderCross(pos, Cardinals.E))
return true;
if (s.TestBorderCross(pos, Cardinals.W))
return true;
return false;
}
#endregion #endregion
#region Landmark Teleport #region Landmark Teleport
@ -1455,10 +1443,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// see that it is actually outside the current region), find the new region that the // see that it is actually outside the current region), find the new region that the
// point is actually in. // point is actually in.
// Returns the coordinates and information of the new region or 'null' of it doesn't exist. // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
out string version, out Vector3 newpos, out string failureReason)
{ {
version = String.Empty; version = String.Empty;
newpos = pos; newpos = pos;
failureReason = string.Empty;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
@ -1475,12 +1465,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (neighbourRegion != null) if (neighbourRegion != null)
{ {
// Compute the entity's position relative to the new region // Compute the entity's position relative to the new region
newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX), newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
(float)(presenceWorldY - (double)neighbourRegion.RegionLocY), (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
pos.Z); pos.Z);
if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
{ {
failureReason = "Cannot region cross into banned parcel";
neighbourRegion = null; neighbourRegion = null;
} }
else else
@ -1490,15 +1481,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
// Check to see if we have access to the target region. // Check to see if we have access to the target region.
string reason;
if (neighbourRegion != null if (neighbourRegion != null
&& !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out failureReason))
{ {
// remember banned // remember banned
m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
neighbourRegion = null; neighbourRegion = null;
} }
} }
else
{
// The destination region just doesn't exist
failureReason = "Cannot cross into non-existant region";
}
if (neighbourRegion == null) if (neighbourRegion == null)
m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}", m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}",
@ -1521,11 +1516,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
uint y; uint y;
Vector3 newpos; Vector3 newpos;
string version; string version;
string failureReason;
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos); GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition,
out version, out newpos, out failureReason);
if (neighbourRegion == null) if (neighbourRegion == null)
{ {
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); agent.ControllingClient.SendAlertMessage(failureReason);
return false; return false;
} }
@ -1534,6 +1531,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion);
return true; return true;
} }
@ -2077,7 +2076,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public NotFoundLocationCache() public NotFoundLocationCache()
{ {
} }
// Add an area to the lost of 'not found' places. The area is the snapped region // Add an area to the list of 'not found' places. The area is the snapped region
// area around the added point. // area around the added point.
public void Add(double pX, double pY) public void Add(double pX, double pY)
{ {
@ -2305,22 +2304,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <param name='neCorner'></param> /// <param name='neCorner'></param>
private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner)
{ {
Border[] northBorders = Scene.NorthBorders.ToArray();
Border[] eastBorders = Scene.EastBorders.ToArray();
Vector2 extent = Vector2.Zero; Vector2 extent = Vector2.Zero;
for (int i = 0; i < eastBorders.Length; i++)
{
extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X;
}
for (int i = 0; i < northBorders.Length; i++)
{
extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y;
}
// Loss of fraction on purpose if (m_regionCombinerModule != null)
extent.X = ((int)extent.X / (int)Constants.RegionSize); {
extent.Y = ((int)extent.Y / (int)Constants.RegionSize); Vector2 megaRegionSize = m_regionCombinerModule.GetSizeOfMegaregion(Scene.RegionInfo.RegionID);
extent.X = (float)Util.WorldToRegionLoc((uint)megaRegionSize.X);
extent.Y = (float)Util.WorldToRegionLoc((uint)megaRegionSize.Y);
}
swCorner.X = Scene.RegionInfo.RegionLocX - 1; swCorner.X = Scene.RegionInfo.RegionLocX - 1;
swCorner.Y = Scene.RegionInfo.RegionLocY - 1; swCorner.Y = Scene.RegionInfo.RegionLocY - 1;

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -462,7 +462,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString());
Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY;
GridRegion finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt);
GridRegion finalDestination = null;
try
{
finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt);
}
catch (Exception e)
{
m_log.Debug("[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e);
}
if (finalDestination == null) if (finalDestination == null)
{ {
client.SendTeleportFailed("Your home region could not be found"); client.SendTeleportFailed("Your home region could not be found");

View File

@ -130,7 +130,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
} }
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr); UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
UUID userID = uasConn.GetUUID(names[0], names[1]);
UUID userID = UUID.Zero;
try
{
userID = uasConn.GetUUID(names[0], names[1]);
}
catch (Exception e)
{
m_log.Debug("[USER MANAGEMENT MODULE]: GetUUID call failed ", e);
}
if (!userID.Equals(UUID.Zero)) if (!userID.Equals(UUID.Zero))
{ {
UserData ud = new UserData(); UserData ud = new UserData();

View File

@ -473,7 +473,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
// serverType, userdata.HomeURL, userID); // serverType, userdata.HomeURL, userID);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
userdata.ServerURLs = uConn.GetServerURLs(userID); try
{
userdata.ServerURLs = uConn.GetServerURLs(userID);
}
catch (Exception e)
{
m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e);
userdata.ServerURLs = new Dictionary<string, object>();
}
if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
return userdata.ServerURLs[serverType].ToString(); return userdata.ServerURLs[serverType].ToString();
} }

View File

@ -126,7 +126,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid
foreach (MapBlockData b in mapBlocks) foreach (MapBlockData b in mapBlocks)
{ {
b.Name = string.Empty; b.Name = string.Empty;
b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's // Set 'simulator is offline'. We need this because the viewer ignores SimAccess.Unknown (255)
b.Access = (byte)SimAccess.Down;
} }
m_log.DebugFormat("[HG MAP]: Resetting {0} blocks", mapBlocks.Count); m_log.DebugFormat("[HG MAP]: Resetting {0} blocks", mapBlocks.Count);

View File

@ -125,14 +125,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour
public OpenSim.Services.Interfaces.GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) public OpenSim.Services.Interfaces.GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
{ {
uint x, y; uint x, y;
Utils.LongToUInts(regionHandle, out x, out y); Util.RegionHandleToRegionLoc(regionHandle, out x, out y);
foreach (Scene s in m_Scenes) foreach (Scene s in m_Scenes)
{ {
if (s.RegionInfo.RegionHandle == regionHandle) if (s.RegionInfo.RegionHandle == regionHandle)
{ {
m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}", m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}",
thisRegion.RegionName, s.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y) ); thisRegion.RegionName, s.Name, x, y );
//m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour"); //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour");
return s.IncomingHelloNeighbour(thisRegion); return s.IncomingHelloNeighbour(thisRegion);

View File

@ -483,7 +483,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject);
// Happily this does not do much to the object since it hasn't been added to the scene yet // Happily this does not do much to the object since it hasn't been added to the scene yet
if (sceneObject.AttachmentPoint == 0) if (!sceneObject.IsAttachment)
{ {
if (m_displacement != Vector3.Zero || m_rotation != 0f) if (m_displacement != Vector3.Zero || m_rotation != 0f)
{ {

View File

@ -631,16 +631,29 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
private warp_Texture GetTexture(UUID id) private warp_Texture GetTexture(UUID id)
{ {
warp_Texture ret = null; warp_Texture ret = null;
byte[] asset = m_scene.AssetService.GetData(id.ToString()); byte[] asset = m_scene.AssetService.GetData(id.ToString());
if (asset != null) if (asset != null)
{ {
IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>(); IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
Bitmap img = (Bitmap) imgDecoder.DecodeToImage(asset); Bitmap img = null;
try
{
img = (Bitmap)imgDecoder.DecodeToImage(asset);
}
catch (Exception e)
{
m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id), e);
}
if (img != null) if (img != null)
{ {
return new warp_Texture(img); return new warp_Texture(img);
} }
} }
return ret; return ret;
} }

View File

@ -214,7 +214,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
// final block, closing the search result // final block, closing the search result
MapBlockData data = new MapBlockData(); MapBlockData data = new MapBlockData();
data.Agents = 0; data.Agents = 0;
data.Access = 255; data.Access = (byte)SimAccess.NonExistent;
data.MapImageId = UUID.Zero; data.MapImageId = UUID.Zero;
data.Name = ""; data.Name = "";
data.RegionFlags = 0; data.RegionFlags = 0;

View File

@ -92,11 +92,12 @@ namespace OpenSim.Region.Framework.Interfaces
void EnableChildAgent(ScenePresence agent, GridRegion region); void EnableChildAgent(ScenePresence agent, GridRegion region);
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos); GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version,
out Vector3 newpos, out string reason);
void Cross(SceneObjectGroup sog, Vector3 position, bool silent); void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
} }
public interface IUserAgentVerificationModule public interface IUserAgentVerificationModule

View File

@ -55,5 +55,10 @@ namespace OpenSim.Region.Framework.Interfaces
/// Currently, will throw an exception if this does not match a root region. /// Currently, will throw an exception if this does not match a root region.
/// </param> /// </param>
Vector2 GetSizeOfMegaregion(UUID regionId); Vector2 GetSizeOfMegaregion(UUID regionId);
/// <summary>
/// Tests to see of position (relative to the region) is within the megaregion
/// </summary>
bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy);
} }
} }

View File

@ -430,6 +430,9 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void IncomingInstantMessage(GridInstantMessage message); public delegate void IncomingInstantMessage(GridInstantMessage message);
public event IncomingInstantMessage OnIncomingInstantMessage; public event IncomingInstantMessage OnIncomingInstantMessage;
public delegate void CrossAgentToNewRegion(ScenePresence sp, bool isFlying, GridRegion newRegion);
public event CrossAgentToNewRegion OnCrossAgentToNewRegion;
public event IncomingInstantMessage OnUnhandledInstantMessage; public event IncomingInstantMessage OnUnhandledInstantMessage;
public delegate void ClientClosed(UUID clientID, Scene scene); public delegate void ClientClosed(UUID clientID, Scene scene);
@ -1960,6 +1963,27 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerCrossAgentToNewRegion(ScenePresence agent, bool isFlying, GridRegion newRegion)
{
CrossAgentToNewRegion handlerCrossAgentToNewRegion = OnCrossAgentToNewRegion;
if (handlerCrossAgentToNewRegion != null)
{
foreach (CrossAgentToNewRegion d in handlerCrossAgentToNewRegion.GetInvocationList())
{
try
{
d(agent, isFlying, newRegion);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerCrossAgentToNewRegion failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
public void TriggerIncomingInstantMessage(GridInstantMessage message) public void TriggerIncomingInstantMessage(GridInstantMessage message)
{ {
IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage; IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage;

View File

@ -160,11 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public SimStatsReporter StatsReporter { get; private set; } public SimStatsReporter StatsReporter { get; private set; }
public List<Border> NorthBorders = new List<Border>();
public List<Border> EastBorders = new List<Border>();
public List<Border> SouthBorders = new List<Border>();
public List<Border> WestBorders = new List<Border>();
/// <summary> /// <summary>
/// Controls whether physics can be applied to prims. Even if false, prims still have entries in a /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a
/// PhysicsScene in order to perform collision detection /// PhysicsScene in order to perform collision detection
@ -218,7 +213,14 @@ namespace OpenSim.Region.Framework.Scenes
protected float m_defaultDrawDistance = 255.0f; protected float m_defaultDrawDistance = 255.0f;
public float DefaultDrawDistance public float DefaultDrawDistance
{ {
get { return m_defaultDrawDistance; } // get { return m_defaultDrawDistance; }
get {
if (RegionInfo != null)
{
m_defaultDrawDistance = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
}
return m_defaultDrawDistance;
}
} }
private List<string> m_AllowedViewers = new List<string>(); private List<string> m_AllowedViewers = new List<string>();
@ -349,7 +351,6 @@ namespace OpenSim.Region.Framework.Scenes
// TODO: Possibly stop other classes being able to manipulate this directly. // TODO: Possibly stop other classes being able to manipulate this directly.
private SceneGraph m_sceneGraph; private SceneGraph m_sceneGraph;
private volatile int m_bordersLocked;
private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
private volatile bool m_backingup; private volatile bool m_backingup;
private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
@ -426,18 +427,6 @@ namespace OpenSim.Region.Framework.Scenes
set { m_splitRegionID = value; } set { m_splitRegionID = value; }
} }
public bool BordersLocked
{
get { return m_bordersLocked == 1; }
set
{
if (value == true)
m_bordersLocked = 1;
else
m_bordersLocked = 0;
}
}
public new float TimeDilation public new float TimeDilation
{ {
get { return m_sceneGraph.PhysicsScene.TimeDilation; } get { return m_sceneGraph.PhysicsScene.TimeDilation; }
@ -1031,28 +1020,6 @@ namespace OpenSim.Region.Framework.Scenes
PeriodicBackup = true; PeriodicBackup = true;
UseBackup = true; UseBackup = true;
BordersLocked = true;
Border northBorder = new Border();
northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<---
northBorder.CrossDirection = Cardinals.N;
NorthBorders.Add(northBorder);
Border southBorder = new Border();
southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
southBorder.CrossDirection = Cardinals.S;
SouthBorders.Add(southBorder);
Border eastBorder = new Border();
eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<---
eastBorder.CrossDirection = Cardinals.E;
EastBorders.Add(eastBorder);
Border westBorder = new Border();
westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
westBorder.CrossDirection = Cardinals.W;
WestBorders.Add(westBorder);
BordersLocked = false;
m_eventManager = new EventManager(); m_eventManager = new EventManager();
m_permissions = new ScenePermissions(this); m_permissions = new ScenePermissions(this);
@ -2445,201 +2412,34 @@ namespace OpenSim.Region.Framework.Scenes
} }
// Simple test to see if a position is in the current region. // Simple test to see if a position is in the current region.
// Resuming the position is relative to the region so anything outside its bounds. // This test is mostly used to see if a region crossing is necessary.
// Assuming the position is relative to the region so anything outside its bounds.
// Return 'true' if position inside region. // Return 'true' if position inside region.
public bool PositionIsInCurrentRegion(Vector3 pos) public bool PositionIsInCurrentRegion(Vector3 pos)
{ {
bool ret = true; bool ret = false;
int xx = (int)Math.Floor(pos.X); int xx = (int)Math.Floor(pos.X);
int yy = (int)Math.Floor(pos.Y); int yy = (int)Math.Floor(pos.Y);
if (xx < 0 if (xx < 0 || yy < 0)
|| xx >= RegionInfo.RegionSizeX return false;
|| yy < 0
|| yy >= RegionInfo.RegionSizeY) IRegionCombinerModule regionCombinerModule = RequestModuleInterface<IRegionCombinerModule>();
ret = false; if (regionCombinerModule == null)
{
// Regular region. Just check for region size
if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY )
ret = true;
}
else
{
// We're in a mega-region so see if we are still in that larger region
ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy);
}
return ret; return ret;
} }
public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
{
if (BordersLocked)
{
switch (gridline)
{
case Cardinals.N:
lock (NorthBorders)
{
foreach (Border b in NorthBorders)
{
if (b.TestCross(position))
return b;
}
}
break;
case Cardinals.S:
lock (SouthBorders)
{
foreach (Border b in SouthBorders)
{
if (b.TestCross(position))
return b;
}
}
break;
case Cardinals.E:
lock (EastBorders)
{
foreach (Border b in EastBorders)
{
if (b.TestCross(position))
return b;
}
}
break;
case Cardinals.W:
lock (WestBorders)
{
foreach (Border b in WestBorders)
{
if (b.TestCross(position))
return b;
}
}
break;
}
}
else
{
switch (gridline)
{
case Cardinals.N:
foreach (Border b in NorthBorders)
{
if (b.TestCross(position))
return b;
}
break;
case Cardinals.S:
foreach (Border b in SouthBorders)
{
if (b.TestCross(position))
return b;
}
break;
case Cardinals.E:
foreach (Border b in EastBorders)
{
if (b.TestCross(position))
return b;
}
break;
case Cardinals.W:
foreach (Border b in WestBorders)
{
if (b.TestCross(position))
return b;
}
break;
}
}
return null;
}
public bool TestBorderCross(Vector3 position, Cardinals border)
{
if (BordersLocked)
{
switch (border)
{
case Cardinals.N:
lock (NorthBorders)
{
foreach (Border b in NorthBorders)
{
if (b.TestCross(position))
return true;
}
}
break;
case Cardinals.E:
lock (EastBorders)
{
foreach (Border b in EastBorders)
{
if (b.TestCross(position))
return true;
}
}
break;
case Cardinals.S:
lock (SouthBorders)
{
foreach (Border b in SouthBorders)
{
if (b.TestCross(position))
return true;
}
}
break;
case Cardinals.W:
lock (WestBorders)
{
foreach (Border b in WestBorders)
{
if (b.TestCross(position))
return true;
}
}
break;
}
}
else
{
switch (border)
{
case Cardinals.N:
foreach (Border b in NorthBorders)
{
if (b.TestCross(position))
return true;
}
break;
case Cardinals.E:
foreach (Border b in EastBorders)
{
if (b.TestCross(position))
return true;
}
break;
case Cardinals.S:
foreach (Border b in SouthBorders)
{
if (b.TestCross(position))
return true;
}
break;
case Cardinals.W:
foreach (Border b in WestBorders)
{
if (b.TestCross(position))
return true;
}
break;
}
}
return false;
}
/// <summary> /// <summary>
/// Called when objects or attachments cross the border, or teleport, between regions. /// Called when objects or attachments cross the border, or teleport, between regions.
/// </summary> /// </summary>
@ -3874,61 +3674,11 @@ namespace OpenSim.Region.Framework.Scenes
{ {
// CleanDroppedAttachments(); // CleanDroppedAttachments();
if (TestBorderCross(acd.startpos, Cardinals.E)) // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking)
{ if (acd.startpos.X < 0) acd.startpos.X = 1f;
Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); if (acd.startpos.X >= RegionInfo.RegionSizeX) acd.startpos.X = RegionInfo.RegionSizeX - 1f;
acd.startpos.X = crossedBorder.BorderLine.Z - 1; if (acd.startpos.Y < 0) acd.startpos.Y = 1f;
m_log.DebugFormat("{0} NewUserConnection Adjusted border E. startpos={1}", LogHeader, acd.startpos); if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f;
}
if (TestBorderCross(acd.startpos, Cardinals.N))
{
Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N);
acd.startpos.Y = crossedBorder.BorderLine.Z - 1;
}
//Mitigate http://opensimulator.org/mantis/view.php?id=3522
// Check if start position is outside of region
// If it is, check the Z start position also.. if not, leave it alone.
if (BordersLocked)
{
lock (EastBorders)
{
if (acd.startpos.X > EastBorders[0].BorderLine.Z)
{
m_log.Warn("FIX AGENT POSITION");
acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
if (acd.startpos.Z > 720)
acd.startpos.Z = 720;
}
}
lock (NorthBorders)
{
if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
{
m_log.Warn("FIX Agent POSITION");
acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
if (acd.startpos.Z > 720)
acd.startpos.Z = 720;
}
}
} else
{
if (acd.startpos.X > EastBorders[0].BorderLine.Z)
{
m_log.Warn("FIX AGENT POSITION");
acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
if (acd.startpos.Z > 720)
acd.startpos.Z = 720;
}
if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
{
m_log.Warn("FIX Agent POSITION");
acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
if (acd.startpos.Z > 720)
acd.startpos.Z = 720;
}
}
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}",

View File

@ -429,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns></returns> /// <returns></returns>
public bool IsAttachmentCheckFull() public bool IsAttachmentCheckFull()
{ {
return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); return (IsAttachment || (m_rootPart.Shape.PCode == (byte)PCodeEnum.Primitive && m_rootPart.Shape.State != 0));
} }
private struct avtocrossInfo private struct avtocrossInfo
@ -451,23 +451,15 @@ namespace OpenSim.Region.Framework.Scenes
if (Scene != null) if (Scene != null)
{ {
if ( if (
// (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) !Scene.PositionIsInCurrentRegion(val)
// || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) && !IsAttachmentCheckFull()
// || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) && (!Scene.LoadingPrims)
// || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) )
// Experimental change for better border crossings.
// The commented out original lines above would, it seems, trigger
// a border crossing a little early or late depending on which
// direction the object was moving.
(Scene.TestBorderCross(val, Cardinals.E)
|| Scene.TestBorderCross(val, Cardinals.W)
|| Scene.TestBorderCross(val, Cardinals.N)
|| Scene.TestBorderCross(val, Cardinals.S))
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
{ {
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
string version = String.Empty; string version = String.Empty;
Vector3 newpos = Vector3.Zero; Vector3 newpos = Vector3.Zero;
string failureReason = String.Empty;
OpenSim.Services.Interfaces.GridRegion destination = null; OpenSim.Services.Interfaces.GridRegion destination = null;
if (m_rootPart.KeyframeMotion != null) if (m_rootPart.KeyframeMotion != null)
@ -485,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes
// We set the avatar position as being the object // We set the avatar position as being the object
// position to get the region to send to // position to get the region to send to
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos)) == null) if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos, out failureReason)) == null)
{ {
canCross = false; canCross = false;
break; break;

View File

@ -2479,13 +2479,10 @@ namespace OpenSim.Region.Framework.Scenes
if (pa != null) if (pa != null)
{ {
Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); Vector3 newpos = pa.Position;
if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos))
if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
{ {
// Setting position outside current region will start region crossing
ParentGroup.AbsolutePosition = newpos; ParentGroup.AbsolutePosition = newpos;
return; return;
} }

View File

@ -1057,30 +1057,32 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
UUID groupUUID = UUID.Zero; UUID groupUUID = ControllingClient.ActiveGroupId;
string GroupName = string.Empty; string groupName = string.Empty;
ulong groupPowers = 0; ulong groupPowers = 0;
// ---------------------------------- // ----------------------------------
// Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
try try
{ {
if (gm != null) if (groupUUID != UUID.Zero && gm != null)
{ {
groupUUID = ControllingClient.ActiveGroupId;
GroupRecord record = gm.GetGroupRecord(groupUUID); GroupRecord record = gm.GetGroupRecord(groupUUID);
if (record != null) if (record != null)
GroupName = record.GroupName; groupName = record.GroupName;
GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
if (groupMembershipData != null) if (groupMembershipData != null)
groupPowers = groupMembershipData.GroupPowers; groupPowers = groupMembershipData.GroupPowers;
} }
ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
Grouptitle); ControllingClient.SendAgentDataUpdate(
m_uuid, groupUUID, Firstname, Lastname, groupPowers, groupName, Grouptitle);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Debug("[AGENTUPDATE]: " + e.ToString()); m_log.Error("[AGENTUPDATE]: Error ", e);
} }
// ------------------------------------ // ------------------------------------
@ -3471,8 +3473,6 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 pos2 = AbsolutePosition; Vector3 pos2 = AbsolutePosition;
Vector3 origPosition = pos2; Vector3 origPosition = pos2;
Vector3 vel = Velocity; Vector3 vel = Velocity;
int neighbor = 0;
int[] fix = new int[2];
// Compute the avatar position in the next physics tick. // Compute the avatar position in the next physics tick.
// If the avatar will be crossing, we force the crossing to happen now // If the avatar will be crossing, we force the crossing to happen now
@ -3505,23 +3505,13 @@ namespace OpenSim.Region.Framework.Scenes
if (m_requestedSitTargetUUID == UUID.Zero) if (m_requestedSitTargetUUID == UUID.Zero)
{ {
m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader); m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader);
const float borderFudge = 0.1f;
if (origPosition.X < 0)
origPosition.X = borderFudge;
else if (origPosition.X > (float)m_scene.RegionInfo.RegionSizeX)
origPosition.X = (float)m_scene.RegionInfo.RegionSizeX - borderFudge;
if (origPosition.Y < 0)
origPosition.Y = borderFudge;
else if (origPosition.Y > (float)m_scene.RegionInfo.RegionSizeY)
origPosition.Y = (float)m_scene.RegionInfo.RegionSizeY - borderFudge;
Velocity = Vector3.Zero; Velocity = Vector3.Zero;
AbsolutePosition = origPosition; AbsolutePosition = EnforceSanityOnPosition(origPosition);
AddToPhysicalScene(isFlying); AddToPhysicalScene(isFlying);
} }
} }
} }
} }
else else
@ -3539,6 +3529,36 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
// Given a position, make sure it is within the current region.
// If just outside some border, the returned position will be just inside the border on that side.
private Vector3 EnforceSanityOnPosition(Vector3 origPosition)
{
const float borderFudge = 0.1f;
Vector3 ret = origPosition;
// Sanity checking on the position to make sure it is in the region we couldn't cross from
float extentX = (float)m_scene.RegionInfo.RegionSizeX;
float extentY = (float)m_scene.RegionInfo.RegionSizeY;
IRegionCombinerModule combiner = m_scene.RequestModuleInterface<IRegionCombinerModule>();
if (combiner != null)
{
// If a mega-region, the size could be much bigger
Vector2 megaExtent = combiner.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
extentX = megaExtent.X;
extentY = megaExtent.Y;
}
if (ret.X < 0)
ret.X = borderFudge;
else if (ret.X >= extentX)
ret.X = extentX - borderFudge;
if (ret.Y < 0)
ret.Y = borderFudge;
else if (ret.Y >= extentY)
ret.Y = extentY - borderFudge;
return ret;
}
/// <summary> /// <summary>
/// Moves the agent outside the region bounds /// Moves the agent outside the region bounds
/// Tells neighbor region that we're crossing to it /// Tells neighbor region that we're crossing to it

View File

@ -1012,7 +1012,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
Hashtable respData = (Hashtable)resp.Value; Hashtable respData = (Hashtable)resp.Value;
if (respData.Contains("error") && !respData.Contains("succeed")) if (respData.Contains("error") && !respData.Contains("succeed"))
{ {
LogRespDataToConsoleError(respData); LogRespDataToConsoleError(requestingAgentID, function, param, respData);
} }
return respData; return respData;
@ -1040,20 +1040,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return error; return error;
} }
private void LogRespDataToConsoleError(Hashtable respData) private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData)
{ {
m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); m_log.ErrorFormat(
"[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}",
foreach (string key in respData.Keys) function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData));
{
m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key);
string[] lines = respData[key].ToString().Split(new char[] { '\n' });
foreach (string line in lines)
{
m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line);
}
}
} }
/// <summary> /// <summary>

View File

@ -116,37 +116,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
+ "If teleport is true then some extra teleport debug information is logged.\n" + "If teleport is true then some extra teleport debug information is logged.\n"
+ "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.",
HandleDebugSceneSetCommand); HandleDebugSceneSetCommand);
scene.AddCommand(
"Regions",
this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand);
}
private void HandleShowBordersCommand(string module, string[] args)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Borders for {0}:\n", m_scene.Name);
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Cross Direction", 15);
cdt.AddColumn("Line", 34);
cdt.AddColumn("Trigger Region", 14);
foreach (Border b in m_scene.NorthBorders)
cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
foreach (Border b in m_scene.EastBorders)
cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
foreach (Border b in m_scene.SouthBorders)
cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
foreach (Border b in m_scene.WestBorders)
cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
cdt.AddToStringBuilder(sb);
MainConsole.Instance.Output(sb.ToString());
} }
private void HandleDebugSceneGetCommand(string module, string[] args) private void HandleDebugSceneGetCommand(string module, string[] args)

View File

@ -44,6 +44,7 @@ namespace OpenSim.Region.RegionCombinerModule
public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static string LogHeader = "[REGION COMBINER MODULE]";
public string Name public string Name
{ {
@ -134,6 +135,49 @@ namespace OpenSim.Region.RegionCombinerModule
throw new Exception(string.Format("Region with id {0} not found", regionId)); throw new Exception(string.Format("Region with id {0} not found", regionId));
} }
// Test to see if this postiion (relative to the region) is within the area covered
// by this megaregion.
public bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy)
{
bool ret = false;
if (xx < 0 || yy < 0)
return ret;
foreach (RegionConnections rootRegion in m_regions.Values)
{
if (currentRegion == rootRegion.RegionId)
{
// The caller is in the root region so this is an easy test
if (xx < rootRegion.XEnd && yy < rootRegion.YEnd)
{
ret = true;
}
break;
}
else
{
// Maybe the caller is in one of the sub-regions
foreach (RegionData childRegion in rootRegion.ConnectedRegions)
{
if (currentRegion == childRegion.RegionId)
{
// This is a child. Diddle the offsets and check if in
Vector3 positionInMegaregion = childRegion.Offset;
positionInMegaregion.X += xx;
positionInMegaregion.Y += yy;
if (positionInMegaregion.X < rootRegion.XEnd && positionInMegaregion.Y < rootRegion.YEnd)
{
ret = true;
}
break;
}
}
}
}
return ret;
}
private void NewPresence(ScenePresence presence) private void NewPresence(ScenePresence presence)
{ {
if (presence.IsChildAgent) if (presence.IsChildAgent)
@ -220,27 +264,6 @@ namespace OpenSim.Region.RegionCombinerModule
// //
*/ */
// Give each region a standard set of non-infinite borders
Border northBorder = new Border();
northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
northBorder.CrossDirection = Cardinals.N;
scene.NorthBorders[0] = northBorder;
Border southBorder = new Border();
southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
southBorder.CrossDirection = Cardinals.S;
scene.SouthBorders[0] = southBorder;
Border eastBorder = new Border();
eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
eastBorder.CrossDirection = Cardinals.E;
scene.EastBorders[0] = eastBorder;
Border westBorder = new Border();
westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
westBorder.CrossDirection = Cardinals.W;
scene.WestBorders[0] = westBorder;
RegionConnections newConn = new RegionConnections(); RegionConnections newConn = new RegionConnections();
newConn.ConnectedRegions = new List<RegionData>(); newConn.ConnectedRegions = new List<RegionData>();
newConn.RegionScene = scene; newConn.RegionScene = scene;
@ -248,8 +271,8 @@ namespace OpenSim.Region.RegionCombinerModule
newConn.RegionId = scene.RegionInfo.originRegionID; newConn.RegionId = scene.RegionInfo.originRegionID;
newConn.X = scene.RegionInfo.RegionLocX; newConn.X = scene.RegionInfo.RegionLocX;
newConn.Y = scene.RegionInfo.RegionLocY; newConn.Y = scene.RegionInfo.RegionLocY;
newConn.XEnd = (int)Constants.RegionSize; newConn.XEnd = scene.RegionInfo.RegionSizeX;
newConn.YEnd = (int)Constants.RegionSize; newConn.YEnd = scene.RegionInfo.RegionSizeX;
lock (m_regions) lock (m_regions)
{ {
@ -415,6 +438,11 @@ namespace OpenSim.Region.RegionCombinerModule
*/ */
#endregion #endregion
// Check to see if this new region is adjacent to the root region.
// Note that we expect the regions to be combined from the root region outward
// thus the requirement for the ordering in the configuration files.
// If we're one region over +x y (i.e. root region is to the west) // If we're one region over +x y (i.e. root region is to the west)
//xxx //xxx
//xxy //xxy
@ -431,7 +459,7 @@ namespace OpenSim.Region.RegionCombinerModule
//xxx //xxx
if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
{ {
connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
break; break;
} }
@ -441,9 +469,8 @@ namespace OpenSim.Region.RegionCombinerModule
//xxx //xxx
if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
{ {
connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
break; break;
} }
} }
@ -453,20 +480,20 @@ namespace OpenSim.Region.RegionCombinerModule
DoWorkForRootRegion(newConn, scene); DoWorkForRootRegion(newConn, scene);
} }
} }
// Set up infinite borders around the entire AABB of the combined ConnectedRegions
AdjustLargeRegionBounds();
} }
private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene)
{ {
// Offset (in meters) from the base of this region to the base of the root region.
Vector3 offset = Vector3.Zero; Vector3 offset = Vector3.Zero;
offset.X = newConn.PosX - rootConn.PosX; offset.X = newConn.PosX - rootConn.PosX;
offset.Y = newConn.PosY - rootConn.PosY; offset.Y = newConn.PosY - rootConn.PosY;
// The new total size of the region (in meters)
// We just extend the X and Y dimensions so the extent might temporarily include areas without regions.
Vector3 extents = Vector3.Zero; Vector3 extents = Vector3.Zero;
extents.Y = rootConn.YEnd; extents.X = Math.Max(rootConn.XEnd, offset.X + newConn.RegionScene.RegionInfo.RegionSizeX);
extents.X = rootConn.XEnd + newConn.XEnd; extents.Y = Math.Max(rootConn.YEnd, offset.Y + newConn.RegionScene.RegionInfo.RegionSizeY);
rootConn.UpdateExtents(extents); rootConn.UpdateExtents(extents);
@ -475,9 +502,6 @@ namespace OpenSim.Region.RegionCombinerModule
rootConn.RegionScene.RegionInfo.RegionName, rootConn.RegionScene.RegionInfo.RegionName,
newConn.RegionScene.RegionInfo.RegionName, offset, extents); newConn.RegionScene.RegionInfo.RegionName, offset, extents);
scene.BordersLocked = true;
rootConn.RegionScene.BordersLocked = true;
RegionData ConnectedRegion = new RegionData(); RegionData ConnectedRegion = new RegionData();
ConnectedRegion.Offset = offset; ConnectedRegion.Offset = offset;
ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
@ -490,34 +514,10 @@ namespace OpenSim.Region.RegionCombinerModule
// Inform Child region that it needs to forward it's terrain to the root region // Inform Child region that it needs to forward it's terrain to the root region
scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
// Extend the borders as appropriate
lock (rootConn.RegionScene.EastBorders)
rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
lock (rootConn.RegionScene.NorthBorders)
rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
lock (rootConn.RegionScene.SouthBorders)
rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
lock (scene.WestBorders)
{
scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
// Trigger auto teleport to root region
scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
}
// Reset Terrain.. since terrain loads before we get here, we need to load // Reset Terrain.. since terrain loads before we get here, we need to load
// it again so it loads in the root region // it again so it loads in the root region
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
// Unlock borders
rootConn.RegionScene.BordersLocked = false;
scene.BordersLocked = false;
// Create a client event forwarder and add this region's events to the root region. // Create a client event forwarder and add this region's events to the root region.
if (rootConn.ClientEventForwarder != null) if (rootConn.ClientEventForwarder != null)
rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
@ -525,6 +525,9 @@ namespace OpenSim.Region.RegionCombinerModule
return true; return true;
} }
/*
* 20140215 radams1: The border stuff was removed and the addition of regions to the mega-regions
* was generalized. These functions are not needed for the generalized solution but left for reference.
private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene)
{ {
Vector3 offset = Vector3.Zero; Vector3 offset = Vector3.Zero;
@ -536,9 +539,6 @@ namespace OpenSim.Region.RegionCombinerModule
extents.X = rootConn.XEnd; extents.X = rootConn.XEnd;
rootConn.UpdateExtents(extents); rootConn.UpdateExtents(extents);
scene.BordersLocked = true;
rootConn.RegionScene.BordersLocked = true;
RegionData ConnectedRegion = new RegionData(); RegionData ConnectedRegion = new RegionData();
ConnectedRegion.Offset = offset; ConnectedRegion.Offset = offset;
ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
@ -553,30 +553,11 @@ namespace OpenSim.Region.RegionCombinerModule
rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
lock (rootConn.RegionScene.NorthBorders)
rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
lock (rootConn.RegionScene.EastBorders)
rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
lock (rootConn.RegionScene.WestBorders)
rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
lock (scene.SouthBorders)
{
scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
}
// Reset Terrain.. since terrain normally loads first. // Reset Terrain.. since terrain normally loads first.
//conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
//conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
scene.BordersLocked = false;
rootConn.RegionScene.BordersLocked = false;
if (rootConn.ClientEventForwarder != null) if (rootConn.ClientEventForwarder != null)
rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
@ -600,9 +581,6 @@ namespace OpenSim.Region.RegionCombinerModule
extents.Y = rootConn.YEnd; extents.Y = rootConn.YEnd;
extents.X = rootConn.XEnd; extents.X = rootConn.XEnd;
scene.BordersLocked = true;
rootConn.RegionScene.BordersLocked = true;
RegionData ConnectedRegion = new RegionData(); RegionData ConnectedRegion = new RegionData();
ConnectedRegion.Offset = offset; ConnectedRegion.Offset = offset;
ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
@ -618,67 +596,10 @@ namespace OpenSim.Region.RegionCombinerModule
rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
lock (rootConn.RegionScene.NorthBorders)
{
if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2)
{
//compound border
// already locked above
rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
lock (rootConn.RegionScene.EastBorders)
rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
lock (rootConn.RegionScene.WestBorders)
rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
}
}
lock (scene.SouthBorders)
{
scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
}
lock (rootConn.RegionScene.EastBorders)
{
if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2)
{
rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
lock (rootConn.RegionScene.NorthBorders)
rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
lock (rootConn.RegionScene.SouthBorders)
rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
}
}
lock (scene.WestBorders)
{
scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
}
/*
else
{
conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
}
*/
// Reset Terrain.. since terrain normally loads first. // Reset Terrain.. since terrain normally loads first.
//conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
//conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
scene.BordersLocked = false;
rootConn.RegionScene.BordersLocked = false;
if (rootConn.ClientEventForwarder != null) if (rootConn.ClientEventForwarder != null)
rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
@ -687,6 +608,7 @@ namespace OpenSim.Region.RegionCombinerModule
//scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents);
} }
*/
private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene)
{ {
@ -885,125 +807,6 @@ namespace OpenSim.Region.RegionCombinerModule
// } // }
// } // }
// Create a set of infinite borders around the whole aabb of the combined island.
private void AdjustLargeRegionBounds()
{
lock (m_regions)
{
foreach (RegionConnections rconn in m_regions.Values)
{
Vector3 offset = Vector3.Zero;
rconn.RegionScene.BordersLocked = true;
foreach (RegionData rdata in rconn.ConnectedRegions)
{
if (rdata.Offset.X > offset.X) offset.X = rdata.Offset.X;
if (rdata.Offset.Y > offset.Y) offset.Y = rdata.Offset.Y;
}
lock (rconn.RegionScene.NorthBorders)
{
Border northBorder = null;
// If we don't already have an infinite border, create one.
if (!TryGetInfiniteBorder(rconn.RegionScene.NorthBorders, out northBorder))
{
northBorder = new Border();
rconn.RegionScene.NorthBorders.Add(northBorder);
}
northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,
offset.Y + (int) Constants.RegionSize); //<---
northBorder.CrossDirection = Cardinals.N;
}
lock (rconn.RegionScene.SouthBorders)
{
Border southBorder = null;
// If we don't already have an infinite border, create one.
if (!TryGetInfiniteBorder(rconn.RegionScene.SouthBorders, out southBorder))
{
southBorder = new Border();
rconn.RegionScene.SouthBorders.Add(southBorder);
}
southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
southBorder.CrossDirection = Cardinals.S;
}
lock (rconn.RegionScene.EastBorders)
{
Border eastBorder = null;
// If we don't already have an infinite border, create one.
if (!TryGetInfiniteBorder(rconn.RegionScene.EastBorders, out eastBorder))
{
eastBorder = new Border();
rconn.RegionScene.EastBorders.Add(eastBorder);
}
eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, offset.X + (int)Constants.RegionSize);
//<---
eastBorder.CrossDirection = Cardinals.E;
}
lock (rconn.RegionScene.WestBorders)
{
Border westBorder = null;
// If we don't already have an infinite border, create one.
if (!TryGetInfiniteBorder(rconn.RegionScene.WestBorders, out westBorder))
{
westBorder = new Border();
rconn.RegionScene.WestBorders.Add(westBorder);
}
westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
westBorder.CrossDirection = Cardinals.W;
}
rconn.RegionScene.BordersLocked = false;
}
}
}
/// <summary>
/// Try and get an Infinite border out of a listT of borders
/// </summary>
/// <param name="borders"></param>
/// <param name="oborder"></param>
/// <returns></returns>
public static bool TryGetInfiniteBorder(List<Border> borders, out Border oborder)
{
// Warning! Should be locked before getting here!
foreach (Border b in borders)
{
if (b.BorderLine.X == float.MinValue && b.BorderLine.Y == float.MaxValue)
{
oborder = b;
return true;
}
}
oborder = null;
return false;
}
public RegionData GetRegionFromPosition(Vector3 pPosition)
{
pPosition = pPosition/(int) Constants.RegionSize;
int OffsetX = (int) pPosition.X;
int OffsetY = (int) pPosition.Y;
lock (m_regions)
{
foreach (RegionConnections regConn in m_regions.Values)
{
foreach (RegionData reg in regConn.ConnectedRegions)
{
if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY)
return reg;
}
}
}
return new RegionData();
}
public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion)
{ {
if (BigRegion.PermissionModule == null) if (BigRegion.PermissionModule == null)

View File

@ -34,6 +34,7 @@ namespace OpenSim.Region.RegionCombinerModule
{ {
public UUID RegionId; public UUID RegionId;
public Scene RegionScene; public Scene RegionScene;
// Offset of this region from the base of the root region.
public Vector3 Offset; public Vector3 Offset;
} }
} }

View File

@ -78,7 +78,8 @@ namespace OpenSim.Services.Connectors.Hypergrid
m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message); m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message);
} }
} }
m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL);
//m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL);
} }
public UserAgentServiceConnector(IConfigSource config) public UserAgentServiceConnector(IConfigSource config)
@ -190,6 +191,40 @@ namespace OpenSim.Services.Connectors.Hypergrid
// no-op // no-op
} }
private Hashtable CallServer(string methodName, Hashtable hash)
{
IList paramList = new ArrayList();
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest(methodName, paramList);
// Send and get reply
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
}
catch (Exception e)
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: {0} call to {1} failed: {2}", methodName, m_ServerURL, e.Message);
throw;
}
if (response.IsFault)
{
throw new Exception(string.Format("[USER AGENT CONNECTOR]: {0} call to {1} returned an error: {2}", methodName, m_ServerURL, response.FaultString));
}
hash = (Hashtable)response.Value;
if (hash == null)
{
throw new Exception(string.Format("[USER AGENT CONNECTOR]: {0} call to {1} returned null", methodName, m_ServerURL));
}
return hash;
}
public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt) public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
{ {
position = Vector3.UnitY; lookAt = Vector3.UnitY; position = Vector3.UnitY; lookAt = Vector3.UnitY;
@ -197,101 +232,58 @@ namespace OpenSim.Services.Connectors.Hypergrid
Hashtable hash = new Hashtable(); Hashtable hash = new Hashtable();
hash["userID"] = userID.ToString(); hash["userID"] = userID.ToString();
IList paramList = new ArrayList(); hash = CallServer("get_home_region", hash);
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList); bool success;
XmlRpcResponse response = null; if (!Boolean.TryParse((string)hash["result"], out success) || !success)
try
{
response = request.Send(m_ServerURL, 10000);
}
catch (Exception)
{
return null; return null;
}
if (response.IsFault) GridRegion region = new GridRegion();
UUID.TryParse((string)hash["uuid"], out region.RegionID);
//m_log.Debug(">> HERE, uuid: " + region.RegionID);
int n = 0;
if (hash["x"] != null)
{ {
return null; Int32.TryParse((string)hash["x"], out n);
region.RegionLocX = n;
//m_log.Debug(">> HERE, x: " + region.RegionLocX);
} }
if (hash["y"] != null)
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{ {
bool success = false; Int32.TryParse((string)hash["y"], out n);
Boolean.TryParse((string)hash["result"], out success); region.RegionLocY = n;
if (success) //m_log.Debug(">> HERE, y: " + region.RegionLocY);
{
GridRegion region = new GridRegion();
UUID.TryParse((string)hash["uuid"], out region.RegionID);
//m_log.Debug(">> HERE, uuid: " + region.RegionID);
int n = 0;
if (hash["x"] != null)
{
Int32.TryParse((string)hash["x"], out n);
region.RegionLocX = n;
//m_log.Debug(">> HERE, x: " + region.RegionLocX);
}
if (hash["y"] != null)
{
Int32.TryParse((string)hash["y"], out n);
region.RegionLocY = n;
//m_log.Debug(">> HERE, y: " + region.RegionLocY);
}
if (hash["size_x"] != null)
{
Int32.TryParse((string)hash["size_x"], out n);
region.RegionSizeX = n;
//m_log.Debug(">> HERE, x: " + region.RegionLocX);
}
if (hash["size_y"] != null)
{
Int32.TryParse((string)hash["size_y"], out n);
region.RegionSizeY = n;
//m_log.Debug(">> HERE, y: " + region.RegionLocY);
}
if (hash["region_name"] != null)
{
region.RegionName = (string)hash["region_name"];
//m_log.Debug(">> HERE, name: " + region.RegionName);
}
if (hash["hostname"] != null)
region.ExternalHostName = (string)hash["hostname"];
if (hash["http_port"] != null)
{
uint p = 0;
UInt32.TryParse((string)hash["http_port"], out p);
region.HttpPort = p;
}
if (hash.ContainsKey("server_uri") && hash["server_uri"] != null)
region.ServerURI = (string)hash["server_uri"];
if (hash["internal_port"] != null)
{
int p = 0;
Int32.TryParse((string)hash["internal_port"], out p);
region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
}
if (hash["position"] != null)
Vector3.TryParse((string)hash["position"], out position);
if (hash["lookAt"] != null)
Vector3.TryParse((string)hash["lookAt"], out lookAt);
// Successful return
return region;
}
} }
catch (Exception) if (hash["region_name"] != null)
{ {
return null; region.RegionName = (string)hash["region_name"];
//m_log.Debug(">> HERE, name: " + region.RegionName);
} }
if (hash["hostname"] != null)
region.ExternalHostName = (string)hash["hostname"];
if (hash["http_port"] != null)
{
uint p = 0;
UInt32.TryParse((string)hash["http_port"], out p);
region.HttpPort = p;
}
if (hash.ContainsKey("server_uri") && hash["server_uri"] != null)
region.ServerURI = (string)hash["server_uri"];
return null; if (hash["internal_port"] != null)
{
int p = 0;
Int32.TryParse((string)hash["internal_port"], out p);
region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
}
if (hash["position"] != null)
Vector3.TryParse((string)hash["position"], out position);
if (hash["lookAt"] != null)
Vector3.TryParse((string)hash["lookAt"], out lookAt);
// Successful return
return region;
} }
public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
@ -500,50 +492,16 @@ namespace OpenSim.Services.Connectors.Hypergrid
Hashtable hash = new Hashtable(); Hashtable hash = new Hashtable();
hash["userID"] = userID.ToString(); hash["userID"] = userID.ToString();
IList paramList = new ArrayList(); hash = CallServer("get_user_info", hash);
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("get_user_info", paramList);
Dictionary<string, object> info = new Dictionary<string, object>(); Dictionary<string, object> info = new Dictionary<string, object>();
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
}
catch
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUserInfo", m_ServerURL);
return info;
}
if (response.IsFault) foreach (object key in hash.Keys)
{ {
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString); if (hash[key] != null)
return info;
}
hash = (Hashtable)response.Value;
try
{
if (hash == null)
{ {
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUserInfo Got null response from {0}! THIS IS BAAAAD", m_ServerURL); info.Add(key.ToString(), hash[key]);
return info;
} }
// Here is the actual response
foreach (object key in hash.Keys)
{
if (hash[key] != null)
{
info.Add(key.ToString(), hash[key]);
}
}
}
catch
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
} }
return info; return info;
@ -554,60 +512,16 @@ namespace OpenSim.Services.Connectors.Hypergrid
Hashtable hash = new Hashtable(); Hashtable hash = new Hashtable();
hash["userID"] = userID.ToString(); hash["userID"] = userID.ToString();
IList paramList = new ArrayList(); hash = CallServer("get_server_urls", hash);
paramList.Add(hash);
Dictionary<string, object> serverURLs = new Dictionary<string, object>();
XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList); foreach (object key in hash.Keys)
// string reason = string.Empty;
// Send and get reply
Dictionary<string, object> serverURLs = new Dictionary<string,object>();
XmlRpcResponse response = null;
try
{ {
response = request.Send(m_ServerURL, 10000); if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null)
}
catch
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetServerURLs for user {1}", m_ServerURL, userID);
// reason = "Exception: " + e.Message;
return serverURLs;
}
if (response.IsFault)
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString);
// reason = "XMLRPC Fault";
return serverURLs;
}
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{
if (hash == null)
{ {
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL); string serverType = key.ToString().Substring(4); // remove "SRV_"
// reason = "Internal error 1"; serverURLs.Add(serverType, hash[key].ToString());
return serverURLs;
} }
// Here is the actual response
foreach (object key in hash.Keys)
{
if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null)
{
string serverType = key.ToString().Substring(4); // remove "SRV_"
serverURLs.Add(serverType, hash[key].ToString());
}
}
}
catch
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
// reason = "Exception: " + e.Message;
} }
return serverURLs; return serverURLs;
@ -618,55 +532,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
Hashtable hash = new Hashtable(); Hashtable hash = new Hashtable();
hash["userID"] = userID.ToString(); hash["userID"] = userID.ToString();
IList paramList = new ArrayList(); hash = CallServer("locate_user", hash);
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList);
// string reason = string.Empty;
// Send and get reply
string url = string.Empty; string url = string.Empty;
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
}
catch
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for LocateUser", m_ServerURL);
// reason = "Exception: " + e.Message;
return url;
}
if (response.IsFault) // Here's the actual response
{ if (hash.ContainsKey("URL"))
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for LocateUser returned an error: {1}", m_ServerURL, response.FaultString); url = hash["URL"].ToString();
// reason = "XMLRPC Fault";
return url;
}
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{
if (hash == null)
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
// reason = "Internal error 1";
return url;
}
// Here's the actual response
if (hash.ContainsKey("URL"))
url = hash["URL"].ToString();
}
catch
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
// reason = "Exception: " + e.Message;
}
return url; return url;
} }
@ -677,55 +549,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
hash["userID"] = userID.ToString(); hash["userID"] = userID.ToString();
hash["targetUserID"] = targetUserID.ToString(); hash["targetUserID"] = targetUserID.ToString();
IList paramList = new ArrayList(); hash = CallServer("get_uui", hash);
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList);
// string reason = string.Empty;
// Send and get reply
string uui = string.Empty; string uui = string.Empty;
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
}
catch
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUI", m_ServerURL);
// reason = "Exception: " + e.Message;
return uui;
}
if (response.IsFault) // Here's the actual response
{ if (hash.ContainsKey("UUI"))
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUI returned an error: {1}", m_ServerURL, response.FaultString); uui = hash["UUI"].ToString();
// reason = "XMLRPC Fault";
return uui;
}
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{
if (hash == null)
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
// reason = "Internal error 1";
return uui;
}
// Here's the actual response
if (hash.ContainsKey("UUI"))
uui = hash["UUI"].ToString();
}
catch
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetUUI response.");
// reason = "Exception: " + e.Message;
}
return uui; return uui;
} }
@ -736,54 +566,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
hash["first"] = first; hash["first"] = first;
hash["last"] = last; hash["last"] = last;
IList paramList = new ArrayList(); hash = CallServer("get_uuid", hash);
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("get_uuid", paramList); if (!hash.ContainsKey("UUID"))
// string reason = string.Empty;
// Send and get reply
UUID uuid = UUID.Zero;
XmlRpcResponse response = null;
try
{ {
response = request.Send(m_ServerURL, 10000); throw new Exception(string.Format("[USER AGENT CONNECTOR]: get_uuid call to {0} didn't return a UUID", m_ServerURL));
}
catch
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUID", m_ServerURL);
// reason = "Exception: " + e.Message;
return uuid;
} }
if (response.IsFault) UUID uuid;
if (!UUID.TryParse(hash["UUID"].ToString(), out uuid))
{ {
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUID returned an error: {1}", m_ServerURL, response.FaultString); throw new Exception(string.Format("[USER AGENT CONNECTOR]: get_uuid call to {0} returned an invalid UUID: {1}", m_ServerURL, hash["UUID"].ToString()));
// reason = "XMLRPC Fault";
return uuid;
}
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{
if (hash == null)
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUDI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
// reason = "Internal error 1";
return uuid;
}
// Here's the actual response
if (hash.ContainsKey("UUID"))
UUID.TryParse(hash["UUID"].ToString(), out uuid);
}
catch
{
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on UUID response.");
// reason = "Exception: " + e.Message;
} }
return uuid; return uuid;

View File

@ -215,7 +215,15 @@ namespace OpenSim.Services.HypergridService
{ {
// Let's check with the UAS if the user is elsewhere // Let's check with the UAS if the user is elsewhere
m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service"); m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service");
url = m_UserAgentService.LocateUser(toAgentID); try
{
url = m_UserAgentService.LocateUser(toAgentID);
}
catch (Exception e)
{
m_log.Warn("[HG IM SERVICE]: LocateUser call failed ", e);
url = string.Empty;
}
} }
// check if we've tried this before.. // check if we've tried this before..

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
@ -47,15 +47,47 @@ namespace OpenSim.Services.Interfaces
{ {
bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason); bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason);
void LogoutAgent(UUID userID, UUID sessionID); void LogoutAgent(UUID userID, UUID sessionID);
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
Dictionary<string, object> GetServerURLs(UUID userID);
Dictionary<string,object> GetUserInfo(UUID userID);
/// <summary>
/// Returns the home region of a remote user.
/// </summary>
/// <returns>On success: the user's home region. If the user doesn't exist: null.</returns>
/// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
/// <summary>
/// Returns the Server URLs of a remote user.
/// </summary>
/// <returns>On success: the user's Server URLs. If the user doesn't exist: an empty dictionary.</returns>
/// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
Dictionary<string, object> GetServerURLs(UUID userID);
/// <summary>
/// Returns the UserInfo of a remote user.
/// </summary>
/// <returns>On success: the user's UserInfo. If the user doesn't exist: an empty dictionary.</returns>
/// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
Dictionary<string, object> GetUserInfo(UUID userID);
/// <summary>
/// Returns the current location of a remote user.
/// </summary>
/// <returns>On success: the user's Server URLs. If the user doesn't exist: "".</returns>
/// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
string LocateUser(UUID userID); string LocateUser(UUID userID);
// Tries to get the universal user identifier for the targetUserId
// on behalf of the userID /// <summary>
/// Returns the Universal User Identifier for 'targetUserID' on behalf of 'userID'.
/// </summary>
/// <returns>On success: the user's UUI. If the user doesn't exist: "".</returns>
/// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
string GetUUI(UUID userID, UUID targetUserID); string GetUUI(UUID userID, UUID targetUserID);
/// <summary>
/// Returns the remote user that has the given name.
/// </summary>
/// <returns>On success: the user's UUID. If the user doesn't exist: UUID.Zero.</returns>
/// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
UUID GetUUID(String first, String last); UUID GetUUID(String first, String last);
// Returns the local friends online // Returns the local friends online

View File

@ -91,7 +91,7 @@ namespace OpenSim.Services.Interfaces
/// </summary> /// </summary>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="folderID"></param> /// <param name="folderID"></param>
/// <returns></returns> /// <returns>Inventory content. null if the request failed.</returns>
InventoryCollection GetFolderContent(UUID userID, UUID folderID); InventoryCollection GetFolderContent(UUID userID, UUID folderID);
/// <summary> /// <summary>

View File

@ -120,11 +120,13 @@ namespace OpenSim.Services.UserAccountService
MainConsole.Instance.OutputFormat("Users online: {0}", onlineRecentlyCount); MainConsole.Instance.OutputFormat("Users online: {0}", onlineRecentlyCount);
} }
public virtual GridUserInfo GetGridUserInfo(string userID) private GridUserData GetGridUserData(string userID)
{ {
GridUserData d = null; GridUserData d = null;
if (userID.Length > 36) // it's a UUI if (userID.Length > 36) // it's a UUI
{
d = m_Database.Get(userID); d = m_Database.Get(userID);
}
else // it's a UUID else // it's a UUID
{ {
GridUserData[] ds = m_Database.GetAll(userID); GridUserData[] ds = m_Database.GetAll(userID);
@ -140,6 +142,13 @@ namespace OpenSim.Services.UserAccountService
} }
} }
return d;
}
public virtual GridUserInfo GetGridUserInfo(string userID)
{
GridUserData d = GetGridUserData(userID);
if (d == null) if (d == null)
return null; return null;
@ -173,7 +182,8 @@ namespace OpenSim.Services.UserAccountService
public GridUserInfo LoggedIn(string userID) public GridUserInfo LoggedIn(string userID)
{ {
m_log.DebugFormat("[GRID USER SERVICE]: User {0} is online", userID); m_log.DebugFormat("[GRID USER SERVICE]: User {0} is online", userID);
GridUserData d = m_Database.Get(userID);
GridUserData d = GetGridUserData(userID);
if (d == null) if (d == null)
{ {
@ -192,7 +202,8 @@ namespace OpenSim.Services.UserAccountService
public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
{ {
m_log.DebugFormat("[GRID USER SERVICE]: User {0} is offline", userID); m_log.DebugFormat("[GRID USER SERVICE]: User {0} is offline", userID);
GridUserData d = m_Database.Get(userID);
GridUserData d = GetGridUserData(userID);
if (d == null) if (d == null)
{ {
@ -211,7 +222,8 @@ namespace OpenSim.Services.UserAccountService
public bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt) public bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt)
{ {
GridUserData d = m_Database.Get(userID); GridUserData d = GetGridUserData(userID);
if (d == null) if (d == null)
{ {
d = new GridUserData(); d = new GridUserData();
@ -229,7 +241,8 @@ namespace OpenSim.Services.UserAccountService
{ {
// m_log.DebugFormat("[GRID USER SERVICE]: SetLastPosition for {0}", userID); // m_log.DebugFormat("[GRID USER SERVICE]: SetLastPosition for {0}", userID);
GridUserData d = m_Database.Get(userID); GridUserData d = GetGridUserData(userID);
if (d == null) if (d == null)
{ {
d = new GridUserData(); d = new GridUserData();
@ -243,4 +256,4 @@ namespace OpenSim.Services.UserAccountService
return m_Database.Store(d); return m_Database.Store(d);
} }
} }
} }

View File

@ -3325,6 +3325,7 @@
<Reference name="nunit.framework" path="../../../../../bin/"/> <Reference name="nunit.framework" path="../../../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../../../bin/"/> <Reference name="OpenMetaverse" path="../../../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../../../bin/"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Monitoring"/> <Reference name="OpenSim.Framework.Monitoring"/>
@ -3334,6 +3335,7 @@
<Reference name="OpenSim.Region.ClientStack.LindenUDP"/> <Reference name="OpenSim.Region.ClientStack.LindenUDP"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.OptionalModules"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Tests.Common"/> <Reference name="OpenSim.Tests.Common"/>