Merge branch 'master' into careminster

Conflicts:
	OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
	OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
	OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
avinationmerge
Melanie 2013-08-17 03:23:45 +01:00
commit bef03fb30b
28 changed files with 417 additions and 172 deletions

View File

@ -439,11 +439,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// k, (string)requestData[k], ((string)requestData[k]).Length); // k, (string)requestData[k], ((string)requestData[k]).Length);
// } // }
CheckStringParameters(requestData, responseData, new string[] {"filename", "regionid"}); CheckStringParameters(requestData, responseData, new string[] { "filename" });
CheckRegionParams(requestData, responseData); CheckRegionParams(requestData, responseData);
Scene scene = null; Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out scene); GetSceneFromRegionParams(requestData, responseData, out scene);
if (scene != null)
{
string file = (string)requestData["filename"]; string file = (string)requestData["filename"];
responseData["accepted"] = true; responseData["accepted"] = true;
@ -451,6 +454,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
LoadHeightmap(file, scene.RegionInfo.RegionID); LoadHeightmap(file, scene.RegionInfo.RegionID);
responseData["success"] = true; responseData["success"] = true;
}
else
{
responseData["success"] = false;
}
m_log.Info("[RADMIN]: Load height maps request complete"); m_log.Info("[RADMIN]: Load height maps request complete");
} }
@ -464,23 +472,30 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString()); // m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString());
CheckStringParameters(requestData, responseData, new string[] { "filename", "regionid" }); CheckStringParameters(requestData, responseData, new string[] { "filename" });
CheckRegionParams(requestData, responseData); CheckRegionParams(requestData, responseData);
Scene region = null; Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out region); GetSceneFromRegionParams(requestData, responseData, out scene);
if (scene != null)
{
string file = (string)requestData["filename"]; string file = (string)requestData["filename"];
m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file);
responseData["accepted"] = true; responseData["accepted"] = true;
ITerrainModule terrainModule = region.RequestModuleInterface<ITerrainModule>(); ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
if (null == terrainModule) throw new Exception("terrain module not available"); if (null == terrainModule) throw new Exception("terrain module not available");
terrainModule.SaveToFile(file); terrainModule.SaveToFile(file);
responseData["success"] = true; responseData["success"] = true;
}
else
{
responseData["success"] = false;
}
m_log.Info("[RADMIN]: Save height maps request complete"); m_log.Info("[RADMIN]: Save height maps request complete");
} }

View File

@ -267,7 +267,7 @@ namespace OpenSim.Framework.Monitoring
public static Hashtable HandleStatsRequest(Hashtable request) public static Hashtable HandleStatsRequest(Hashtable request)
{ {
Hashtable responsedata = new Hashtable(); Hashtable responsedata = new Hashtable();
string regpath = request["uri"].ToString(); // string regpath = request["uri"].ToString();
int response_code = 200; int response_code = 200;
string contenttype = "text/json"; string contenttype = "text/json";

View File

@ -123,7 +123,7 @@ namespace OpenSim.Region.ClientStack.Linden
if (m_URL == "localhost") if (m_URL == "localhost")
{ {
m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); // m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler( caps.RegisterHandler(
"AvatarPickerSearch", "AvatarPickerSearch",
new AvatarPickerSearchHandler("/CAPS/" + capID + "/", m_People, "AvatarPickerSearch", "Search for avatars by name")); new AvatarPickerSearchHandler("/CAPS/" + capID + "/", m_People, "AvatarPickerSearch", "Search for avatars by name"));

View File

@ -106,6 +106,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
stat => stat.Value = m_udpServer.IncomingPacketsProcessed, stat => stat.Value = m_udpServer.IncomingPacketsProcessed,
StatVerbosity.Debug)); StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"IncomingPacketsMalformedCount",
"Number of inbound UDP packets that could not be recognized as LL protocol packets.",
"",
"",
"clientstack",
scene.Name,
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = m_udpServer.IncomingMalformedPacketCount,
StatVerbosity.Info));
StatsManager.RegisterStat(
new Stat(
"IncomingPacketsOrphanedCount",
"Number of inbound packets that were not initial connections packets and could not be associated with a viewer.",
"",
"",
"clientstack",
scene.Name,
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = m_udpServer.IncomingOrphanedPacketCount,
StatVerbosity.Info));
StatsManager.RegisterStat( StatsManager.RegisterStat(
new Stat( new Stat(
"OutgoingUDPSendsCount", "OutgoingUDPSendsCount",
@ -272,7 +298,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public Socket Server { get { return null; } } public Socket Server { get { return null; } }
private int m_malformedCount = 0; // Guard against a spamming attack /// <summary>
/// Record how many inbound packets could not be recognized as LLUDP packets.
/// </summary>
public int IncomingMalformedPacketCount { get; private set; }
/// <summary>
/// Record how many inbound packets could not be associated with a simulator circuit.
/// </summary>
public int IncomingOrphanedPacketCount { get; private set; }
/// <summary> /// <summary>
/// Record current outgoing client for monitoring purposes. /// Record current outgoing client for monitoring purposes.
@ -1193,6 +1227,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
} }
private void RecordMalformedInboundPacket(IPEndPoint endPoint)
{
// if (m_malformedCount < 100)
// m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
IncomingMalformedPacketCount++;
if ((IncomingMalformedPacketCount % 10000) == 0)
m_log.WarnFormat(
"[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack. Last was from {1}",
IncomingMalformedPacketCount, endPoint);
}
public override void PacketReceived(UDPPacketBuffer buffer) public override void PacketReceived(UDPPacketBuffer buffer)
{ {
// Debugging/Profiling // Debugging/Profiling
@ -1214,6 +1261,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", // "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
RecordMalformedInboundPacket(endPoint);
return; // Drop undersized packet return; // Drop undersized packet
} }
@ -1232,6 +1281,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}", // "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}",
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
RecordMalformedInboundPacket(endPoint);
return; // Malformed header return; // Malformed header
} }
@ -1247,34 +1298,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Only allocate a buffer for zerodecoding if the packet is zerocoded // Only allocate a buffer for zerodecoding if the packet is zerocoded
((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
} }
catch (MalformedDataException)
{
}
catch (IndexOutOfRangeException)
{
// m_log.WarnFormat(
// "[LLUDPSERVER]: Dropping short packet received from {0} in {1}",
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
return; // Drop short packet
}
catch (Exception e) catch (Exception e)
{ {
if (m_malformedCount < 100) if (IncomingMalformedPacketCount < 100)
m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
m_malformedCount++;
if ((m_malformedCount % 100000) == 0)
m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
} }
// Fail-safe check // Fail-safe check
if (packet == null) if (packet == null)
{ {
m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse {0} byte packet from {1}:", if (IncomingMalformedPacketCount < 100)
buffer.DataLength, buffer.RemoteEndPoint); {
m_log.Error(Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); m_log.WarnFormat("[LLUDPSERVER]: Malformed data, cannot parse {0} byte packet from {1}, data {2}:",
buffer.DataLength, buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null));
}
RecordMalformedInboundPacket(endPoint);
return; return;
} }
@ -1337,6 +1377,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (client == null || !(client is LLClientView)) if (client == null || !(client is LLClientView))
{ {
//m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
IncomingOrphanedPacketCount++;
if ((IncomingOrphanedPacketCount % 10000) == 0)
m_log.WarnFormat(
"[LLUDPSERVER]: Received {0} orphaned packets so far. Last was from {1}",
IncomingOrphanedPacketCount, endPoint);
return; return;
} }

