From 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb Mon Sep 17 00:00:00 2001
From: onefang
Date: Sun, 19 May 2019 21:24:15 +1000
Subject: Dump OpenSim 0.9.0.1 into it's own branch.
---
.../Framework/Scenes/Scene.PacketHandlers.cs | 291 ++++++++++++++-------
1 file changed, 200 insertions(+), 91 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs')
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 8ebcd92..84bad25 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Scenes
///
///
///
- protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
+ public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
UUID fromID, UUID targetID, bool fromAgent, bool broadcast)
{
OSChatMessage args = new OSChatMessage();
@@ -60,6 +60,7 @@ namespace OpenSim.Region.Framework.Scenes
args.Position = fromPos;
args.SenderUUID = fromID;
args.Scene = this;
+ args.Destination = targetID;
if (fromAgent)
{
@@ -74,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes
}
args.From = fromName;
- args.TargetUUID = targetID;
+ //args.
// m_log.DebugFormat(
// "[SCENE]: Sending message {0} on channel {1}, type {2} from {3}, broadcast {4}",
@@ -129,19 +130,6 @@ namespace OpenSim.Region.Framework.Scenes
{
SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true);
}
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public void SimChatToAgent(UUID targetID, byte[] message, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
- {
- SimChat(message, ChatTypeEnum.Say, 0, fromPos, fromName, fromID, targetID, fromAgent, false);
- }
///
///
@@ -176,29 +164,34 @@ namespace OpenSim.Region.Framework.Scenes
///
///
///
- public void SelectPrim(uint primLocalID, IClientAPI remoteClient)
+ public void SelectPrim(List primIDs, IClientAPI remoteClient)
{
- SceneObjectPart part = GetSceneObjectPart(primLocalID);
+ foreach(uint primLocalID in primIDs)
+ {
+ SceneObjectPart part = GetSceneObjectPart(primLocalID);
- if (null == part)
- return;
+ if (part == null)
+ continue;
- if (part.IsRoot)
- {
SceneObjectGroup sog = part.ParentGroup;
- sog.SendPropertiesToClient(remoteClient);
- sog.IsSelected = true;
+ if (sog == null)
+ continue;
+
+ // waste of time because properties do not send prim flags as they should
+ // if a friend got or lost edit rights after login, a full update is needed
+ if(sog.OwnerID != remoteClient.AgentId)
+ part.SendFullUpdate(remoteClient);
// A prim is only tainted if it's allowed to be edited by the person clicking it.
- if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)
- || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId))
+ if (Permissions.CanChangeSelectedState(part, (ScenePresence)remoteClient.SceneAgent))
{
- EventManager.TriggerParcelPrimCountTainted();
+ bool oldsel = part.IsSelected;
+ part.IsSelected = true;
+ if(!oldsel)
+ EventManager.TriggerParcelPrimCountTainted();
}
- }
- else
- {
- part.SendPropertiesToClient(remoteClient);
+
+ part.SendPropertiesToClient(remoteClient);
}
}
@@ -220,13 +213,13 @@ namespace OpenSim.Region.Framework.Scenes
if (groupID != UUID.Zero)
{
GroupMembershipData gmd = m_groupsModule.GetMembershipData(groupID, remoteClient.AgentId);
-
+
if (gmd == null)
{
// m_log.WarnFormat(
// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group",
// remoteClient.Name, GroupID, objectLocalID);
-
+
return;
}
}
@@ -237,6 +230,7 @@ namespace OpenSim.Region.Framework.Scenes
if (so.OwnerID == remoteClient.AgentId)
{
so.SetGroup(groupID, remoteClient);
+ EventManager.TriggerParcelPrimCountTainted();
}
}
}
@@ -251,40 +245,29 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart part = GetSceneObjectPart(primLocalID);
if (part == null)
return;
-
- // A deselect packet contains all the local prims being deselected. However, since selection is still
- // group based we only want the root prim to trigger a full update - otherwise on objects with many prims
- // we end up sending many duplicate ObjectUpdates
- if (part.ParentGroup.RootPart.LocalId != part.LocalId)
- return;
+
+ bool oldgprSelect = part.ParentGroup.IsSelected;
// This is wrong, wrong, wrong. Selection should not be
// handled by group, but by prim. Legacy cruft.
// TODO: Make selection flagging per prim!
//
- part.ParentGroup.IsSelected = false;
-
- part.ParentGroup.ScheduleGroupForFullUpdate();
-
- // If it's not an attachment, and we are allowed to move it,
- // then we might have done so. If we moved across a parcel
- // boundary, we will need to recount prims on the parcels.
- // For attachments, that makes no sense.
- //
- if (!part.ParentGroup.IsAttachment)
+ if (Permissions.CanChangeSelectedState(part, (ScenePresence)remoteClient.SceneAgent))
{
- if (Permissions.CanEditObject(
- part.UUID, remoteClient.AgentId)
- || Permissions.CanMoveObject(
- part.UUID, remoteClient.AgentId))
+ part.IsSelected = false;
+ if (!part.ParentGroup.IsAttachment && oldgprSelect != part.ParentGroup.IsSelected)
EventManager.TriggerParcelPrimCountTainted();
+
+ // restore targetOmega
+ if (part.AngularVelocity != Vector3.Zero)
+ part.ScheduleTerseUpdate();
}
}
- public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount,
+ public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount,
int transactiontype, string description)
{
- EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount,
+ EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount,
transactiontype, description);
EventManager.TriggerMoneyTransfer(this, args);
@@ -293,8 +276,8 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned,
bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated)
{
- EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned,
- removeContribution, parcelLocalID, parcelArea,
+ EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned,
+ removeContribution, parcelLocalID, parcelArea,
parcelPrice, authenticated);
// First, allow all validators a stab at it
@@ -307,7 +290,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List surfaceArgs)
{
SceneObjectPart part = GetSceneObjectPart(localID);
-
+
if (part == null)
return;
@@ -320,19 +303,17 @@ namespace OpenSim.Region.Framework.Scenes
// Currently only grab/touch for the single prim
// the client handles rez correctly
obj.ObjectGrabHandler(localID, offsetPos, remoteClient);
-
+
// If the touched prim handles touches, deliver it
- // If not, deliver to root prim
if ((part.ScriptEvents & scriptEvents.touch_start) != 0)
- EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
+ EventManager.TriggerObjectGrab(part.LocalId, 0, offsetPos, remoteClient, surfaceArg);
// Deliver to the root prim if the touched prim doesn't handle touches
- // or if we're meant to pass on touches anyway. Don't send to root prim
- // if prim touched is the root prim as we just did it
+ // or if we're meant to pass on touches anyway.
if (((part.ScriptEvents & scriptEvents.touch_start) == 0) ||
- (part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
+ (part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
{
- EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
+ EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, offsetPos, remoteClient, surfaceArg);
}
}
@@ -343,23 +324,37 @@ namespace OpenSim.Region.Framework.Scenes
if (part == null)
return;
- SceneObjectGroup obj = part.ParentGroup;
+ SceneObjectGroup group = part.ParentGroup;
+ if(group == null || group.IsDeleted)
+ return;
+
+ if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.)
+ {
+ group.GrabMovement(objectID, offset, pos, remoteClient);
+ }
+
+ // This is outside the above permissions condition
+ // so that if the object is locked the client moving the object
+ // get's it's position on the simulator even if it was the same as before
+ // This keeps the moving user's client in sync with the rest of the world.
+ group.SendGroupTerseUpdate();
SurfaceTouchEventArgs surfaceArg = null;
if (surfaceArgs != null && surfaceArgs.Count > 0)
surfaceArg = surfaceArgs[0];
+ Vector3 grabOffset = pos - part.AbsolutePosition;
// If the touched prim handles touches, deliver it
- // If not, deliver to root prim
if ((part.ScriptEvents & scriptEvents.touch) != 0)
- EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
+// EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
+ EventManager.TriggerObjectGrabbing(part.LocalId, 0, grabOffset, remoteClient, surfaceArg);
// Deliver to the root prim if the touched prim doesn't handle touches
- // or if we're meant to pass on touches anyway. Don't send to root prim
- // if prim touched is the root prim as we just did it
+ // or if we're meant to pass on touches anyway.
if (((part.ScriptEvents & scriptEvents.touch) == 0) ||
- (part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
+ (part.PassTouches && (part.LocalId != group.RootPart.LocalId)))
{
- EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
+// EventManager.TriggerObjectGrabbing(group.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
+ EventManager.TriggerObjectGrabbing(group.RootPart.LocalId, part.LocalId, grabOffset, remoteClient, surfaceArg);
}
}
@@ -369,18 +364,77 @@ namespace OpenSim.Region.Framework.Scenes
if (part == null)
return;
- SceneObjectGroup obj = part.ParentGroup;
+ SceneObjectGroup grp = part.ParentGroup;
SurfaceTouchEventArgs surfaceArg = null;
if (surfaceArgs != null && surfaceArgs.Count > 0)
surfaceArg = surfaceArgs[0];
// If the touched prim handles touches, deliver it
- // If not, deliver to root prim
if ((part.ScriptEvents & scriptEvents.touch_end) != 0)
EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient, surfaceArg);
- else
- EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg);
+ // if not or PassTouchs, send it also to root.
+ if (((part.ScriptEvents & scriptEvents.touch_end) == 0) ||
+ (part.PassTouches && (part.LocalId != grp.RootPart.LocalId)))
+ {
+ EventManager.TriggerObjectDeGrab(grp.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg);
+ }
+ }
+
+ ///
+ /// Start spinning the given object
+ ///
+ ///
+ ///
+ ///
+ public virtual void ProcessSpinStart(UUID objectID, IClientAPI remoteClient)
+ {
+ SceneObjectGroup group = GetGroupByPrim(objectID);
+ if (group != null)
+ {
+ if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.)
+ {
+ group.SpinStart(remoteClient);
+ }
+ }
+ }
+
+ ///
+ /// Spin the given object
+ ///
+ ///
+ ///
+ ///
+ public virtual void ProcessSpinObject(UUID objectID, Quaternion rotation, IClientAPI remoteClient)
+ {
+ SceneObjectGroup group = GetGroupByPrim(objectID);
+ if (group != null)
+ {
+ if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.)
+ {
+ group.SpinMovement(rotation, remoteClient);
+ }
+ // This is outside the above permissions condition
+ // so that if the object is locked the client moving the object
+ // get's it's position on the simulator even if it was the same as before
+ // This keeps the moving user's client in sync with the rest of the world.
+ group.SendGroupTerseUpdate();
+ }
+ }
+
+ public virtual void ProcessSpinObjectStop(UUID objectID, IClientAPI remoteClient)
+ {
+/* no op for now
+ SceneObjectGroup group = GetGroupByPrim(objectID);
+ if (group != null)
+ {
+ if (Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))// && PermissionsMngr.)
+ {
+// group.SpinMovement(rotation, remoteClient);
+ }
+ group.SendGroupTerseUpdate();
+ }
+*/
}
public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID,
@@ -439,6 +493,20 @@ namespace OpenSim.Region.Framework.Scenes
return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10;
}
+ private class DescendentsRequestData
+ {
+ public IClientAPI RemoteClient;
+ public UUID FolderID;
+ public UUID OwnerID;
+ public bool FetchFolders;
+ public bool FetchItems;
+ public int SortOrder;
+ }
+
+ private Queue m_descendentsRequestQueue = new Queue();
+ private Object m_descendentsRequestLock = new Object();
+ private bool m_descendentsRequestProcessing = false;
+
///
/// Tell the client about the various child items and folders contained in the requested folder.
///
@@ -475,11 +543,31 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- // We're going to send the reply async, because there may be
- // an enormous quantity of packets -- basically the entire inventory!
- // We don't want to block the client thread while all that is happening.
- SendInventoryDelegate d = SendInventoryAsync;
- d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d);
+ lock (m_descendentsRequestLock)
+ {
+ if (!m_descendentsRequestProcessing)
+ {
+ m_descendentsRequestProcessing = true;
+
+ // We're going to send the reply async, because there may be
+ // an enormous quantity of packets -- basically the entire inventory!
+ // We don't want to block the client thread while all that is happening.
+ SendInventoryDelegate d = SendInventoryAsync;
+ d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d);
+
+ return;
+ }
+
+ DescendentsRequestData req = new DescendentsRequestData();
+ req.RemoteClient = remoteClient;
+ req.FolderID = folderID;
+ req.OwnerID = ownerID;
+ req.FetchFolders = fetchFolders;
+ req.FetchItems = fetchItems;
+ req.SortOrder = sortOrder;
+
+ m_descendentsRequestQueue.Enqueue(req);
+ }
}
delegate void SendInventoryDelegate(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder);
@@ -494,16 +582,32 @@ namespace OpenSim.Region.Framework.Scenes
{
m_log.Error(
string.Format(
- "[AGENT INVENTORY]: Error in SendInventoryAsync() for {0} with folder ID {1}. Exception ", e));
+ "[AGENT INVENTORY]: Error in SendInventoryAsync() for {0} with folder ID {1}. Exception ", e, folderID));
}
+ Thread.Sleep(20);
}
void SendInventoryComplete(IAsyncResult iar)
{
SendInventoryDelegate d = (SendInventoryDelegate)iar.AsyncState;
d.EndInvoke(iar);
+
+ lock (m_descendentsRequestLock)
+ {
+ if (m_descendentsRequestQueue.Count > 0)
+ {
+ DescendentsRequestData req = m_descendentsRequestQueue.Dequeue();
+
+ d = SendInventoryAsync;
+ d.BeginInvoke(req.RemoteClient, req.FolderID, req.OwnerID, req.FetchFolders, req.FetchItems, req.SortOrder, SendInventoryComplete, d);
+
+ return;
+ }
+
+ m_descendentsRequestProcessing = false;
+ }
}
-
+
///
/// Handle an inventory folder creation request from the client.
///
@@ -543,8 +647,7 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat(
// "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId);
- InventoryFolderBase folder = new InventoryFolderBase(folderID, remoteClient.AgentId);
- folder = InventoryService.GetFolder(folder);
+ InventoryFolderBase folder = InventoryService.GetFolder(remoteClient.AgentId, folderID);
if (folder != null)
{
folder.Name = name;
@@ -558,11 +661,10 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
-
+
public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID)
{
- InventoryFolderBase folder = new InventoryFolderBase(folderID, remoteClient.AgentId);
- folder = InventoryService.GetFolder(folder);
+ InventoryFolderBase folder = InventoryService.GetFolder(remoteClient.AgentId, folderID);
if (folder != null)
{
folder.ParentID = parentID;
@@ -601,10 +703,17 @@ namespace OpenSim.Region.Framework.Scenes
{
InventoryFolderBase folder = new InventoryFolderBase(folderID, userID);
- if (InventoryService.PurgeFolder(folder))
- m_log.DebugFormat("[AGENT INVENTORY]: folder {0} purged successfully", folderID);
- else
- m_log.WarnFormat("[AGENT INVENTORY]: could not purge folder {0}", folderID);
+ try
+ {
+ if (InventoryService.PurgeFolder(folder))
+ m_log.DebugFormat("[AGENT INVENTORY]: folder {0} purged successfully", folderID);
+ else
+ m_log.WarnFormat("[AGENT INVENTORY]: could not purge folder {0}", folderID);
+ }
+ catch (Exception e)
+ {
+ m_log.WarnFormat("[AGENT INVENTORY]: Exception on async purge folder for user {0}: {1}", userID, e.Message);
+ }
}
private void PurgeFolderCompleted(IAsyncResult iar)
--
cgit v1.1