diff options
12 files changed, 951 insertions, 678 deletions
diff --git a/OpenSim/Framework/PermissionsUtil.cs b/OpenSim/Framework/PermissionsUtil.cs index d785a78..5d3186d 100644 --- a/OpenSim/Framework/PermissionsUtil.cs +++ b/OpenSim/Framework/PermissionsUtil.cs | |||
@@ -72,8 +72,8 @@ namespace OpenSim.Framework | |||
72 | /// <param name="mainPerms">The permissions variable to modify.</param> | 72 | /// <param name="mainPerms">The permissions variable to modify.</param> |
73 | public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms) | 73 | public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms) |
74 | { | 74 | { |
75 | if ((foldedPerms & 7) == 0) | 75 | // if ((foldedPerms & 7) == 0) |
76 | return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded | 76 | // return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded |
77 | 77 | ||
78 | if ((foldedPerms & ((uint)PermissionMask.Copy >> 13)) == 0) | 78 | if ((foldedPerms & ((uint)PermissionMask.Copy >> 13)) == 0) |
79 | mainPerms &= ~(uint)PermissionMask.Copy; | 79 | mainPerms &= ~(uint)PermissionMask.Copy; |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index b0d30b6..ca6c3ca 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -358,7 +358,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
358 | return queue.Count > 0; | 358 | return queue.Count > 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID); | 361 | //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID); |
362 | return true; | 362 | return true; |
363 | } | 363 | } |
364 | 364 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index b7c8594..a3fdae1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -1750,25 +1750,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1750 | endPoint, | 1750 | endPoint, |
1751 | sessionInfo); | 1751 | sessionInfo); |
1752 | 1752 | ||
1753 | // Send ack straight away to let the viewer know that the connection is active. | ||
1754 | // The client will be null if it already exists (e.g. if on a region crossing the client sends a use | ||
1755 | // circuit code to the existing child agent. This is not particularly obvious. | ||
1756 | SendAckImmediate(endPoint, uccp.Header.Sequence); | ||
1757 | |||
1758 | // We only want to send initial data to new clients, not ones which are being converted from child to root. | ||
1759 | if (client != null) | ||
1760 | { | ||
1761 | AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); | ||
1762 | bool tp = (aCircuit.teleportFlags > 0); | ||
1763 | // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from | ||
1764 | if (!tp) | ||
1765 | client.SceneAgent.SendInitialDataToMe(); | ||
1766 | } | ||
1767 | |||
1768 | // Now we know we can handle more data | 1753 | // Now we know we can handle more data |
1769 | Thread.Sleep(200); | 1754 | // Thread.Sleep(200); |
1770 | 1755 | ||
1771 | // Obtain the queue and remove it from the cache | 1756 | // Obtain the pending queue and remove it from the cache |
1772 | Queue<UDPPacketBuffer> queue = null; | 1757 | Queue<UDPPacketBuffer> queue = null; |
1773 | 1758 | ||
1774 | lock (m_pendingCache) | 1759 | lock (m_pendingCache) |
@@ -1790,6 +1775,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1790 | PacketReceived(buf); | 1775 | PacketReceived(buf); |
1791 | } | 1776 | } |
1792 | queue = null; | 1777 | queue = null; |
1778 | |||
1779 | // Send ack straight away to let the viewer know that the connection is active. | ||
1780 | // The client will be null if it already exists (e.g. if on a region crossing the client sends a use | ||
1781 | // circuit code to the existing child agent. This is not particularly obvious. | ||
1782 | SendAckImmediate(endPoint, uccp.Header.Sequence); | ||
1783 | |||
1784 | // We only want to send initial data to new clients, not ones which are being converted from child to root. | ||
1785 | if (client != null) | ||
1786 | { | ||
1787 | AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); | ||
1788 | bool tp = (aCircuit.teleportFlags > 0); | ||
1789 | // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from | ||
1790 | if (!tp) | ||
1791 | client.SceneAgent.SendInitialDataToMe(); | ||
1792 | } | ||
1793 | } | 1793 | } |
1794 | else | 1794 | else |
1795 | { | 1795 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 0825a01..2c7cd40 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -388,23 +388,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
388 | 388 | ||
389 | Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>(); | 389 | Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>(); |
390 | 390 | ||
391 | foreach (SceneObjectGroup so in attachments) | 391 | if (sp.PresenceType != PresenceType.Npc) |
392 | { | ||
393 | // Scripts MUST be snapshotted before the object is | ||
394 | // removed from the scene because doing otherwise will | ||
395 | // clobber the run flag | ||
396 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | ||
397 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | ||
398 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); | ||
399 | } | ||
400 | |||
401 | lock (sp.AttachmentsSyncLock) | ||
402 | { | 392 | { |
403 | foreach (SceneObjectGroup so in attachments) | 393 | foreach (SceneObjectGroup so in attachments) |
404 | UpdateDetachedObject(sp, so, scriptStates[so]); | 394 | { |
405 | 395 | // Scripts MUST be snapshotted before the object is | |
406 | sp.ClearAttachments(); | 396 | // removed from the scene because doing otherwise will |
397 | // clobber the run flag | ||
398 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | ||
399 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | ||
400 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); | ||
401 | } | ||
402 | |||
403 | lock (sp.AttachmentsSyncLock) | ||
404 | { | ||
405 | foreach (SceneObjectGroup so in attachments) | ||
406 | UpdateDetachedObject(sp, so, scriptStates[so]); | ||
407 | sp.ClearAttachments(); | ||
408 | } | ||
407 | } | 409 | } |
410 | else | ||
411 | { | ||
412 | lock (sp.AttachmentsSyncLock) | ||
413 | { | ||
414 | foreach (SceneObjectGroup so in attachments) | ||
415 | UpdateDetachedObject(sp, so, String.Empty); | ||
416 | sp.ClearAttachments(); | ||
417 | } | ||
418 | } | ||
408 | } | 419 | } |
409 | 420 | ||
410 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) | 421 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) |
@@ -1014,6 +1025,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1014 | // Remove the object from the scene so no more updates | 1025 | // Remove the object from the scene so no more updates |
1015 | // are sent. Doing this before the below changes will ensure | 1026 | // are sent. Doing this before the below changes will ensure |
1016 | // updates can't cause "HUD artefacts" | 1027 | // updates can't cause "HUD artefacts" |
1028 | |||
1017 | m_scene.DeleteSceneObject(so, false, false); | 1029 | m_scene.DeleteSceneObject(so, false, false); |
1018 | 1030 | ||
1019 | // Prepare sog for storage | 1031 | // Prepare sog for storage |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 9b41083..dcfc630 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -236,12 +236,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
236 | fromName = avatar.Name; | 236 | fromName = avatar.Name; |
237 | fromID = c.Sender.AgentId; | 237 | fromID = c.Sender.AgentId; |
238 | if (avatar.GodLevel >= 200) | 238 | if (avatar.GodLevel >= 200) |
239 | { | 239 | { // let gods speak to outside or things may get confusing |
240 | fromNamePrefix = m_adminPrefix; | 240 | fromNamePrefix = m_adminPrefix; |
241 | checkParcelHide = false; | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | checkParcelHide = true; | ||
241 | } | 246 | } |
242 | destination = UUID.Zero; // Avatars cant "SayTo" | 247 | destination = UUID.Zero; // Avatars cant "SayTo" |
243 | ownerID = c.Sender.AgentId; | 248 | ownerID = c.Sender.AgentId; |
244 | checkParcelHide = true; | 249 | |
245 | hidePos = fromPos; | 250 | hidePos = fromPos; |
246 | break; | 251 | break; |
247 | 252 | ||
@@ -305,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
305 | // objects on a parcel with access restrictions | 310 | // objects on a parcel with access restrictions |
306 | if (checkParcelHide) | 311 | if (checkParcelHide) |
307 | { | 312 | { |
308 | if (sourceParcelID != Presencecheck.LandData.GlobalID) | 313 | if (sourceParcelID != Presencecheck.LandData.GlobalID && presence.GodLevel < 200) |
309 | return; | 314 | return; |
310 | } | 315 | } |
311 | if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) | 316 | if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index d8e3082..c8555ab 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -368,7 +368,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
368 | public void SendOutNearestBanLine(IClientAPI client) | 368 | public void SendOutNearestBanLine(IClientAPI client) |
369 | { | 369 | { |
370 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 370 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
371 | if (sp == null || sp.IsChildAgent) | 371 | if (sp == null) |
372 | return; | 372 | return; |
373 | 373 | ||
374 | List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); | 374 | List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); |
@@ -394,11 +394,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
394 | 394 | ||
395 | if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar)) | 395 | if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar)) |
396 | return; | 396 | return; |
397 | if (avatar.IsChildAgent) | ||
398 | return; | ||
399 | 397 | ||
400 | SendParcelOverlay(remoteClient); | 398 | SendParcelOverlay(remoteClient); |
401 | 399 | ||
400 | if (avatar.IsChildAgent) | ||
401 | return; | ||
402 | |||
402 | ILandObject over = GetLandObject(avatar.AbsolutePosition.X,avatar.AbsolutePosition.Y); | 403 | ILandObject over = GetLandObject(avatar.AbsolutePosition.X,avatar.AbsolutePosition.Y); |
403 | if (over == null) | 404 | if (over == null) |
404 | return; | 405 | return; |
@@ -958,7 +959,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
958 | UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); | 959 | UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); |
959 | m_scene.ForEachClient(SendParcelOverlay); | 960 | m_scene.ForEachClient(SendParcelOverlay); |
960 | result.SendLandUpdateToAvatarsOverMe(); | 961 | result.SendLandUpdateToAvatarsOverMe(); |
961 | 962 | startLandObject.SendLandUpdateToAvatarsOverMe(); | |
962 | } | 963 | } |
963 | 964 | ||
964 | /// <summary> | 965 | /// <summary> |
@@ -1047,7 +1048,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1047 | /// <param name="remote_client">The object representing the client</param> | 1048 | /// <param name="remote_client">The object representing the client</param> |
1048 | public void SendParcelOverlay(IClientAPI remote_client) | 1049 | public void SendParcelOverlay(IClientAPI remote_client) |
1049 | { | 1050 | { |
1050 | |||
1051 | if (remote_client.SceneAgent.PresenceType == PresenceType.Npc) | 1051 | if (remote_client.SceneAgent.PresenceType == PresenceType.Npc) |
1052 | return; | 1052 | return; |
1053 | 1053 | ||
@@ -1198,20 +1198,24 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1198 | bool needOverlay = false; | 1198 | bool needOverlay = false; |
1199 | if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay)) | 1199 | if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay)) |
1200 | { | 1200 | { |
1201 | //the proprieties to who changed it | 1201 | //the proprieties to who changed them |
1202 | 1202 | ||
1203 | land.SendLandProperties(0, true, LandChannel.LAND_RESULT_SINGLE, remote_client); | 1203 | land.SendLandProperties(0, true, LandChannel.LAND_RESULT_SINGLE, remote_client); |
1204 | 1204 | ||
1205 | if (needOverlay) | 1205 | if (needOverlay) |
1206 | { | 1206 | { |
1207 | UUID parcelID = land.LandData.GlobalID; | 1207 | UUID parcelID = land.LandData.GlobalID; |
1208 | m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar) | 1208 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
1209 | { | 1209 | { |
1210 | if (avatar.IsDeleted || avatar.IsChildAgent) | 1210 | if (avatar.IsDeleted || avatar.isNPC) |
1211 | return; | 1211 | return; |
1212 | 1212 | ||
1213 | IClientAPI client = avatar.ControllingClient; | 1213 | IClientAPI client = avatar.ControllingClient; |
1214 | SendParcelOverlay(client); | 1214 | SendParcelOverlay(client); |
1215 | |||
1216 | if (avatar.IsChildAgent) | ||
1217 | return; | ||
1218 | |||
1215 | ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 1219 | ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
1216 | if (aland != null) | 1220 | if (aland != null) |
1217 | { | 1221 | { |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 29c2234..e002feb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -617,6 +617,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
617 | avatar.Invulnerable = true; | 617 | avatar.Invulnerable = true; |
618 | 618 | ||
619 | SendLandUpdateToClient(snap_selection, avatar.ControllingClient); | 619 | SendLandUpdateToClient(snap_selection, avatar.ControllingClient); |
620 | avatar.currentParcelUUID = LandData.GlobalID; | ||
620 | } | 621 | } |
621 | } | 622 | } |
622 | }); | 623 | }); |
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 7f06e82..692e0c9 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs | |||
@@ -1366,7 +1366,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1366 | { | 1366 | { |
1367 | try | 1367 | try |
1368 | { | 1368 | { |
1369 | // m_log.ErrorFormat("[EVENT MANAGER]: OnRemovePresenceDelegate: {0}",d.Target.ToString()); | ||
1369 | d(agentId); | 1370 | d(agentId); |
1371 | // m_log.ErrorFormat("[EVENT MANAGER]: OnRemovePresenceDelegate done "); | ||
1370 | } | 1372 | } |
1371 | catch (Exception e) | 1373 | catch (Exception e) |
1372 | { | 1374 | { |
@@ -2037,7 +2039,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2037 | { | 2039 | { |
2038 | try | 2040 | try |
2039 | { | 2041 | { |
2042 | // m_log.ErrorFormat("[EVENT MANAGER]: TriggerClientClosed: {0}", d.Target.ToString()); | ||
2040 | d(ClientID, scene); | 2043 | d(ClientID, scene); |
2044 | // m_log.ErrorFormat("[EVENT MANAGER]: TriggerClientClosed done "); | ||
2045 | |||
2041 | } | 2046 | } |
2042 | catch (Exception e) | 2047 | catch (Exception e) |
2043 | { | 2048 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 746b703..8634a3a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -1234,8 +1234,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1234 | { | 1234 | { |
1235 | uint perms = taskItem.CurrentPermissions; | 1235 | uint perms = taskItem.CurrentPermissions; |
1236 | PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms); | 1236 | PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms); |
1237 | agentItem.BasePermissions = perms | (uint)PermissionMask.Move; | 1237 | // agentItem.BasePermissions = perms | (uint)PermissionMask.Move; |
1238 | agentItem.CurrentPermissions = agentItem.BasePermissions; | 1238 | // agentItem.CurrentPermissions = agentItem.BasePermissions; |
1239 | agentItem.CurrentPermissions = perms | (uint)PermissionMask.Move; | ||
1239 | } | 1240 | } |
1240 | else | 1241 | else |
1241 | { | 1242 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0765b3f..0266faf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -3640,13 +3640,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3640 | } | 3640 | } |
3641 | 3641 | ||
3642 | m_eventManager.TriggerClientClosed(agentID, this); | 3642 | m_eventManager.TriggerClientClosed(agentID, this); |
3643 | // m_log.Debug("[Scene]TriggerClientClosed done"); | ||
3643 | m_eventManager.TriggerOnRemovePresence(agentID); | 3644 | m_eventManager.TriggerOnRemovePresence(agentID); |
3645 | // m_log.Debug("[Scene]TriggerOnRemovePresence done"); | ||
3644 | 3646 | ||
3645 | if (!isChildAgent) | 3647 | if (!isChildAgent) |
3646 | { | 3648 | { |
3647 | if (AttachmentsModule != null) | 3649 | if (AttachmentsModule != null) |
3648 | { | 3650 | { |
3651 | // m_log.Debug("[Scene]DeRezAttachments"); | ||
3649 | AttachmentsModule.DeRezAttachments(avatar); | 3652 | AttachmentsModule.DeRezAttachments(avatar); |
3653 | // m_log.Debug("[Scene]DeRezAttachments done"); | ||
3650 | } | 3654 | } |
3651 | 3655 | ||
3652 | ForEachClient( | 3656 | ForEachClient( |
@@ -3660,7 +3664,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3660 | 3664 | ||
3661 | // It's possible for child agents to have transactions if changes are being made cross-border. | 3665 | // It's possible for child agents to have transactions if changes are being made cross-border. |
3662 | if (AgentTransactionsModule != null) | 3666 | if (AgentTransactionsModule != null) |
3667 | { | ||
3668 | // m_log.Debug("[Scene]RemoveAgentAssetTransactions"); | ||
3663 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); | 3669 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); |
3670 | } | ||
3664 | m_log.Debug("[Scene] The avatar has left the building"); | 3671 | m_log.Debug("[Scene] The avatar has left the building"); |
3665 | } | 3672 | } |
3666 | catch (Exception e) | 3673 | catch (Exception e) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 08e26c5..dd0c828 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs | |||
@@ -1,581 +1,581 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Threading; | 31 | using System.Threading; |
32 | using OpenMetaverse; | 32 | using OpenMetaverse; |
33 | using log4net; | 33 | using log4net; |
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Console; | 36 | using OpenSim.Framework.Console; |
37 | 37 | ||
38 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
39 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 39 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
40 | 40 | ||
41 | namespace OpenSim.Region.Framework.Scenes | 41 | namespace OpenSim.Region.Framework.Scenes |
42 | { | 42 | { |
43 | public abstract class SceneBase : IScene | 43 | public abstract class SceneBase : IScene |
44 | { | 44 | { |
45 | protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | protected static readonly string LogHeader = "[SCENE]"; | 46 | protected static readonly string LogHeader = "[SCENE]"; |
47 | 47 | ||
48 | #region Events | 48 | #region Events |
49 | 49 | ||
50 | public event restart OnRestart; | 50 | public event restart OnRestart; |
51 | 51 | ||
52 | #endregion | 52 | #endregion |
53 | 53 | ||
54 | #region Fields | 54 | #region Fields |
55 | 55 | ||
56 | public string Name { get { return RegionInfo.RegionName; } } | 56 | public string Name { get { return RegionInfo.RegionName; } } |
57 | 57 | ||
58 | public IConfigSource Config | 58 | public IConfigSource Config |
59 | { | 59 | { |
60 | get { return GetConfig(); } | 60 | get { return GetConfig(); } |
61 | } | 61 | } |
62 | 62 | ||
63 | protected virtual IConfigSource GetConfig() | 63 | protected virtual IConfigSource GetConfig() |
64 | { | 64 | { |
65 | return null; | 65 | return null; |
66 | } | 66 | } |
67 | 67 | ||
68 | /// <value> | 68 | /// <value> |
69 | /// All the region modules attached to this scene. | 69 | /// All the region modules attached to this scene. |
70 | /// </value> | 70 | /// </value> |
71 | public Dictionary<string, IRegionModuleBase> RegionModules | 71 | public Dictionary<string, IRegionModuleBase> RegionModules |
72 | { | 72 | { |
73 | get { return m_regionModules; } | 73 | get { return m_regionModules; } |
74 | } | 74 | } |
75 | private Dictionary<string, IRegionModuleBase> m_regionModules = new Dictionary<string, IRegionModuleBase>(); | 75 | private Dictionary<string, IRegionModuleBase> m_regionModules = new Dictionary<string, IRegionModuleBase>(); |
76 | 76 | ||
77 | /// <value> | 77 | /// <value> |
78 | /// The module interfaces available from this scene. | 78 | /// The module interfaces available from this scene. |
79 | /// </value> | 79 | /// </value> |
80 | protected Dictionary<Type, List<object>> ModuleInterfaces = new Dictionary<Type, List<object>>(); | 80 | protected Dictionary<Type, List<object>> ModuleInterfaces = new Dictionary<Type, List<object>>(); |
81 | 81 | ||
82 | protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>(); | 82 | protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>(); |
83 | 83 | ||
84 | /// <value> | 84 | /// <value> |
85 | /// The module commanders available from this scene | 85 | /// The module commanders available from this scene |
86 | /// </value> | 86 | /// </value> |
87 | protected Dictionary<string, ICommander> m_moduleCommanders = new Dictionary<string, ICommander>(); | 87 | protected Dictionary<string, ICommander> m_moduleCommanders = new Dictionary<string, ICommander>(); |
88 | 88 | ||
89 | /// <value> | 89 | /// <value> |
90 | /// Registered classes that are capable of creating entities. | 90 | /// Registered classes that are capable of creating entities. |
91 | /// </value> | 91 | /// </value> |
92 | protected Dictionary<PCode, IEntityCreator> m_entityCreators = new Dictionary<PCode, IEntityCreator>(); | 92 | protected Dictionary<PCode, IEntityCreator> m_entityCreators = new Dictionary<PCode, IEntityCreator>(); |
93 | 93 | ||
94 | /// <summary> | 94 | /// <summary> |
95 | /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is | 95 | /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is |
96 | /// dispensed. | 96 | /// dispensed. |
97 | /// </summary> | 97 | /// </summary> |
98 | protected uint m_lastAllocatedLocalId = 720000; | 98 | protected uint m_lastAllocatedLocalId = 720000; |
99 | 99 | ||
100 | private readonly Mutex _primAllocateMutex = new Mutex(false); | 100 | private readonly Mutex _primAllocateMutex = new Mutex(false); |
101 | 101 | ||
102 | protected readonly ClientManager m_clientManager = new ClientManager(); | 102 | protected readonly ClientManager m_clientManager = new ClientManager(); |
103 | 103 | ||
104 | public bool LoginsEnabled | 104 | public bool LoginsEnabled |
105 | { | 105 | { |
106 | get | 106 | get |
107 | { | 107 | { |
108 | return m_loginsEnabled; | 108 | return m_loginsEnabled; |
109 | } | 109 | } |
110 | 110 | ||
111 | set | 111 | set |
112 | { | 112 | { |
113 | if (m_loginsEnabled != value) | 113 | if (m_loginsEnabled != value) |
114 | { | 114 | { |
115 | m_loginsEnabled = value; | 115 | m_loginsEnabled = value; |
116 | EventManager.TriggerRegionLoginsStatusChange(this); | 116 | EventManager.TriggerRegionLoginsStatusChange(this); |
117 | } | 117 | } |
118 | } | 118 | } |
119 | } | 119 | } |
120 | private bool m_loginsEnabled; | 120 | private bool m_loginsEnabled; |
121 | 121 | ||
122 | public bool Ready | 122 | public bool Ready |
123 | { | 123 | { |
124 | get | 124 | get |
125 | { | 125 | { |
126 | return m_ready; | 126 | return m_ready; |
127 | } | 127 | } |
128 | 128 | ||
129 | set | 129 | set |
130 | { | 130 | { |
131 | if (m_ready != value) | 131 | if (m_ready != value) |
132 | { | 132 | { |
133 | m_ready = value; | 133 | m_ready = value; |
134 | EventManager.TriggerRegionReadyStatusChange(this); | 134 | EventManager.TriggerRegionReadyStatusChange(this); |
135 | } | 135 | } |
136 | } | 136 | } |
137 | } | 137 | } |
138 | private bool m_ready; | 138 | private bool m_ready; |
139 | 139 | ||
140 | public float TimeDilation | 140 | public float TimeDilation |
141 | { | 141 | { |
142 | get { return 1.0f; } | 142 | get { return 1.0f; } |
143 | } | 143 | } |
144 | 144 | ||
145 | protected ulong m_regionHandle; | 145 | protected ulong m_regionHandle; |
146 | protected string m_regionName; | 146 | protected string m_regionName; |
147 | 147 | ||
148 | public ITerrainChannel Heightmap; | 148 | public ITerrainChannel Heightmap; |
149 | 149 | ||
150 | /// <value> | 150 | /// <value> |
151 | /// Allows retrieval of land information for this scene. | 151 | /// Allows retrieval of land information for this scene. |
152 | /// </value> | 152 | /// </value> |
153 | public ILandChannel LandChannel; | 153 | public ILandChannel LandChannel; |
154 | 154 | ||
155 | /// <value> | 155 | /// <value> |
156 | /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules | 156 | /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules |
157 | /// to subscribe to scene events. | 157 | /// to subscribe to scene events. |
158 | /// </value> | 158 | /// </value> |
159 | public EventManager EventManager | 159 | public EventManager EventManager |
160 | { | 160 | { |
161 | get { return m_eventManager; } | 161 | get { return m_eventManager; } |
162 | } | 162 | } |
163 | protected EventManager m_eventManager; | 163 | protected EventManager m_eventManager; |
164 | 164 | ||
165 | protected ScenePermissions m_permissions; | 165 | protected ScenePermissions m_permissions; |
166 | public ScenePermissions Permissions | 166 | public ScenePermissions Permissions |
167 | { | 167 | { |
168 | get { return m_permissions; } | 168 | get { return m_permissions; } |
169 | } | 169 | } |
170 | 170 | ||
171 | protected string m_datastore; | 171 | protected string m_datastore; |
172 | 172 | ||
173 | /* Used by the loadbalancer plugin on GForge */ | 173 | /* Used by the loadbalancer plugin on GForge */ |
174 | protected RegionStatus m_regStatus; | 174 | protected RegionStatus m_regStatus; |
175 | public RegionStatus RegionStatus | 175 | public RegionStatus RegionStatus |
176 | { | 176 | { |
177 | get { return m_regStatus; } | 177 | get { return m_regStatus; } |
178 | set { m_regStatus = value; } | 178 | set { m_regStatus = value; } |
179 | } | 179 | } |
180 | 180 | ||
181 | #endregion | 181 | #endregion |
182 | 182 | ||
183 | public SceneBase(RegionInfo regInfo) | 183 | public SceneBase(RegionInfo regInfo) |
184 | { | 184 | { |
185 | RegionInfo = regInfo; | 185 | RegionInfo = regInfo; |
186 | } | 186 | } |
187 | 187 | ||
188 | #region Update Methods | 188 | #region Update Methods |
189 | 189 | ||
190 | /// <summary> | 190 | /// <summary> |
191 | /// Called to update the scene loop by a number of frames and until shutdown. | 191 | /// Called to update the scene loop by a number of frames and until shutdown. |
192 | /// </summary> | 192 | /// </summary> |
193 | /// <param name="frames"> | 193 | /// <param name="frames"> |
194 | /// Number of frames to update. Exits on shutdown even if there are frames remaining. | 194 | /// Number of frames to update. Exits on shutdown even if there are frames remaining. |
195 | /// If -1 then updates until shutdown. | 195 | /// If -1 then updates until shutdown. |
196 | /// </param> | 196 | /// </param> |
197 | public abstract void Update(int frames); | 197 | public abstract void Update(int frames); |
198 | 198 | ||
199 | #endregion | 199 | #endregion |
200 | 200 | ||
201 | #region Terrain Methods | 201 | #region Terrain Methods |
202 | 202 | ||
203 | /// <summary> | 203 | /// <summary> |
204 | /// Loads the World heightmap | 204 | /// Loads the World heightmap |
205 | /// </summary> | 205 | /// </summary> |
206 | public abstract void LoadWorldMap(); | 206 | public abstract void LoadWorldMap(); |
207 | 207 | ||
208 | /// <summary> | 208 | /// <summary> |
209 | /// Send the region heightmap to the client | 209 | /// Send the region heightmap to the client |
210 | /// </summary> | 210 | /// </summary> |
211 | /// <param name="RemoteClient">Client to send to</param> | 211 | /// <param name="RemoteClient">Client to send to</param> |
212 | public virtual void SendLayerData(IClientAPI RemoteClient) | 212 | public virtual void SendLayerData(IClientAPI RemoteClient) |
213 | { | 213 | { |
214 | RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); | 214 | RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); |
215 | } | 215 | } |
216 | 216 | ||
217 | #endregion | 217 | #endregion |
218 | 218 | ||
219 | #region Add/Remove Agent/Avatar | 219 | #region Add/Remove Agent/Avatar |
220 | 220 | ||
221 | public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); | 221 | public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); |
222 | 222 | ||
223 | public abstract bool CloseAgent(UUID agentID, bool force); | 223 | public abstract bool CloseAgent(UUID agentID, bool force); |
224 | 224 | ||
225 | public bool TryGetScenePresence(UUID agentID, out object scenePresence) | 225 | public bool TryGetScenePresence(UUID agentID, out object scenePresence) |
226 | { | 226 | { |
227 | scenePresence = null; | 227 | scenePresence = null; |
228 | ScenePresence sp = null; | 228 | ScenePresence sp = null; |
229 | if (TryGetScenePresence(agentID, out sp)) | 229 | if (TryGetScenePresence(agentID, out sp)) |
230 | { | 230 | { |
231 | scenePresence = sp; | 231 | scenePresence = sp; |
232 | return true; | 232 | return true; |
233 | } | 233 | } |
234 | 234 | ||
235 | return false; | 235 | return false; |
236 | } | 236 | } |
237 | 237 | ||
238 | /// <summary> | 238 | /// <summary> |
239 | /// Try to get a scene presence from the scene | 239 | /// Try to get a scene presence from the scene |
240 | /// </summary> | 240 | /// </summary> |
241 | /// <param name="agentID"></param> | 241 | /// <param name="agentID"></param> |
242 | /// <param name="scenePresence">null if there is no scene presence with the given agent id</param> | 242 | /// <param name="scenePresence">null if there is no scene presence with the given agent id</param> |
243 | /// <returns>true if there was a scene presence with the given id, false otherwise.</returns> | 243 | /// <returns>true if there was a scene presence with the given id, false otherwise.</returns> |
244 | public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); | 244 | public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); |
245 | 245 | ||
246 | #endregion | 246 | #endregion |
247 | 247 | ||
248 | /// <summary> | 248 | /// <summary> |
249 | /// | 249 | /// |
250 | /// </summary> | 250 | /// </summary> |
251 | /// <returns></returns> | 251 | /// <returns></returns> |
252 | public virtual RegionInfo RegionInfo { get; private set; } | 252 | public virtual RegionInfo RegionInfo { get; private set; } |
253 | 253 | ||
254 | #region admin stuff | 254 | #region admin stuff |
255 | 255 | ||
256 | public abstract void OtherRegionUp(GridRegion otherRegion); | 256 | public abstract void OtherRegionUp(GridRegion otherRegion); |
257 | 257 | ||
258 | public virtual string GetSimulatorVersion() | 258 | public virtual string GetSimulatorVersion() |
259 | { | 259 | { |
260 | return "OpenSimulator Server"; | 260 | return "OpenSimulator Server"; |
261 | } | 261 | } |
262 | 262 | ||
263 | #endregion | 263 | #endregion |
264 | 264 | ||
265 | #region Shutdown | 265 | #region Shutdown |
266 | 266 | ||
267 | /// <summary> | 267 | /// <summary> |
268 | /// Tidy before shutdown | 268 | /// Tidy before shutdown |
269 | /// </summary> | 269 | /// </summary> |
270 | public virtual void Close() | 270 | public virtual void Close() |
271 | { | 271 | { |
272 | try | 272 | try |
273 | { | 273 | { |
274 | EventManager.TriggerShutdown(); | 274 | EventManager.TriggerShutdown(); |
275 | } | 275 | } |
276 | catch (Exception e) | 276 | catch (Exception e) |
277 | { | 277 | { |
278 | m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); | 278 | m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); |
279 | } | 279 | } |
280 | } | 280 | } |
281 | 281 | ||
282 | #endregion | 282 | #endregion |
283 | 283 | ||
284 | /// <summary> | 284 | /// <summary> |
285 | /// Returns a new unallocated local ID | 285 | /// Returns a new unallocated local ID |
286 | /// </summary> | 286 | /// </summary> |
287 | /// <returns>A brand new local ID</returns> | 287 | /// <returns>A brand new local ID</returns> |
288 | public uint AllocateLocalId() | 288 | public uint AllocateLocalId() |
289 | { | 289 | { |
290 | uint myID; | 290 | uint myID; |
291 | 291 | ||
292 | _primAllocateMutex.WaitOne(); | 292 | _primAllocateMutex.WaitOne(); |
293 | myID = ++m_lastAllocatedLocalId; | 293 | myID = ++m_lastAllocatedLocalId; |
294 | _primAllocateMutex.ReleaseMutex(); | 294 | _primAllocateMutex.ReleaseMutex(); |
295 | 295 | ||
296 | return myID; | 296 | return myID; |
297 | } | 297 | } |
298 | 298 | ||
299 | #region Module Methods | 299 | #region Module Methods |
300 | 300 | ||
301 | /// <summary> | 301 | /// <summary> |
302 | /// Add a region-module to this scene. TODO: This will replace AddModule in the future. | 302 | /// Add a region-module to this scene. TODO: This will replace AddModule in the future. |
303 | /// </summary> | 303 | /// </summary> |
304 | /// <param name="name"></param> | 304 | /// <param name="name"></param> |
305 | /// <param name="module"></param> | 305 | /// <param name="module"></param> |
306 | public void AddRegionModule(string name, IRegionModuleBase module) | 306 | public void AddRegionModule(string name, IRegionModuleBase module) |
307 | { | 307 | { |
308 | if (!RegionModules.ContainsKey(name)) | 308 | if (!RegionModules.ContainsKey(name)) |
309 | { | 309 | { |
310 | RegionModules.Add(name, module); | 310 | RegionModules.Add(name, module); |
311 | } | 311 | } |
312 | } | 312 | } |
313 | 313 | ||
314 | public void RemoveRegionModule(string name) | 314 | public void RemoveRegionModule(string name) |
315 | { | 315 | { |
316 | RegionModules.Remove(name); | 316 | RegionModules.Remove(name); |
317 | } | 317 | } |
318 | 318 | ||
319 | /// <summary> | 319 | /// <summary> |
320 | /// Register a module commander. | 320 | /// Register a module commander. |
321 | /// </summary> | 321 | /// </summary> |
322 | /// <param name="commander"></param> | 322 | /// <param name="commander"></param> |
323 | public void RegisterModuleCommander(ICommander commander) | 323 | public void RegisterModuleCommander(ICommander commander) |
324 | { | 324 | { |
325 | lock (m_moduleCommanders) | 325 | lock (m_moduleCommanders) |
326 | { | 326 | { |
327 | m_moduleCommanders.Add(commander.Name, commander); | 327 | m_moduleCommanders.Add(commander.Name, commander); |
328 | } | 328 | } |
329 | } | 329 | } |
330 | 330 | ||
331 | /// <summary> | 331 | /// <summary> |
332 | /// Unregister a module commander and all its commands | 332 | /// Unregister a module commander and all its commands |
333 | /// </summary> | 333 | /// </summary> |
334 | /// <param name="name"></param> | 334 | /// <param name="name"></param> |
335 | public void UnregisterModuleCommander(string name) | 335 | public void UnregisterModuleCommander(string name) |
336 | { | 336 | { |
337 | lock (m_moduleCommanders) | 337 | lock (m_moduleCommanders) |
338 | { | 338 | { |
339 | ICommander commander; | 339 | ICommander commander; |
340 | if (m_moduleCommanders.TryGetValue(name, out commander)) | 340 | if (m_moduleCommanders.TryGetValue(name, out commander)) |
341 | m_moduleCommanders.Remove(name); | 341 | m_moduleCommanders.Remove(name); |
342 | } | 342 | } |
343 | } | 343 | } |
344 | 344 | ||
345 | /// <summary> | 345 | /// <summary> |
346 | /// Get a module commander | 346 | /// Get a module commander |
347 | /// </summary> | 347 | /// </summary> |
348 | /// <param name="name"></param> | 348 | /// <param name="name"></param> |
349 | /// <returns>The module commander, null if no module commander with that name was found</returns> | 349 | /// <returns>The module commander, null if no module commander with that name was found</returns> |
350 | public ICommander GetCommander(string name) | 350 | public ICommander GetCommander(string name) |
351 | { | 351 | { |
352 | lock (m_moduleCommanders) | 352 | lock (m_moduleCommanders) |
353 | { | 353 | { |
354 | if (m_moduleCommanders.ContainsKey(name)) | 354 | if (m_moduleCommanders.ContainsKey(name)) |
355 | return m_moduleCommanders[name]; | 355 | return m_moduleCommanders[name]; |
356 | } | 356 | } |
357 | 357 | ||
358 | return null; | 358 | return null; |
359 | } | 359 | } |
360 | 360 | ||
361 | public Dictionary<string, ICommander> GetCommanders() | 361 | public Dictionary<string, ICommander> GetCommanders() |
362 | { | 362 | { |
363 | return m_moduleCommanders; | 363 | return m_moduleCommanders; |
364 | } | 364 | } |
365 | 365 | ||
366 | /// <summary> | 366 | /// <summary> |
367 | /// Register an interface to a region module. This allows module methods to be called directly as | 367 | /// Register an interface to a region module. This allows module methods to be called directly as |
368 | /// well as via events. If there is already a module registered for this interface, it is not replaced | 368 | /// well as via events. If there is already a module registered for this interface, it is not replaced |
369 | /// (is this the best behaviour?) | 369 | /// (is this the best behaviour?) |
370 | /// </summary> | 370 | /// </summary> |
371 | /// <param name="mod"></param> | 371 | /// <param name="mod"></param> |
372 | public void RegisterModuleInterface<M>(M mod) | 372 | public void RegisterModuleInterface<M>(M mod) |
373 | { | 373 | { |
374 | // m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); | 374 | // m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); |
375 | 375 | ||
376 | List<Object> l = null; | 376 | List<Object> l = null; |
377 | if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) | 377 | if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) |
378 | { | 378 | { |
379 | l = new List<Object>(); | 379 | l = new List<Object>(); |
380 | ModuleInterfaces.Add(typeof(M), l); | 380 | ModuleInterfaces.Add(typeof(M), l); |
381 | } | 381 | } |
382 | 382 | ||
383 | if (l.Count > 0) | 383 | if (l.Count > 0) |
384 | return; | 384 | return; |
385 | 385 | ||
386 | l.Add(mod); | 386 | l.Add(mod); |
387 | 387 | ||
388 | if (mod is IEntityCreator) | 388 | if (mod is IEntityCreator) |
389 | { | 389 | { |
390 | IEntityCreator entityCreator = (IEntityCreator)mod; | 390 | IEntityCreator entityCreator = (IEntityCreator)mod; |
391 | foreach (PCode pcode in entityCreator.CreationCapabilities) | 391 | foreach (PCode pcode in entityCreator.CreationCapabilities) |
392 | { | 392 | { |
393 | m_entityCreators[pcode] = entityCreator; | 393 | m_entityCreators[pcode] = entityCreator; |
394 | } | 394 | } |
395 | } | 395 | } |
396 | } | 396 | } |
397 | 397 | ||
398 | public void UnregisterModuleInterface<M>(M mod) | 398 | public void UnregisterModuleInterface<M>(M mod) |
399 | { | 399 | { |
400 | List<Object> l; | 400 | List<Object> l; |
401 | if (ModuleInterfaces.TryGetValue(typeof(M), out l)) | 401 | if (ModuleInterfaces.TryGetValue(typeof(M), out l)) |
402 | { | 402 | { |
403 | if (l.Remove(mod)) | 403 | if (l.Remove(mod)) |
404 | { | 404 | { |
405 | if (mod is IEntityCreator) | 405 | if (mod is IEntityCreator) |
406 | { | 406 | { |
407 | IEntityCreator entityCreator = (IEntityCreator)mod; | 407 | IEntityCreator entityCreator = (IEntityCreator)mod; |
408 | foreach (PCode pcode in entityCreator.CreationCapabilities) | 408 | foreach (PCode pcode in entityCreator.CreationCapabilities) |
409 | { | 409 | { |
410 | m_entityCreators[pcode] = null; | 410 | m_entityCreators[pcode] = null; |
411 | } | 411 | } |
412 | } | 412 | } |
413 | } | 413 | } |
414 | } | 414 | } |
415 | } | 415 | } |
416 | 416 | ||
417 | public void StackModuleInterface<M>(M mod) | 417 | public void StackModuleInterface<M>(M mod) |
418 | { | 418 | { |
419 | List<Object> l; | 419 | List<Object> l; |
420 | if (ModuleInterfaces.ContainsKey(typeof(M))) | 420 | if (ModuleInterfaces.ContainsKey(typeof(M))) |
421 | l = ModuleInterfaces[typeof(M)]; | 421 | l = ModuleInterfaces[typeof(M)]; |
422 | else | 422 | else |
423 | l = new List<Object>(); | 423 | l = new List<Object>(); |
424 | 424 | ||
425 | if (l.Contains(mod)) | 425 | if (l.Contains(mod)) |
426 | return; | 426 | return; |
427 | 427 | ||
428 | l.Add(mod); | 428 | l.Add(mod); |
429 | 429 | ||
430 | if (mod is IEntityCreator) | 430 | if (mod is IEntityCreator) |
431 | { | 431 | { |
432 | IEntityCreator entityCreator = (IEntityCreator)mod; | 432 | IEntityCreator entityCreator = (IEntityCreator)mod; |
433 | foreach (PCode pcode in entityCreator.CreationCapabilities) | 433 | foreach (PCode pcode in entityCreator.CreationCapabilities) |
434 | { | 434 | { |
435 | m_entityCreators[pcode] = entityCreator; | 435 | m_entityCreators[pcode] = entityCreator; |
436 | } | 436 | } |
437 | } | 437 | } |
438 | 438 | ||
439 | ModuleInterfaces[typeof(M)] = l; | 439 | ModuleInterfaces[typeof(M)] = l; |
440 | } | 440 | } |
441 | 441 | ||
442 | /// <summary> | 442 | /// <summary> |
443 | /// For the given interface, retrieve the region module which implements it. | 443 | /// For the given interface, retrieve the region module which implements it. |
444 | /// </summary> | 444 | /// </summary> |
445 | /// <returns>null if there is no registered module implementing that interface</returns> | 445 | /// <returns>null if there is no registered module implementing that interface</returns> |
446 | public T RequestModuleInterface<T>() | 446 | public T RequestModuleInterface<T>() |
447 | { | 447 | { |
448 | if (ModuleInterfaces.ContainsKey(typeof(T)) && | 448 | if (ModuleInterfaces.ContainsKey(typeof(T)) && |
449 | (ModuleInterfaces[typeof(T)].Count > 0)) | 449 | (ModuleInterfaces[typeof(T)].Count > 0)) |
450 | return (T)ModuleInterfaces[typeof(T)][0]; | 450 | return (T)ModuleInterfaces[typeof(T)][0]; |
451 | else | 451 | else |
452 | return default(T); | 452 | return default(T); |
453 | } | 453 | } |
454 | 454 | ||
455 | /// <summary> | 455 | /// <summary> |
456 | /// For the given interface, retrieve an array of region modules that implement it. | 456 | /// For the given interface, retrieve an array of region modules that implement it. |
457 | /// </summary> | 457 | /// </summary> |
458 | /// <returns>an empty array if there are no registered modules implementing that interface</returns> | 458 | /// <returns>an empty array if there are no registered modules implementing that interface</returns> |
459 | public T[] RequestModuleInterfaces<T>() | 459 | public T[] RequestModuleInterfaces<T>() |
460 | { | 460 | { |
461 | if (ModuleInterfaces.ContainsKey(typeof(T))) | 461 | if (ModuleInterfaces.ContainsKey(typeof(T))) |
462 | { | 462 | { |
463 | List<T> ret = new List<T>(); | 463 | List<T> ret = new List<T>(); |
464 | 464 | ||
465 | foreach (Object o in ModuleInterfaces[typeof(T)]) | 465 | foreach (Object o in ModuleInterfaces[typeof(T)]) |
466 | ret.Add((T)o); | 466 | ret.Add((T)o); |
467 | return ret.ToArray(); | 467 | return ret.ToArray(); |
468 | } | 468 | } |
469 | else | 469 | else |
470 | { | 470 | { |
471 | return new T[] {}; | 471 | return new T[] {}; |
472 | } | 472 | } |
473 | } | 473 | } |
474 | 474 | ||
475 | #endregion | 475 | #endregion |
476 | 476 | ||
477 | /// <summary> | 477 | /// <summary> |
478 | /// Call this from a region module to add a command to the OpenSim console. | 478 | /// Call this from a region module to add a command to the OpenSim console. |
479 | /// </summary> | 479 | /// </summary> |
480 | /// <param name="mod"></param> | 480 | /// <param name="mod"></param> |
481 | /// <param name="command"></param> | 481 | /// <param name="command"></param> |
482 | /// <param name="shorthelp"></param> | 482 | /// <param name="shorthelp"></param> |
483 | /// <param name="longhelp"></param> | 483 | /// <param name="longhelp"></param> |
484 | /// <param name="callback"></param> | 484 | /// <param name="callback"></param> |
485 | public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) | 485 | public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) |
486 | { | 486 | { |
487 | AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); | 487 | AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); |
488 | } | 488 | } |
489 | 489 | ||
490 | /// <summary> | 490 | /// <summary> |
491 | /// Call this from a region module to add a command to the OpenSim console. | 491 | /// Call this from a region module to add a command to the OpenSim console. |
492 | /// </summary> | 492 | /// </summary> |
493 | /// <param name="mod"> | 493 | /// <param name="mod"> |
494 | /// The use of IRegionModuleBase is a cheap trick to get a different method signature, | 494 | /// The use of IRegionModuleBase is a cheap trick to get a different method signature, |
495 | /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. | 495 | /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. |
496 | /// </param> | 496 | /// </param> |
497 | /// <param name="category"> | 497 | /// <param name="category"> |
498 | /// Category of the command. This is the section under which it will appear when the user asks for help | 498 | /// Category of the command. This is the section under which it will appear when the user asks for help |
499 | /// </param> | 499 | /// </param> |
500 | /// <param name="command"></param> | 500 | /// <param name="command"></param> |
501 | /// <param name="shorthelp"></param> | 501 | /// <param name="shorthelp"></param> |
502 | /// <param name="longhelp"></param> | 502 | /// <param name="longhelp"></param> |
503 | /// <param name="callback"></param> | 503 | /// <param name="callback"></param> |
504 | public void AddCommand( | 504 | public void AddCommand( |
505 | string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) | 505 | string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) |
506 | { | 506 | { |
507 | AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); | 507 | AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); |
508 | } | 508 | } |
509 | 509 | ||
510 | /// <summary> | 510 | /// <summary> |
511 | /// Call this from a region module to add a command to the OpenSim console. | 511 | /// Call this from a region module to add a command to the OpenSim console. |
512 | /// </summary> | 512 | /// </summary> |
513 | /// <param name="mod"></param> | 513 | /// <param name="mod"></param> |
514 | /// <param name="command"></param> | 514 | /// <param name="command"></param> |
515 | /// <param name="shorthelp"></param> | 515 | /// <param name="shorthelp"></param> |
516 | /// <param name="longhelp"></param> | 516 | /// <param name="longhelp"></param> |
517 | /// <param name="descriptivehelp"></param> | 517 | /// <param name="descriptivehelp"></param> |
518 | /// <param name="callback"></param> | 518 | /// <param name="callback"></param> |
519 | public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) | 519 | public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) |
520 | { | 520 | { |
521 | string moduleName = ""; | 521 | string moduleName = ""; |
522 | 522 | ||
523 | if (module != null) | 523 | if (module != null) |
524 | moduleName = module.Name; | 524 | moduleName = module.Name; |
525 | 525 | ||
526 | AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); | 526 | AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); |
527 | } | 527 | } |
528 | 528 | ||
529 | /// <summary> | 529 | /// <summary> |
530 | /// Call this from a region module to add a command to the OpenSim console. | 530 | /// Call this from a region module to add a command to the OpenSim console. |
531 | /// </summary> | 531 | /// </summary> |
532 | /// <param name="category"> | 532 | /// <param name="category"> |
533 | /// Category of the command. This is the section under which it will appear when the user asks for help | 533 | /// Category of the command. This is the section under which it will appear when the user asks for help |
534 | /// </param> | 534 | /// </param> |
535 | /// <param name="mod"></param> | 535 | /// <param name="mod"></param> |
536 | /// <param name="command"></param> | 536 | /// <param name="command"></param> |
537 | /// <param name="shorthelp"></param> | 537 | /// <param name="shorthelp"></param> |
538 | /// <param name="longhelp"></param> | 538 | /// <param name="longhelp"></param> |
539 | /// <param name="descriptivehelp"></param> | 539 | /// <param name="descriptivehelp"></param> |
540 | /// <param name="callback"></param> | 540 | /// <param name="callback"></param> |
541 | public void AddCommand( | 541 | public void AddCommand( |
542 | string category, IRegionModuleBase module, string command, | 542 | string category, IRegionModuleBase module, string command, |
543 | string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) | 543 | string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) |
544 | { | 544 | { |
545 | if (MainConsole.Instance == null) | 545 | if (MainConsole.Instance == null) |
546 | return; | 546 | return; |
547 | 547 | ||
548 | bool shared = false; | 548 | bool shared = false; |
549 | 549 | ||
550 | if (module != null) | 550 | if (module != null) |
551 | shared = module is ISharedRegionModule; | 551 | shared = module is ISharedRegionModule; |
552 | 552 | ||
553 | MainConsole.Instance.Commands.AddCommand( | 553 | MainConsole.Instance.Commands.AddCommand( |
554 | category, shared, command, shorthelp, longhelp, descriptivehelp, callback); | 554 | category, shared, command, shorthelp, longhelp, descriptivehelp, callback); |
555 | } | 555 | } |
556 | 556 | ||
557 | public virtual ISceneObject DeserializeObject(string representation) | 557 | public virtual ISceneObject DeserializeObject(string representation) |
558 | { | 558 | { |
559 | return null; | 559 | return null; |
560 | } | 560 | } |
561 | 561 | ||
562 | public virtual bool AllowScriptCrossings | 562 | public virtual bool AllowScriptCrossings |
563 | { | 563 | { |
564 | get { return false; } | 564 | get { return false; } |
565 | } | 565 | } |
566 | 566 | ||
567 | public virtual void Start() | 567 | public virtual void Start() |
568 | { | 568 | { |
569 | } | 569 | } |
570 | 570 | ||
571 | public void Restart() | 571 | public void Restart() |
572 | { | 572 | { |
573 | // This has to be here to fire the event | 573 | // This has to be here to fire the event |
574 | restart handlerPhysicsCrash = OnRestart; | 574 | restart handlerPhysicsCrash = OnRestart; |
575 | if (handlerPhysicsCrash != null) | 575 | if (handlerPhysicsCrash != null) |
576 | handlerPhysicsCrash(RegionInfo); | 576 | handlerPhysicsCrash(RegionInfo); |
577 | } | 577 | } |
578 | 578 | ||
579 | public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); | 579 | public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); |
580 | } | 580 | } |
581 | } | 581 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a9a6ba4..f41a828 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -164,12 +164,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
164 | lock (parcelLock) | 164 | lock (parcelLock) |
165 | { | 165 | { |
166 | bool oldhide = m_currentParcelHide; | 166 | bool oldhide = m_currentParcelHide; |
167 | bool check = true; | 167 | bool checksame = true; |
168 | if (value != m_currentParcelUUID) | 168 | if (value != m_currentParcelUUID) |
169 | { | 169 | { |
170 | m_previusParcelHide = m_currentParcelHide; | 170 | m_previusParcelHide = m_currentParcelHide; |
171 | m_previusParcelUUID = m_currentParcelUUID; | 171 | m_previusParcelUUID = m_currentParcelUUID; |
172 | check = false; | 172 | checksame = false; |
173 | } | 173 | } |
174 | m_currentParcelUUID = value; | 174 | m_currentParcelUUID = value; |
175 | m_currentParcelHide = false; | 175 | m_currentParcelHide = false; |
@@ -177,8 +177,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
177 | ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y); | 177 | ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y); |
178 | if (land != null && !land.LandData.SeeAVs) | 178 | if (land != null && !land.LandData.SeeAVs) |
179 | m_currentParcelHide = true; | 179 | m_currentParcelHide = true; |
180 | if (m_previusParcelUUID != UUID.Zero) | 180 | |
181 | ParcelCrossCheck(m_currentParcelUUID,m_previusParcelUUID,m_currentParcelHide, m_previusParcelHide, oldhide,check); | 181 | if (m_previusParcelUUID != UUID.Zero || checksame) |
182 | ParcelCrossCheck(m_currentParcelUUID,m_previusParcelUUID,m_currentParcelHide, m_previusParcelHide, oldhide,checksame); | ||
182 | } | 183 | } |
183 | } | 184 | } |
184 | } | 185 | } |
@@ -1835,42 +1836,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
1835 | m_currentParcelUUID = UUID.Zero; | 1836 | m_currentParcelUUID = UUID.Zero; |
1836 | 1837 | ||
1837 | // send initial land overlay and parcel | 1838 | // send initial land overlay and parcel |
1838 | if (!IsChildAgent) | 1839 | ILandChannel landch = m_scene.LandChannel; |
1840 | if (landch != null) | ||
1839 | { | 1841 | { |
1840 | ILandChannel landch = m_scene.LandChannel; | 1842 | landch.sendClientInitialLandInfo(client); |
1841 | if (landch != null) | 1843 | if (!IsChildAgent) |
1842 | { | 1844 | { |
1843 | landch.sendClientInitialLandInfo(client); | ||
1844 | newhide = m_currentParcelHide; | 1845 | newhide = m_currentParcelHide; |
1845 | m_currentParcelHide = false; | 1846 | m_currentParcelHide = false; |
1846 | } | 1847 | } |
1847 | } | 1848 | } |
1848 | 1849 | ||
1849 | |||
1850 | // send agentData to all clients including us (?) | 1850 | // send agentData to all clients including us (?) |
1851 | // get appearance | 1851 | // get appearance |
1852 | // if in cache sent it to all clients | 1852 | // if in cache sent it to all clients |
1853 | // send what we have to us, even if not in cache ( bad? ) | 1853 | // send what we have to us, even if not in cache ( bad? ) |
1854 | ValidateAndSendAppearanceAndAgentData(); | 1854 | ValidateAndSendAppearanceAndAgentData(); |
1855 | 1855 | ||
1856 | // Create child agents in neighbouring regions | ||
1857 | if (openChildAgents && !IsChildAgent) | ||
1858 | { | ||
1859 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | ||
1860 | if (m_agentTransfer != null) | ||
1861 | m_agentTransfer.EnableChildAgents(this); | ||
1862 | } | ||
1863 | |||
1864 | |||
1865 | // attachments | 1856 | // attachments |
1866 | if (isNPC || (TeleportFlags & TeleportFlags.ViaLogin) != 0) | 1857 | if (isNPC || (TeleportFlags & TeleportFlags.ViaLogin) != 0) |
1867 | { | 1858 | { |
1868 | if (Scene.AttachmentsModule != null) | 1859 | if (Scene.AttachmentsModule != null) |
1869 | Util.FireAndForget( | 1860 | // Util.FireAndForget( |
1870 | o => | 1861 | // o => |
1871 | { | 1862 | // { |
1872 | Scene.AttachmentsModule.RezAttachments(this); | 1863 | Scene.AttachmentsModule.RezAttachments(this); |
1873 | }); | 1864 | // }); |
1874 | } | 1865 | } |
1875 | else | 1866 | else |
1876 | { | 1867 | { |
@@ -1894,6 +1885,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1894 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", | 1885 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", |
1895 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); | 1886 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); |
1896 | 1887 | ||
1888 | // Create child agents in neighbouring regions | ||
1889 | if (openChildAgents && !IsChildAgent) | ||
1890 | { | ||
1891 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | ||
1892 | if (m_agentTransfer != null) | ||
1893 | m_agentTransfer.EnableChildAgents(this); | ||
1894 | } | ||
1895 | |||
1897 | // send the rest of the world | 1896 | // send the rest of the world |
1898 | if (m_teleportFlags > 0 && !isNPC) | 1897 | if (m_teleportFlags > 0 && !isNPC) |
1899 | SendInitialDataToMe(); | 1898 | SendInitialDataToMe(); |
@@ -1923,8 +1922,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1923 | } | 1922 | } |
1924 | // if hide force a check | 1923 | // if hide force a check |
1925 | if (!IsChildAgent && newhide) | 1924 | if (!IsChildAgent && newhide) |
1926 | ParcelCrossCheck(m_currentParcelUUID, m_previusParcelUUID, | 1925 | { |
1927 | true, m_previusParcelHide, false, true); | 1926 | ParcelLoginCheck(m_currentParcelUUID); |
1927 | m_currentParcelHide = newhide; | ||
1928 | } | ||
1928 | } | 1929 | } |
1929 | 1930 | ||
1930 | /// <summary> | 1931 | /// <summary> |
@@ -3368,19 +3369,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3368 | 3369 | ||
3369 | public void SendTerseUpdateToAgentClient(ScenePresence p) | 3370 | public void SendTerseUpdateToAgentClient(ScenePresence p) |
3370 | { | 3371 | { |
3371 | // messy checks because a client doesn't know what presence it belongs too | ||
3372 | |||
3373 | IClientAPI remoteClient = p.ControllingClient; | 3372 | IClientAPI remoteClient = p.ControllingClient; |
3374 | if (remoteClient == null) | ||
3375 | return; | ||
3376 | 3373 | ||
3377 | if (!remoteClient.IsActive) | 3374 | if (!remoteClient.IsActive) |
3378 | return; | 3375 | return; |
3379 | 3376 | ||
3380 | if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID) | 3377 | if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && p.GodLevel < 200) |
3381 | return; | 3378 | return; |
3382 | 3379 | ||
3383 | |||
3384 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); | 3380 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); |
3385 | remoteClient.SendEntityUpdate( | 3381 | remoteClient.SendEntityUpdate( |
3386 | this, | 3382 | this, |
@@ -3464,6 +3460,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3464 | // we created a new ScenePresence (a new child agent) in a fresh region. | 3460 | // we created a new ScenePresence (a new child agent) in a fresh region. |
3465 | // Request info about all the (root) agents in this region | 3461 | // Request info about all the (root) agents in this region |
3466 | // Note: This won't send data *to* other clients in that region (children don't send) | 3462 | // Note: This won't send data *to* other clients in that region (children don't send) |
3463 | if (m_teleportFlags <= 0) | ||
3464 | { | ||
3465 | ILandChannel landch = m_scene.LandChannel; | ||
3466 | if (landch != null) | ||
3467 | { | ||
3468 | landch.sendClientInitialLandInfo(ControllingClient); | ||
3469 | } | ||
3470 | } | ||
3467 | SendOtherAgentsAvatarDataToMe(); | 3471 | SendOtherAgentsAvatarDataToMe(); |
3468 | SendOtherAgentsAppearanceToMe(); | 3472 | SendOtherAgentsAppearanceToMe(); |
3469 | 3473 | ||
@@ -3586,7 +3590,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3586 | public void SendAvatarDataToAgent(ScenePresence avatar) | 3590 | public void SendAvatarDataToAgent(ScenePresence avatar) |
3587 | { | 3591 | { |
3588 | //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); | 3592 | //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); |
3589 | if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID) | 3593 | if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200) |
3590 | return; | 3594 | return; |
3591 | avatar.ControllingClient.SendAvatarDataImmediate(this); | 3595 | avatar.ControllingClient.SendAvatarDataImmediate(this); |
3592 | Animator.SendAnimPackToClient(avatar.ControllingClient); | 3596 | Animator.SendAnimPackToClient(avatar.ControllingClient); |
@@ -3653,7 +3657,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3653 | { | 3657 | { |
3654 | // m_log.DebugFormat( | 3658 | // m_log.DebugFormat( |
3655 | // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); | 3659 | // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); |
3656 | if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID) | 3660 | if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200) |
3657 | return; | 3661 | return; |
3658 | avatar.ControllingClient.SendAppearance( | 3662 | avatar.ControllingClient.SendAppearance( |
3659 | UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); | 3663 | UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); |
@@ -3866,14 +3870,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
3866 | /// </summary> | 3870 | /// </summary> |
3867 | protected bool CrossToNewRegion() | 3871 | protected bool CrossToNewRegion() |
3868 | { | 3872 | { |
3873 | bool result = false; | ||
3874 | parcelRegionCross(false); | ||
3869 | try | 3875 | try |
3870 | { | 3876 | { |
3871 | return m_scene.CrossAgentToNewRegion(this, Flying); | 3877 | result = m_scene.CrossAgentToNewRegion(this, Flying); |
3872 | } | 3878 | } |
3873 | catch | 3879 | catch |
3874 | { | 3880 | { |
3875 | return m_scene.CrossAgentToNewRegion(this, false); | 3881 | result = m_scene.CrossAgentToNewRegion(this, false); |
3876 | } | 3882 | } |
3883 | if(!result) | ||
3884 | parcelRegionCross(true); | ||
3885 | |||
3886 | return result; | ||
3887 | |||
3877 | } | 3888 | } |
3878 | 3889 | ||
3879 | public void Reset() | 3890 | public void Reset() |
@@ -3947,6 +3958,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3947 | /// </summary> | 3958 | /// </summary> |
3948 | public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) | 3959 | public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) |
3949 | { | 3960 | { |
3961 | int oldgodlevel = GodLevel; | ||
3962 | |||
3950 | if (godStatus) | 3963 | if (godStatus) |
3951 | { | 3964 | { |
3952 | // For now, assign god level 200 to anyone | 3965 | // For now, assign god level 200 to anyone |
@@ -3967,6 +3980,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3967 | } | 3980 | } |
3968 | 3981 | ||
3969 | ControllingClient.SendAdminResponse(token, (uint)GodLevel); | 3982 | ControllingClient.SendAdminResponse(token, (uint)GodLevel); |
3983 | |||
3984 | if(oldgodlevel != GodLevel) | ||
3985 | parcelGodCheck(m_currentParcelUUID, GodLevel >= 200); | ||
3970 | } | 3986 | } |
3971 | 3987 | ||
3972 | #region Child Agent Updates | 3988 | #region Child Agent Updates |
@@ -5377,7 +5393,221 @@ namespace OpenSim.Region.Framework.Scenes | |||
5377 | 5393 | ||
5378 | } | 5394 | } |
5379 | 5395 | ||
5380 | private void ParcelCrossCheck(UUID currentParcelUUID,UUID previusParcelUUID, | 5396 | private void parcelGodCheck(UUID currentParcelID, bool isGod) |
5397 | { | ||
5398 | List<ScenePresence> allpresences = null; | ||
5399 | |||
5400 | |||
5401 | allpresences = m_scene.GetScenePresences(); | ||
5402 | |||
5403 | if (isGod) | ||
5404 | { | ||
5405 | List<ScenePresence> viewsToSendme = new List<ScenePresence>(); | ||
5406 | |||
5407 | foreach (ScenePresence p in allpresences) | ||
5408 | { | ||
5409 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5410 | continue; | ||
5411 | |||
5412 | if (p.ParcelHideThisAvatar && p.currentParcelUUID != currentParcelID) | ||
5413 | { | ||
5414 | viewsToSendme.Add(p); // i see them | ||
5415 | } | ||
5416 | } | ||
5417 | |||
5418 | if (viewsToSendme.Count > 0) | ||
5419 | { | ||
5420 | foreach (ScenePresence p in viewsToSendme) | ||
5421 | { | ||
5422 | if (p.IsChildAgent) | ||
5423 | continue; | ||
5424 | m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); | ||
5425 | ControllingClient.SendAvatarDataImmediate(p); | ||
5426 | p.SendAppearanceToAgent(this); | ||
5427 | p.SendAttachmentsToClient(ControllingClient); | ||
5428 | if (p.Animator != null) | ||
5429 | p.Animator.SendAnimPackToClient(ControllingClient); | ||
5430 | } | ||
5431 | } | ||
5432 | } | ||
5433 | else | ||
5434 | { | ||
5435 | List<ScenePresence> killsToSendme = new List<ScenePresence>(); | ||
5436 | |||
5437 | foreach (ScenePresence p in allpresences) | ||
5438 | { | ||
5439 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5440 | continue; | ||
5441 | |||
5442 | if (p.ParcelHideThisAvatar && p.currentParcelUUID != currentParcelID) | ||
5443 | { | ||
5444 | killsToSendme.Add(p); | ||
5445 | } | ||
5446 | } | ||
5447 | |||
5448 | if (killsToSendme.Count > 0) | ||
5449 | { | ||
5450 | foreach (ScenePresence p in killsToSendme) | ||
5451 | { | ||
5452 | m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); | ||
5453 | try { ControllingClient.SendKillObject(new List<uint> { p.LocalId }); } | ||
5454 | catch (NullReferenceException) { } | ||
5455 | } | ||
5456 | } | ||
5457 | } | ||
5458 | |||
5459 | } | ||
5460 | |||
5461 | private void ParcelLoginCheck(UUID currentParcelID) | ||
5462 | { | ||
5463 | List<ScenePresence> killsToSendto = new List<ScenePresence>(); | ||
5464 | List<ScenePresence> killsToSendme = new List<ScenePresence>(); | ||
5465 | List<ScenePresence> viewsToSendto = new List<ScenePresence>(); | ||
5466 | List<ScenePresence> viewsToSendme = new List<ScenePresence>(); | ||
5467 | List<ScenePresence> allpresences = null; | ||
5468 | |||
5469 | allpresences = m_scene.GetScenePresences(); | ||
5470 | |||
5471 | foreach (ScenePresence p in allpresences) | ||
5472 | { | ||
5473 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5474 | continue; | ||
5475 | |||
5476 | if (currentParcelID != p.currentParcelUUID) | ||
5477 | { | ||
5478 | if (p.GodLevel < 200) | ||
5479 | killsToSendto.Add(p); | ||
5480 | if (GodLevel < 200 && p.ParcelHideThisAvatar) | ||
5481 | killsToSendme.Add(p); | ||
5482 | } | ||
5483 | else | ||
5484 | { | ||
5485 | viewsToSendto.Add(p); | ||
5486 | viewsToSendme.Add(p); | ||
5487 | } | ||
5488 | } | ||
5489 | allpresences.Clear(); | ||
5490 | |||
5491 | // send the things | ||
5492 | // kill main avatar object | ||
5493 | if (killsToSendto.Count > 0 && PresenceType != PresenceType.Npc) | ||
5494 | { | ||
5495 | foreach (ScenePresence p in killsToSendto) | ||
5496 | { | ||
5497 | m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); | ||
5498 | try { p.ControllingClient.SendKillObject(new List<uint> { LocalId }); } | ||
5499 | catch (NullReferenceException) { } | ||
5500 | } | ||
5501 | } | ||
5502 | |||
5503 | if (killsToSendme.Count > 0) | ||
5504 | { | ||
5505 | foreach (ScenePresence p in killsToSendme) | ||
5506 | { | ||
5507 | m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); | ||
5508 | try { ControllingClient.SendKillObject(new List<uint> { p.LocalId }); } | ||
5509 | catch (NullReferenceException) { } | ||
5510 | } | ||
5511 | } | ||
5512 | |||
5513 | if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc) | ||
5514 | { | ||
5515 | foreach (ScenePresence p in viewsToSendto) | ||
5516 | { | ||
5517 | m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname); | ||
5518 | p.ControllingClient.SendAvatarDataImmediate(this); | ||
5519 | SendAppearanceToAgent(p); | ||
5520 | SendAttachmentsToClient(p.ControllingClient); | ||
5521 | if (Animator != null) | ||
5522 | Animator.SendAnimPackToClient(p.ControllingClient); | ||
5523 | } | ||
5524 | } | ||
5525 | |||
5526 | if (viewsToSendme.Count > 0) | ||
5527 | { | ||
5528 | foreach (ScenePresence p in viewsToSendme) | ||
5529 | { | ||
5530 | m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); | ||
5531 | if (p.IsChildAgent) | ||
5532 | continue; | ||
5533 | ControllingClient.SendAvatarDataImmediate(p); | ||
5534 | p.SendAppearanceToAgent(this); | ||
5535 | p.SendAttachmentsToClient(ControllingClient); | ||
5536 | if (p.Animator != null) | ||
5537 | p.Animator.SendAnimPackToClient(ControllingClient); | ||
5538 | } | ||
5539 | } | ||
5540 | } | ||
5541 | |||
5542 | private void parcelRegionCross(bool abort) | ||
5543 | { | ||
5544 | if (!ParcelHideThisAvatar) | ||
5545 | return; | ||
5546 | |||
5547 | List<ScenePresence> allpresences = null; | ||
5548 | allpresences = m_scene.GetScenePresences(); | ||
5549 | |||
5550 | if (abort) | ||
5551 | { | ||
5552 | List<ScenePresence> viewsToSendme = new List<ScenePresence>(); | ||
5553 | |||
5554 | foreach (ScenePresence p in allpresences) | ||
5555 | { | ||
5556 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5557 | continue; | ||
5558 | |||
5559 | if (p.currentParcelUUID == m_currentParcelUUID) | ||
5560 | { | ||
5561 | viewsToSendme.Add(p); | ||
5562 | } | ||
5563 | } | ||
5564 | |||
5565 | if (viewsToSendme.Count > 0) | ||
5566 | { | ||
5567 | foreach (ScenePresence p in viewsToSendme) | ||
5568 | { | ||
5569 | if (p.IsChildAgent) | ||
5570 | continue; | ||
5571 | // m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); | ||
5572 | ControllingClient.SendAvatarDataImmediate(p); | ||
5573 | p.SendAppearanceToAgent(this); | ||
5574 | p.SendAttachmentsToClient(ControllingClient); | ||
5575 | if (p.Animator != null) | ||
5576 | p.Animator.SendAnimPackToClient(ControllingClient); | ||
5577 | } | ||
5578 | } | ||
5579 | } | ||
5580 | else | ||
5581 | { | ||
5582 | if (GodLevel >= 200) | ||
5583 | return; | ||
5584 | |||
5585 | List<ScenePresence> killsToSendme = new List<ScenePresence>(); | ||
5586 | foreach (ScenePresence p in allpresences) | ||
5587 | { | ||
5588 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5589 | continue; | ||
5590 | |||
5591 | if (p.currentParcelUUID == m_currentParcelUUID) | ||
5592 | { | ||
5593 | killsToSendme.Add(p); | ||
5594 | } | ||
5595 | } | ||
5596 | |||
5597 | if (killsToSendme.Count > 0) | ||
5598 | { | ||
5599 | foreach (ScenePresence p in killsToSendme) | ||
5600 | { | ||
5601 | m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); | ||
5602 | try { ControllingClient.SendKillObject(new List<uint> { p.LocalId }); } | ||
5603 | catch (NullReferenceException) { } | ||
5604 | } | ||
5605 | } | ||
5606 | } | ||
5607 | } | ||
5608 | |||
5609 | |||
5610 | private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID, | ||
5381 | bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check) | 5611 | bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check) |
5382 | { | 5612 | { |
5383 | List<ScenePresence> killsToSendto = new List<ScenePresence>(); | 5613 | List<ScenePresence> killsToSendto = new List<ScenePresence>(); |
@@ -5391,6 +5621,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5391 | 5621 | ||
5392 | if (check) | 5622 | if (check) |
5393 | { | 5623 | { |
5624 | // check is relative to current parcel only | ||
5394 | if (currentParcelUUID == null || oldhide == currentParcelHide) | 5625 | if (currentParcelUUID == null || oldhide == currentParcelHide) |
5395 | return; | 5626 | return; |
5396 | 5627 | ||
@@ -5404,8 +5635,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
5404 | continue; | 5635 | continue; |
5405 | 5636 | ||
5406 | // those on not on parcel see me | 5637 | // those on not on parcel see me |
5407 | if (currentParcelUUID != p.currentParcelUUID) | 5638 | if (currentParcelID != p.currentParcelUUID) |
5408 | { | 5639 | { |
5409 | viewsToSendto.Add(p); // they see me | 5640 | viewsToSendto.Add(p); // they see me |
5410 | } | 5641 | } |
5411 | } | 5642 | } |
@@ -5419,14 +5650,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
5419 | continue; | 5650 | continue; |
5420 | 5651 | ||
5421 | // those not on parcel dont see me | 5652 | // those not on parcel dont see me |
5422 | if (currentParcelUUID != p.currentParcelUUID) | 5653 | if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200) |
5423 | { | 5654 | { |
5424 | killsToSendto.Add(p); // they dont see me | 5655 | killsToSendto.Add(p); // they dont see me |
5425 | } | 5656 | } |
5426 | } | 5657 | } |
5427 | } // where public end | 5658 | } // where public end |
5428 | 5659 | ||
5429 | |||
5430 | allpresences.Clear(); | 5660 | allpresences.Clear(); |
5431 | } | 5661 | } |
5432 | else | 5662 | else |
@@ -5436,7 +5666,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5436 | // now on a private parcel | 5666 | // now on a private parcel |
5437 | allpresences = m_scene.GetScenePresences(); | 5667 | allpresences = m_scene.GetScenePresences(); |
5438 | 5668 | ||
5439 | if (previusParcelHide && previusParcelUUID != UUID.Zero) | 5669 | if (previusParcelHide && previusParcelID != UUID.Zero) |
5440 | { | 5670 | { |
5441 | foreach (ScenePresence p in allpresences) | 5671 | foreach (ScenePresence p in allpresences) |
5442 | { | 5672 | { |
@@ -5444,13 +5674,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
5444 | continue; | 5674 | continue; |
5445 | 5675 | ||
5446 | // only those on previus parcel need receive kills | 5676 | // only those on previus parcel need receive kills |
5447 | if (previusParcelUUID == p.currentParcelUUID) | 5677 | if (previusParcelID == p.currentParcelUUID) |
5448 | { | 5678 | { |
5449 | killsToSendto.Add(p); // they dont see me | 5679 | if(p.GodLevel < 200) |
5450 | killsToSendme.Add(p); // i dont see them | 5680 | killsToSendto.Add(p); // they dont see me |
5681 | if(GodLevel < 200) | ||
5682 | killsToSendme.Add(p); // i dont see them | ||
5451 | } | 5683 | } |
5452 | // only those on new parcel need see | 5684 | // only those on new parcel need see |
5453 | if (currentParcelUUID == p.currentParcelUUID) | 5685 | if (currentParcelID == p.currentParcelUUID) |
5454 | { | 5686 | { |
5455 | viewsToSendto.Add(p); // they see me | 5687 | viewsToSendto.Add(p); // they see me |
5456 | viewsToSendme.Add(p); // i see them | 5688 | viewsToSendme.Add(p); // i see them |
@@ -5468,7 +5700,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5468 | continue; | 5700 | continue; |
5469 | 5701 | ||
5470 | // those not on new parcel dont see me | 5702 | // those not on new parcel dont see me |
5471 | if (currentParcelUUID != p.currentParcelUUID) | 5703 | if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200) |
5472 | { | 5704 | { |
5473 | killsToSendto.Add(p); // they dont see me | 5705 | killsToSendto.Add(p); // they dont see me |
5474 | } | 5706 | } |
@@ -5484,7 +5716,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5484 | else | 5716 | else |
5485 | { | 5717 | { |
5486 | // now on public parcel | 5718 | // now on public parcel |
5487 | if (previusParcelHide && previusParcelUUID != UUID.Zero) | 5719 | if (previusParcelHide && previusParcelID != UUID.Zero) |
5488 | { | 5720 | { |
5489 | // was on private area | 5721 | // was on private area |
5490 | allpresences = m_scene.GetScenePresences(); | 5722 | allpresences = m_scene.GetScenePresences(); |
@@ -5494,7 +5726,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
5494 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | 5726 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) |
5495 | continue; | 5727 | continue; |
5496 | // only those old parcel need receive kills | 5728 | // only those old parcel need receive kills |
5497 | if (previusParcelUUID == p.currentParcelUUID) | 5729 | if (previusParcelID == p.currentParcelUUID && GodLevel < 200) |
5498 | { | 5730 | { |
5499 | killsToSendme.Add(p); // i dont see them | 5731 | killsToSendme.Add(p); // i dont see them |
5500 | } | 5732 | } |
@@ -5511,29 +5743,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
5511 | 5743 | ||
5512 | // send the things | 5744 | // send the things |
5513 | // kill main avatar object | 5745 | // kill main avatar object |
5514 | if (killsToSendto.Count > 0) | 5746 | if (killsToSendto.Count > 0 && PresenceType != PresenceType.Npc) |
5515 | { | 5747 | { |
5516 | foreach (ScenePresence p in killsToSendto) | 5748 | foreach (ScenePresence p in killsToSendto) |
5517 | { | 5749 | { |
5750 | m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); | ||
5518 | try { p.ControllingClient.SendKillObject(new List<uint> { LocalId }); } | 5751 | try { p.ControllingClient.SendKillObject(new List<uint> { LocalId }); } |
5519 | catch (NullReferenceException) { } | 5752 | catch (NullReferenceException) { } |
5520 | } | 5753 | } |
5521 | } | 5754 | } |
5522 | 5755 | ||
5523 | if (killsToSendme.Count > 0 && PresenceType != PresenceType.Npc) | 5756 | if (killsToSendme.Count > 0 ) |
5524 | { | 5757 | { |
5525 | foreach (ScenePresence p in killsToSendme) | 5758 | foreach (ScenePresence p in killsToSendme) |
5526 | { | 5759 | { |
5760 | m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); | ||
5527 | try {ControllingClient.SendKillObject(new List<uint> { p.LocalId }); } | 5761 | try {ControllingClient.SendKillObject(new List<uint> { p.LocalId }); } |
5528 | catch (NullReferenceException) { } | 5762 | catch (NullReferenceException) { } |
5529 | } | 5763 | } |
5530 | } | 5764 | } |
5531 | 5765 | ||
5532 | if (viewsToSendto.Count > 0) | 5766 | if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc) |
5533 | { | 5767 | { |
5534 | foreach (ScenePresence p in viewsToSendto) | 5768 | foreach (ScenePresence p in viewsToSendto) |
5535 | { | 5769 | { |
5536 | p.ControllingClient.SendAvatarDataImmediate(this); | 5770 | p.ControllingClient.SendAvatarDataImmediate(this); |
5771 | // m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname); | ||
5537 | SendAppearanceToAgent(p); | 5772 | SendAppearanceToAgent(p); |
5538 | SendAttachmentsToClient(p.ControllingClient); | 5773 | SendAttachmentsToClient(p.ControllingClient); |
5539 | if (Animator != null) | 5774 | if (Animator != null) |
@@ -5541,10 +5776,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
5541 | } | 5776 | } |
5542 | } | 5777 | } |
5543 | 5778 | ||
5544 | if (viewsToSendme.Count > 0 && PresenceType != PresenceType.Npc) | 5779 | if (viewsToSendme.Count > 0 ) |
5545 | { | 5780 | { |
5546 | foreach (ScenePresence p in viewsToSendme) | 5781 | foreach (ScenePresence p in viewsToSendme) |
5547 | { | 5782 | { |
5783 | if (p.IsChildAgent) | ||
5784 | continue; | ||
5785 | // m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); | ||
5548 | ControllingClient.SendAvatarDataImmediate(p); | 5786 | ControllingClient.SendAvatarDataImmediate(p); |
5549 | p.SendAppearanceToAgent(this); | 5787 | p.SendAppearanceToAgent(this); |
5550 | p.SendAttachmentsToClient(ControllingClient); | 5788 | p.SendAttachmentsToClient(ControllingClient); |