View File

@ -145,39 +145,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return packet; return packet;
} }
// private byte[] decoded_header = new byte[10];
private static PacketType GetType(byte[] bytes) private static PacketType GetType(byte[] bytes)
{ {
byte[] decoded_header = new byte[10 + 8];
ushort id; ushort id;
PacketFrequency freq; PacketFrequency freq;
bool isZeroCoded = (bytes[0] & Helpers.MSG_ZEROCODED) != 0;
if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0) if (bytes[6] == 0xFF)
{ {
Helpers.ZeroDecode(bytes, 16, decoded_header); if (bytes[7] == 0xFF)
}
else
{ {
Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10);
}
if (decoded_header[6] == 0xFF)
{
if (decoded_header[7] == 0xFF)
{
id = (ushort) ((decoded_header[8] << 8) + decoded_header[9]);
freq = PacketFrequency.Low; freq = PacketFrequency.Low;
if (isZeroCoded && bytes[8] == 0)
id = bytes[10];
else
id = (ushort)((bytes[8] << 8) + bytes[9]);
} }
else else
{ {
id = decoded_header[7];
freq = PacketFrequency.Medium; freq = PacketFrequency.Medium;
id = bytes[7];
} }
} }
else else
{ {
id = decoded_header[6];
freq = PacketFrequency.High; freq = PacketFrequency.High;
id = bytes[6];
} }
return Packet.GetType(id, freq); return Packet.GetType(id, freq);

View File

@ -361,22 +361,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// If we're an NPC then skip all the item checks and manipulations since we don't have an // If we're an NPC then skip all the item checks and manipulations since we don't have an
// inventory right now. // inventory right now.
SceneObjectGroup objatt RezSingleAttachmentFromInventoryInternal(
= RezSingleAttachmentFromInventoryInternal(
sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true, d); sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true, d);
if (ThrottlePer100PrimsRezzed > 0)
{
int throttleMs = (int)Math.Round((float)objatt.PrimCount / 100 * ThrottlePer100PrimsRezzed);
if (DebugLevel > 0)
m_log.DebugFormat(
"[ATTACHMENTS MODULE]: Throttling by {0}ms after rez of {1} with {2} prims for attachment to {3} on point {4} in {5}",
throttleMs, objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name);
Thread.Sleep(throttleMs);
}
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -844,7 +844,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
TestClient tc = new TestClient(acd, sceneA); TestClient tc = new TestClient(acd, sceneA);
List<TestClient> destinationTestClients = new List<TestClient>(); List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
@ -925,7 +925,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
IConfig modulesConfig = config.AddConfig("Modules"); IConfig modulesConfig = config.AddConfig("Modules");
modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("EntityTransferModule", etmA.Name);
modulesConfig.Set("SimulationServices", lscm.Name); modulesConfig.Set("SimulationServices", lscm.Name);
IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule");
@ -944,7 +943,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
TestClient tc = new TestClient(acd, sceneA); TestClient tc = new TestClient(acd, sceneA);
List<TestClient> destinationTestClients = new List<TestClient>(); List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
@ -966,7 +965,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
// Both these operations will occur on different threads and will wait for each other. // Both these operations will occur on different threads and will wait for each other.
// We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1 // We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1
// test protocol, where we are trying to avoid unpredictable async operations in regression tests. // test protocol, where we are trying to avoid unpredictable async operations in regression tests.
((TestClient)beforeTeleportSp.ControllingClient).OnTestClientSendRegionTeleport tc.OnTestClientSendRegionTeleport
+= (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL)
=> ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null); => ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null);

View File

@ -307,7 +307,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
} }
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(targetID, out serverURI); GetUserProfileServerURI(targetID, out serverURI);
UUID creatorId = UUID.Zero; UUID creatorId = UUID.Zero;
OSDMap parameters= new OSDMap(); OSDMap parameters= new OSDMap();
@ -372,7 +372,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
} }
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(target, out serverURI); GetUserProfileServerURI(target, out serverURI);
object Ad = (object)ad; object Ad = (object)ad;
if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString()))
@ -441,10 +441,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; Vector3 pos = remoteClient.SceneAgent.AbsolutePosition;
ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y);
ScenePresence p = FindPresence(remoteClient.AgentId); ScenePresence p = FindPresence(remoteClient.AgentId);
Vector3 avaPos = p.AbsolutePosition; // Vector3 avaPos = p.AbsolutePosition;
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
if (land == null) if (land == null)
{ {
@ -470,7 +470,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
object Ad = ad; object Ad = ad;
OSD X = OSD.SerializeMembers(Ad); OSD.SerializeMembers(Ad);
if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString())) if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString()))
{ {
@ -491,7 +491,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient)
{ {
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
UUID classifiedId; UUID classifiedId;
OSDMap parameters= new OSDMap(); OSDMap parameters= new OSDMap();
@ -541,7 +541,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
} }
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(targetId, out serverURI); GetUserProfileServerURI(targetId, out serverURI);
OSDMap parameters= new OSDMap(); OSDMap parameters= new OSDMap();
parameters.Add("creatorId", OSD.FromUUID(targetId)); parameters.Add("creatorId", OSD.FromUUID(targetId));
@ -592,7 +592,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
UUID targetID; UUID targetID;
UUID.TryParse(args[0], out targetID); UUID.TryParse(args[0], out targetID);
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(targetID, out serverURI); GetUserProfileServerURI(targetID, out serverURI);
IClientAPI remoteClient = (IClientAPI)sender; IClientAPI remoteClient = (IClientAPI)sender;
UserProfilePick pick = new UserProfilePick(); UserProfilePick pick = new UserProfilePick();
@ -660,7 +660,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString());
UserProfilePick pick = new UserProfilePick(); UserProfilePick pick = new UserProfilePick();
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
ScenePresence p = FindPresence(remoteClient.AgentId); ScenePresence p = FindPresence(remoteClient.AgentId);
Vector3 avaPos = p.AbsolutePosition; Vector3 avaPos = p.AbsolutePosition;
@ -720,7 +720,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
public void PickDelete(IClientAPI remoteClient, UUID queryPickID) public void PickDelete(IClientAPI remoteClient, UUID queryPickID)
{ {
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
OSDMap parameters= new OSDMap(); OSDMap parameters= new OSDMap();
parameters.Add("pickId", OSD.FromUUID(queryPickID)); parameters.Add("pickId", OSD.FromUUID(queryPickID));
@ -755,7 +755,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
IClientAPI remoteClient = (IClientAPI)sender; IClientAPI remoteClient = (IClientAPI)sender;
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
note.TargetId = remoteClient.AgentId; note.TargetId = remoteClient.AgentId;
UUID.TryParse(args[0], out note.UserId); UUID.TryParse(args[0], out note.UserId);
@ -791,7 +791,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
note.Notes = queryNotes; note.Notes = queryNotes;
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
object Note = note; object Note = note;
if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString()))
@ -836,7 +836,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
prop.Language = languages; prop.Language = languages;
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
object Param = prop; object Param = prop;
if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString()))
@ -958,7 +958,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
prop.FirstLifeText = newProfile.FirstLifeAboutText; prop.FirstLifeText = newProfile.FirstLifeAboutText;
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
object Prop = prop; object Prop = prop;
@ -972,7 +972,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
} }
} }
/// <summary> /// <summary>
/// Gets the profile data. /// Gets the profile data.
/// </summary> /// </summary>
@ -997,7 +996,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
} }
string serverURI = string.Empty; string serverURI = string.Empty;
bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI); GetUserProfileServerURI(properties.UserId, out serverURI);
// This is checking a friend on the home grid // This is checking a friend on the home grid
// Not HG friend // Not HG friend
@ -1245,7 +1244,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
return false; return false;
} }
byte[] buf = new byte[8192];
Stream rstream = webResponse.GetResponseStream(); Stream rstream = webResponse.GetResponseStream();
OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream);
@ -1311,7 +1309,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
return false; return false;
} }
byte[] buf = new byte[8192];
Stream rstream = webResponse.GetResponseStream(); Stream rstream = webResponse.GetResponseStream();
OSDMap response = new OSDMap(); OSDMap response = new OSDMap();

View File

@ -317,7 +317,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
sp.Name, sp.UUID, position, regionHandle); sp.Name, sp.UUID, position, regionHandle);
sp.ControllingClient.SendTeleportFailed("Slow down!"); sp.ControllingClient.SendTeleportFailed("Previous teleport process incomplete. Please retry shortly.");
return; return;
} }
@ -1034,6 +1035,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.SenderWantsToWaitForRoot = true; agent.SenderWantsToWaitForRoot = true;
//SetCallbackURL(agent, sp.Scene.RegionInfo); //SetCallbackURL(agent, sp.Scene.RegionInfo);
// Reset the do not close flag. This must be done before the destination opens child connections (here
// triggered by UpdateAgent) to avoid race conditions. However, we also want to reset it as late as possible
// to avoid a situation where an unexpectedly early call to Scene.NewUserConnection() wrongly results
// in no close.
sp.DoNotCloseAfterTeleport = false;
// Send the Update. If this returns true, we know the client has contacted the destination // Send the Update. If this returns true, we know the client has contacted the destination
// via CompleteMovementIntoRegion, so we can let go. // via CompleteMovementIntoRegion, so we can let go.
// If it returns false, something went wrong, and we need to abort. // If it returns false, something went wrong, and we need to abort.
@ -1060,6 +1067,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
// Need to signal neighbours whether child agents may need closing irrespective of whether this
// one needed closing. We also need to close child agents as quickly as possible to avoid complicated
// race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back
// to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex
// distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are
// abandoned without proper close by viewer but then re-used by an incoming connection.
sp.CloseChildAgents(newRegionX, newRegionY);
// May need to logout or other cleanup // May need to logout or other cleanup
AgentHasMovedAway(sp, logout); AgentHasMovedAway(sp, logout);
@ -1069,22 +1084,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Now let's make it officially a child agent // Now let's make it officially a child agent
sp.MakeChildAgent(); sp.MakeChildAgent();
// May still need to signal neighbours whether child agents may need closing irrespective of whether this
// one needed closing. Neighbour regions also contain logic to prevent a close if a subsequent move or
// teleport re-established the child connection.
//
// It may be possible to also close child agents after a pause but one needs to be very careful about
// race conditions between different regions on rapid teleporting (e.g. from A1 to a non-neighbour B, back
// to a neighbour A2 then off to a non-neighbour C. Also, closing child agents early may be more compatible
// with complicated scenarios where there a mixture of V1 and V2 teleports, though this is conjecture. It's
// easier to close immediately and greatly reduce the scope of race conditions if possible.
sp.CloseChildAgents(newRegionX, newRegionY);
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
{ {
sp.DoNotCloseAfterTeleport = false;
// RED ALERT!!!! // RED ALERT!!!!
// PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
// THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
@ -1093,19 +1095,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
Thread.Sleep(15000); Thread.Sleep(15000);
if (!sp.DoNotCloseAfterTeleport)
{
// OK, it got this agent. Let's close everything // OK, it got this agent. Let's close everything
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing agent {0} in {1}", sp.Name, Scene.Name); // If we shouldn't close the agent due to some other region renewing the connection
// then this will be handled in IncomingCloseAgent under lock conditions
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
sp.Scene.IncomingCloseAgent(sp.UUID, false); sp.Scene.IncomingCloseAgent(sp.UUID, false);
} }
else else
{
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {1}", sp.Name, Scene.Name);
sp.DoNotCloseAfterTeleport = false;
}
}
else
{ {
// now we have a child agent in this region. // now we have a child agent in this region.
sp.Reset(); sp.Reset();

View File

@ -3862,21 +3862,30 @@ namespace OpenSim.Region.Framework.Scenes
// In the case where, for example, an A B C D region layout, an avatar may // In the case where, for example, an A B C D region layout, an avatar may
// teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
// renews the lease on the child agent at B, we must make sure that the close from A does not succeed. // renews the lease on the child agent at B, we must make sure that the close from A does not succeed.
if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) //
{ // XXX: In the end, this should not be necessary if child agents are closed without delay on
m_log.DebugFormat( // teleport, since realistically, the close request should always be processed before any other
"[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", // region tried to re-establish a child agent. This is much simpler since the logic below is
sp.Name, Name); // vulnerable to an issue when a viewer quits a region without sending a proper logout but then
// re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport
// flag when no teleport had taken place (and hence no close was going to come).
// if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle))
// {
// m_log.DebugFormat(
// "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.",
// sp.Name, Name);
//
// sp.DoNotCloseAfterTeleport = true;
// }
// else if (EntityTransferModule.IsInTransit(sp.UUID))
sp.DoNotCloseAfterTeleport = true; if (EntityTransferModule.IsInTransit(sp.UUID))
}
else if (EntityTransferModule.IsInTransit(sp.UUID))
{ {
m_log.DebugFormat(
"[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt previous end-of-teleport close.",
sp.Name, Name);
sp.DoNotCloseAfterTeleport = true; sp.DoNotCloseAfterTeleport = true;
m_log.DebugFormat(
"[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.",
sp.Name, Name);
} }
} }
} }

View File

@ -223,7 +223,7 @@ namespace OpenSim.Region.Framework.Scenes
private float m_sitAvatarHeight = 2.0f; private float m_sitAvatarHeight = 2.0f;
private Vector3 m_lastChildAgentUpdatePosition; private Vector3 m_lastChildAgentUpdatePosition;
private Vector3 m_lastChildAgentUpdateCamPosition; // private Vector3 m_lastChildAgentUpdateCamPosition;
private const int LAND_VELOCITYMAG_MAX = 12; private const int LAND_VELOCITYMAG_MAX = 12;
@ -2108,8 +2108,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_movementUpdateCount < 1) if (m_movementUpdateCount < 1)
m_movementUpdateCount = 1; m_movementUpdateCount = 1;
// AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
// Camera location in world. We'll need to raytrace // Camera location in world. We'll need to raytrace
// from this location from time to time. // from this location from time to time.
@ -3241,7 +3240,7 @@ namespace OpenSim.Region.Framework.Scenes
if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance)
{ {
m_lastChildAgentUpdatePosition = AbsolutePosition; m_lastChildAgentUpdatePosition = AbsolutePosition;
m_lastChildAgentUpdateCamPosition = CameraPosition; // m_lastChildAgentUpdateCamPosition = CameraPosition;
ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
cadu.ActiveGroupID = UUID.Zero.Guid; cadu.ActiveGroupID = UUID.Zero.Guid;

View File

@ -147,7 +147,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
AgentCircuitData acd = SceneHelpers.GenerateAgentData(uaB); AgentCircuitData acd = SceneHelpers.GenerateAgentData(uaB);
TestClient clientB = new TestClient(acd, sceneB); TestClient clientB = new TestClient(acd, sceneB);
List<TestClient> childClientsB = new List<TestClient>(); List<TestClient> childClientsB = new List<TestClient>();
EntityTransferHelpers.SetUpInformClientOfNeighbour(clientB, childClientsB); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(clientB, childClientsB);
SceneHelpers.AddScenePresence(sceneB, clientB, acd); SceneHelpers.AddScenePresence(sceneB, clientB, acd);

View File

@ -97,7 +97,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
TestClient tc = new TestClient(acd, sceneA); TestClient tc = new TestClient(acd, sceneA);
List<TestClient> destinationTestClients = new List<TestClient>(); List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
originalSp.AbsolutePosition = new Vector3(128, 32, 10); originalSp.AbsolutePosition = new Vector3(128, 32, 10);

View File

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Text; using System.Text;
using System.Threading;
using Nini.Config; using Nini.Config;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
@ -107,7 +108,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
} }
[Test] [Test]
public void TestSameSimulatorIsolatedRegions() public void TestSameSimulatorIsolatedRegionsV1()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// TestHelpers.EnableLogging(); // TestHelpers.EnableLogging();
@ -146,7 +147,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
sp.AbsolutePosition = new Vector3(30, 31, 32); sp.AbsolutePosition = new Vector3(30, 31, 32);
List<TestClient> destinationTestClients = new List<TestClient>(); List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetUpInformClientOfNeighbour((TestClient)sp.ControllingClient, destinationTestClients); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(
(TestClient)sp.ControllingClient, destinationTestClients);
sceneA.RequestTeleportLocation( sceneA.RequestTeleportLocation(
sp.ControllingClient, sp.ControllingClient,
@ -179,6 +181,67 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
} }
[Test]
public void TestSameSimulatorIsolatedRegionsV2()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID userId = TestHelpers.ParseTail(0x1);
EntityTransferModule etmA = new EntityTransferModule();
EntityTransferModule etmB = new EntityTransferModule();
LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
IConfigSource config = new IniConfigSource();
IConfig modulesConfig = config.AddConfig("Modules");
modulesConfig.Set("EntityTransferModule", etmA.Name);
modulesConfig.Set("SimulationServices", lscm.Name);
SceneHelpers sh = new SceneHelpers();
TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
SceneHelpers.SetupSceneModules(sceneA, config, etmA);
SceneHelpers.SetupSceneModules(sceneB, config, etmB);
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
Vector3 teleportPosition = new Vector3(10, 11, 12);
Vector3 teleportLookAt = new Vector3(20, 21, 22);
ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
sp.AbsolutePosition = new Vector3(30, 31, 32);
List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetupSendRegionTeleportTriggersDestinationClientCreateAndCompleteMovement(
(TestClient)sp.ControllingClient, destinationTestClients);
sceneA.RequestTeleportLocation(
sp.ControllingClient,
sceneB.RegionInfo.RegionHandle,
teleportPosition,
teleportLookAt,
(uint)TeleportFlags.ViaLocation);
Assert.That(sceneA.GetScenePresence(userId), Is.Null);
ScenePresence sceneBSp = sceneB.GetScenePresence(userId);
Assert.That(sceneBSp, Is.Not.Null);
Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1));
Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
// TODO: Add assertions to check correct circuit details in both scenes.
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
// position instead).
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
}
/// <summary> /// <summary>
/// Test teleport procedures when the target simulator returns false when queried about access. /// Test teleport procedures when the target simulator returns false when queried about access.
/// </summary> /// </summary>
@ -428,7 +491,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
} }
[Test] [Test]
public void TestSameSimulatorNeighbouringRegions() public void TestSameSimulatorNeighbouringRegionsV1()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// TestHelpers.EnableLogging(); // TestHelpers.EnableLogging();
@ -466,7 +529,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
TestClient tc = new TestClient(acd, sceneA); TestClient tc = new TestClient(acd, sceneA);
List<TestClient> destinationTestClients = new List<TestClient>(); List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd); ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32); beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32);
@ -510,6 +573,90 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// position instead). // position instead).
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
// TestHelpers.DisableLogging();
}
[Test]
public void TestSameSimulatorNeighbouringRegionsV2()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID userId = TestHelpers.ParseTail(0x1);
EntityTransferModule etmA = new EntityTransferModule();
EntityTransferModule etmB = new EntityTransferModule();
LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
IConfigSource config = new IniConfigSource();
IConfig modulesConfig = config.AddConfig("Modules");
modulesConfig.Set("EntityTransferModule", etmA.Name);
modulesConfig.Set("SimulationServices", lscm.Name);
SceneHelpers sh = new SceneHelpers();
TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
Vector3 teleportPosition = new Vector3(10, 11, 12);
Vector3 teleportLookAt = new Vector3(20, 21, 22);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
TestClient tc = new TestClient(acd, sceneA);
List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32);
Assert.That(beforeSceneASp, Is.Not.Null);
Assert.That(beforeSceneASp.IsChildAgent, Is.False);
ScenePresence beforeSceneBSp = sceneB.GetScenePresence(userId);
Assert.That(beforeSceneBSp, Is.Not.Null);
Assert.That(beforeSceneBSp.IsChildAgent, Is.True);
// Here, we need to make clientA's receipt of SendRegionTeleport trigger clientB's CompleteMovement(). This
// is to operate the teleport V2 mechanism where the EntityTransferModule will first request the client to
// CompleteMovement to the region and then call UpdateAgent to the destination region to confirm the receipt
// Both these operations will occur on different threads and will wait for each other.
// We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1
// test protocol, where we are trying to avoid unpredictable async operations in regression tests.
tc.OnTestClientSendRegionTeleport
+= (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL)
=> ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null);
sceneA.RequestTeleportLocation(
beforeSceneASp.ControllingClient,
sceneB.RegionInfo.RegionHandle,
teleportPosition,
teleportLookAt,
(uint)TeleportFlags.ViaLocation);
ScenePresence afterSceneASp = sceneA.GetScenePresence(userId);
Assert.That(afterSceneASp, Is.Not.Null);
Assert.That(afterSceneASp.IsChildAgent, Is.True);
ScenePresence afterSceneBSp = sceneB.GetScenePresence(userId);
Assert.That(afterSceneBSp, Is.Not.Null);
Assert.That(afterSceneBSp.IsChildAgent, Is.False);
Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(1));
Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1));
Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
// TODO: Add assertions to check correct circuit details in both scenes.
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
// position instead).
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
// TestHelpers.DisableLogging(); // TestHelpers.DisableLogging();
} }
} }

View File

@ -69,7 +69,9 @@ public class BSActorAvatarMove : BSActor
// BSActor.Dispose() // BSActor.Dispose()
public override void Dispose() public override void Dispose()
{ {
Enabled = false; base.SetEnabled(false);
// Now that turned off, remove any state we have in the scene.
Refresh();
} }
// Called when physical parameters (properties set in Bullet) need to be re-applied. // Called when physical parameters (properties set in Bullet) need to be re-applied.
@ -181,7 +183,7 @@ public class BSActorAvatarMove : BSActor
if (m_controllingPrim.IsColliding) if (m_controllingPrim.IsColliding)
{ {
// If we are colliding with a stationary object, presume we're standing and don't move around // If we are colliding with a stationary object, presume we're standing and don't move around
if (!m_controllingPrim.ColliderIsMoving) if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
{ {
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
m_controllingPrim.IsStationary = true; m_controllingPrim.IsStationary = true;

View File

@ -107,6 +107,8 @@ public sealed class BSCharacter : BSPhysObject
PhysicalActors.Add(AvatarMoveActorName, m_moveActor); PhysicalActors.Add(AvatarMoveActorName, m_moveActor);
SetPhysicalProperties(); SetPhysicalProperties();
IsInitialized = true;
}); });
return; return;
} }
@ -114,6 +116,8 @@ public sealed class BSCharacter : BSPhysObject
// called when this character is being destroyed and the resources should be released // called when this character is being destroyed and the resources should be released
public override void Destroy() public override void Destroy()
{ {
IsInitialized = false;
base.Destroy(); base.Destroy();
DetailLog("{0},BSCharacter.Destroy", LocalID); DetailLog("{0},BSCharacter.Destroy", LocalID);

View File

@ -72,6 +72,8 @@ public abstract class BSPhysObject : PhysicsActor
} }
protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
{ {
IsInitialized = false;
PhysScene = parentScene; PhysScene = parentScene;
LocalID = localID; LocalID = localID;
PhysObjectName = name; PhysObjectName = name;
@ -130,6 +132,9 @@ public abstract class BSPhysObject : PhysicsActor
public string PhysObjectName { get; protected set; } public string PhysObjectName { get; protected set; }
public string TypeName { get; protected set; } public string TypeName { get; protected set; }
// Set to 'true' when the object is completely initialized.
// This mostly prevents property updates and collisions until the object is completely here.
public bool IsInitialized { get; protected set; }
// Return the object mass without calculating it or having side effects // Return the object mass without calculating it or having side effects
public abstract float RawMass { get; } public abstract float RawMass { get; }
@ -352,6 +357,8 @@ public abstract class BSPhysObject : PhysicsActor
// On a collision, check the collider and remember if the last collider was moving // On a collision, check the collider and remember if the last collider was moving
// Used to modify the standing of avatars (avatars on stationary things stand still) // Used to modify the standing of avatars (avatars on stationary things stand still)
public bool ColliderIsMoving; public bool ColliderIsMoving;
// 'true' if the last collider was a volume detect object
public bool ColliderIsVolumeDetect;
// Used by BSCharacter to manage standing (and not slipping) // Used by BSCharacter to manage standing (and not slipping)
public bool IsStationary; public bool IsStationary;
@ -431,6 +438,7 @@ public abstract class BSPhysObject : PhysicsActor
// For movement tests, remember if we are colliding with an object that is moving. // For movement tests, remember if we are colliding with an object that is moving.
ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;
ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false;
// Make a collection of the collisions that happened the last simulation tick. // Make a collection of the collisions that happened the last simulation tick.
// This is different than the collection created for sending up to the simulator as it is cleared every tick. // This is different than the collection created for sending up to the simulator as it is cleared every tick.

View File

@ -110,6 +110,8 @@ public class BSPrim : BSPhysObject
CreateGeomAndObject(true); CreateGeomAndObject(true);
CurrentCollisionFlags = PhysScene.PE.GetCollisionFlags(PhysBody); CurrentCollisionFlags = PhysScene.PE.GetCollisionFlags(PhysBody);
IsInitialized = true;
}); });
} }
@ -117,6 +119,8 @@ public class BSPrim : BSPhysObject
public override void Destroy() public override void Destroy()
{ {
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
IsInitialized = false;
base.Destroy(); base.Destroy();
// Undo any vehicle properties // Undo any vehicle properties

View File

@ -639,6 +639,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
BSPhysObject pobj; BSPhysObject pobj;
if (PhysObjects.TryGetValue(entprop.ID, out pobj)) if (PhysObjects.TryGetValue(entprop.ID, out pobj))
{ {
if (pobj.IsInitialized)
pobj.UpdateProperties(entprop); pobj.UpdateProperties(entprop);
} }
} }
@ -766,11 +767,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
if (collider.IsInitialized)
{
if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration))
{ {
// If a collision was 'good', remember to send it to the simulator // If a collision was 'good', remember to send it to the simulator
ObjectsWithCollisions.Add(collider); ObjectsWithCollisions.Add(collider);
} }
}
return; return;
} }

View File

@ -85,7 +85,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
data.destinationServerURI = args["destination_serveruri"]; data.destinationServerURI = args["destination_serveruri"];
} }
catch (InvalidCastException e) catch (InvalidCastException)
{ {
m_log.ErrorFormat("[HOME AGENT HANDLER]: Bad cast in UnpackData"); m_log.ErrorFormat("[HOME AGENT HANDLER]: Bad cast in UnpackData");
} }

View File

@ -453,7 +453,6 @@ namespace OpenSim.Server.Handlers.Hypergrid
XmlRpcResponse response = new XmlRpcResponse(); XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash; response.Value = hash;
return response; return response;
} }
/// <summary> /// <summary>
@ -471,9 +470,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
//string portstr = (string)requestData["port"]; //string portstr = (string)requestData["port"];
if (requestData.ContainsKey("first") && requestData.ContainsKey("last")) if (requestData.ContainsKey("first") && requestData.ContainsKey("last"))
{ {
UUID userID = UUID.Zero;
string first = (string)requestData["first"]; string first = (string)requestData["first"];
string last = (string)requestData["last"]; string last = (string)requestData["last"];
UUID uuid = m_HomeUsersService.GetUUID(first, last); UUID uuid = m_HomeUsersService.GetUUID(first, last);
hash["UUID"] = uuid.ToString(); hash["UUID"] = uuid.ToString();
@ -482,7 +479,6 @@ namespace OpenSim.Server.Handlers.Hypergrid
XmlRpcResponse response = new XmlRpcResponse(); XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash; response.Value = hash;
return response; return response;
} }
} }
} }

View File

@ -39,8 +39,7 @@ namespace OpenSim.Server.Handlers.Profiles
{ {
public class UserProfilesConnector: ServiceConnector public class UserProfilesConnector: ServiceConnector
{ {
static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// Our Local Module // Our Local Module
public IUserProfilesService ServiceModule public IUserProfilesService ServiceModule
@ -111,4 +110,3 @@ namespace OpenSim.Server.Handlers.Profiles
} }
} }
} }

View File

@ -98,7 +98,7 @@ namespace OpenSim.Services.Connectors
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[NEIGHBOUR SERVICE CONNCTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}", "[NEIGHBOUR SERVICES CONNECTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}",
uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace);
return false; return false;
@ -117,7 +117,7 @@ namespace OpenSim.Services.Connectors
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[NEIGHBOUR SERVICE CONNCTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}", "[NEIGHBOUR SERVICES CONNECTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}",
thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace);
return false; return false;
@ -137,7 +137,7 @@ namespace OpenSim.Services.Connectors
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[NEIGHBOUR SERVICE CONNCTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}", "[NEIGHBOUR SERVICES CONNECTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}",
thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace);
return false; return false;
@ -175,7 +175,7 @@ namespace OpenSim.Services.Connectors
if (webResponse == null) if (webResponse == null)
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[REST COMMS]: Null reply on DoHelloNeighbourCall post from {0} to {1}", "[NEIGHBOUR SERVICES CONNECTOR]: Null reply on DoHelloNeighbourCall post from {0} to {1}",
thisRegion.RegionName, region.RegionName); thisRegion.RegionName, region.RegionName);
} }
@ -193,7 +193,7 @@ namespace OpenSim.Services.Connectors
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[NEIGHBOUR SERVICE CONNCTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}", "[NEIGHBOUR SERVICES CONNECTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}",
region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace); region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace);
return false; return false;

View File

@ -56,11 +56,8 @@ namespace OpenSim.Services.Connectors.SimianGrid
private Scene m_scene; private Scene m_scene;
private String m_simianURL; private String m_simianURL;
private IGridUserService m_GridUserService;
#region IRegionModule Members #region IRegionModule Members
public string Name public string Name
{ {
get { return this.GetType().Name; } get { return this.GetType().Name; }

View File

@ -29,11 +29,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Reflection; using System.Reflection;
using log4net; using log4net;
using Mono.Addins; using Mono.Addins;
using Nini.Config; using Nini.Config;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -52,7 +50,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IConfig m_config = null; private IConfig m_config = null;
private bool m_enabled = true;
private String m_simianURL; private String m_simianURL;
@ -63,7 +60,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
get { return this.GetType().Name; } get { return this.GetType().Name; }
} }
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
try try
@ -76,7 +72,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
if (String.IsNullOrEmpty(m_simianURL)) if (String.IsNullOrEmpty(m_simianURL))
{ {
// m_log.DebugFormat("[SimianGrid] service URL is not defined"); // m_log.DebugFormat("[SimianGrid] service URL is not defined");
m_enabled = false;
return; return;
} }
@ -141,6 +136,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
} }
#endregion #endregion
public static String SimulatorCapability = UUID.Zero.ToString(); public static String SimulatorCapability = UUID.Zero.ToString();
public static OSDMap PostToService(string url, NameValueCollection data) public static OSDMap PostToService(string url, NameValueCollection data)
{ {

View File

@ -31,6 +31,7 @@ using System.IO;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using NUnit.Framework; using NUnit.Framework;
@ -59,7 +60,8 @@ namespace OpenSim.Tests.Common
/// A list that will be populated with any TestClients set up in response to /// A list that will be populated with any TestClients set up in response to
/// being informed about a destination region. /// being informed about a destination region.
/// </param> /// </param>
public static void SetUpInformClientOfNeighbour(TestClient tc, List<TestClient> neighbourTcs) public static void SetupInformClientOfNeighbourTriggersNeighbourClientCreate(
TestClient tc, List<TestClient> neighbourTcs)
{ {
// XXX: Confusingly, this is also used for non-neighbour notification (as in teleports that do not use the // XXX: Confusingly, this is also used for non-neighbour notification (as in teleports that do not use the
// event queue). // event queue).
@ -75,8 +77,6 @@ namespace OpenSim.Tests.Common
"[TEST CLIENT]: Processing inform client of neighbour located at {0},{1} at {2}", "[TEST CLIENT]: Processing inform client of neighbour located at {0},{1} at {2}",
x, y, neighbourExternalEndPoint); x, y, neighbourExternalEndPoint);
// In response to this message, we are going to make a teleport to the scene we've previous been told
// about by test code (this needs to be improved).
AgentCircuitData newAgent = tc.RequestClientInfo(); AgentCircuitData newAgent = tc.RequestClientInfo();
Scene neighbourScene; Scene neighbourScene;
@ -87,5 +87,42 @@ namespace OpenSim.Tests.Common
neighbourScene.AddNewClient(neighbourTc, PresenceType.User); neighbourScene.AddNewClient(neighbourTc, PresenceType.User);
}; };
} }
/// <summary>
/// Set up correct handling of the InformClientOfNeighbour call from the source region that triggers the
/// viewer to setup a connection with the destination region.
/// </summary>
/// <param name='tc'></param>
/// <param name='neighbourTcs'>
/// A list that will be populated with any TestClients set up in response to
/// being informed about a destination region.
/// </param>
public static void SetupSendRegionTeleportTriggersDestinationClientCreateAndCompleteMovement(
TestClient client, List<TestClient> destinationClients)
{
client.OnTestClientSendRegionTeleport
+= (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) =>
{
uint x, y;
Utils.LongToUInts(regionHandle, out x, out y);
x /= Constants.RegionSize;
y /= Constants.RegionSize;
m_log.DebugFormat(
"[TEST CLIENT]: Processing send region teleport for destination at {0},{1} at {2}",
x, y, regionExternalEndPoint);
AgentCircuitData newAgent = client.RequestClientInfo();
Scene destinationScene;
SceneManager.Instance.TryGetScene(x, y, out destinationScene);
TestClient destinationClient = new TestClient(newAgent, destinationScene);
destinationClients.Add(destinationClient);
destinationScene.AddNewClient(destinationClient, PresenceType.User);
ThreadPool.UnsafeQueueUserWorkItem(o => destinationClient.CompleteMovement(), null);
};
}
} }
} }

View File

@ -58,6 +58,11 @@ namespace pCampBot
public delegate void AnEvent(Bot callbot, EventType someevent); // event delegate for bot events public delegate void AnEvent(Bot callbot, EventType someevent); // event delegate for bot events
/// <summary>
/// Controls whether bots request textures for the object information they receive
/// </summary>
public bool RequestObjectTextures { get; set; }
/// <summary> /// <summary>
/// Bot manager. /// Bot manager.
/// </summary> /// </summary>
@ -469,6 +474,9 @@ namespace pCampBot
public void Objects_NewPrim(object sender, PrimEventArgs args) public void Objects_NewPrim(object sender, PrimEventArgs args)
{ {
if (!RequestObjectTextures)
return;
Primitive prim = args.Prim; Primitive prim = args.Prim;
if (prim != null) if (prim != null)

View File

@ -300,6 +300,7 @@ namespace pCampBot
Bot pb = new Bot(bm, behaviours, firstName, lastName, password, startLocation, loginUri); Bot pb = new Bot(bm, behaviours, firstName, lastName, password, startLocation, loginUri);
pb.wear = wearSetting; pb.wear = wearSetting;
pb.Client.Settings.SEND_AGENT_UPDATES = InitBotSendAgentUpdates; pb.Client.Settings.SEND_AGENT_UPDATES = InitBotSendAgentUpdates;
pb.RequestObjectTextures = InitBotRequestObjectTextures;
pb.OnConnected += handlebotEvent; pb.OnConnected += handlebotEvent;
pb.OnDisconnected += handlebotEvent; pb.OnDisconnected += handlebotEvent;