limit max number of attachments to 38. All can be on same point

0.9.1.1
UbitUmarov 2019-11-13 18:44:58 +00:00
parent 2828aa3e9b
commit 5d2ffdc35b
7 changed files with 101 additions and 84 deletions

View File

@ -164,7 +164,6 @@ namespace OpenSim.Region.ClientStack.Linden
m_features["BakesOnMeshEnabled"] = true;
m_features["PhysicsMaterialsEnabled"] = true;
OSDMap typesMap = new OSDMap();
typesMap["convex"] = true;
typesMap["none"] = true;
@ -175,10 +174,14 @@ namespace OpenSim.Region.ClientStack.Linden
m_features["LSLSyntaxId"] = OSD.FromUUID(m_scriptSyntaxID);
OSDMap meshAnim = new OSDMap();
meshAnim["AnimatedObjectMaxTris"] = OSD.FromInteger(10000);
meshAnim["AnimatedObjectMaxTris"] = OSD.FromInteger(150000);
meshAnim["MaxAgentAnimatedObjectAttachments"] = OSD.FromInteger(2);
m_features["AnimatedObjects"] = meshAnim;
m_features["MaxAgentAttachments"] = OSD.FromInteger(Constants.MaxAgentAttachments);
m_features["MaxAgentGroupsBasic"] = OSD.FromInteger(Constants.MaxAgentGroups);
m_features["MaxAgentGroupsPremium"] = OSD.FromInteger(Constants.MaxAgentGroups);
// Extra information for viewers that want to use it
// TODO: Take these out of here into their respective modules, like map-server-url
OSDMap extrasMap;

View File

@ -59,6 +59,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
private Scene m_scene;
private IRegionConsole m_regionConsole;
private IInventoryAccessModule m_invAccessModule;
private bool m_wearReplacesAllOption = true;
/// <summary>
/// Are attachments enabled?
@ -74,6 +75,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (config != null)
{
Enabled = config.GetBoolean("Enabled", true);
m_wearReplacesAllOption = config.GetBoolean("WearReplacesAll", true);
}
else
{
@ -101,9 +103,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public void RemoveRegion(Scene scene)
{
m_scene.UnregisterModuleInterface<IAttachmentsModule>(this);
if (!Enabled)
return;
if (Enabled)
m_scene.UnregisterModuleInterface<IAttachmentsModule>(this);
m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
}
@ -225,8 +228,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ConsoleDisplayList ct = new ConsoleDisplayList();
List<SceneObjectGroup> attachmentObjects = sp.GetAttachments();
foreach (SceneObjectGroup attachmentObject in attachmentObjects)
for (int i = 0; i < attachmentObjects.Count; ++i)
{
SceneObjectGroup attachmentObject = attachmentObjects[i];
ct.Indent = 2;
ct.AddRow("Attachment Name", attachmentObject.Name);
ct.AddRow("Local ID", attachmentObject.LocalId);
@ -308,13 +312,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
List<SceneObjectGroup> attachments = sp.GetAttachments();
if (attachments.Count > 0)
{
ad.AttachmentObjects = new List<ISceneObject>();
ad.AttachmentObjectStates = new List<string>();
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
ad.AttachmentObjects = new List<ISceneObject>(attachments.Count);
ad.AttachmentObjectStates = new List<string>(attachments.Count);
sp.InTransitScriptStates.Clear();
foreach (SceneObjectGroup sog in attachments)
for (int indx = 0; indx < attachments.Count; ++indx)
{
SceneObjectGroup sog = attachments[indx];
// We need to make a copy and pass that copy
// because of transfers withn the same sim
ISceneObject clone = sog.CloneForNewScene();
@ -343,17 +347,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
sp.ClearAttachments();
int i = 0;
foreach (ISceneObject so in ad.AttachmentObjects)
for (int indx = 0; indx < ad.AttachmentObjects.Count; ++indx)
{
((SceneObjectGroup)so).LocalId = 0;
((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
SceneObjectGroup sog = (SceneObjectGroup)ad.AttachmentObjects[indx];
sog.LocalId = 0;
sog.RootPart.ClearUpdateSchedule();
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}",
// ad.AttachmentObjectStates[i].Length, so.Name, sp.Name, m_scene.Name);
// ad.AttachmentObjectStates[i].Length, sog.Name, sp.Name, m_scene.Name);
so.SetState(ad.AttachmentObjectStates[i++], m_scene);
m_scene.IncomingCreateObject(Vector3.Zero, so);
sog.SetState(ad.AttachmentObjectStates[i++], m_scene);
m_scene.IncomingCreateObject(Vector3.Zero, sog);
}
}
}
@ -363,14 +368,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (!Enabled)
return;
if (null == sp.Appearance)
if (sp.Appearance == null)
{
m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
return;
}
if (sp.GetAttachments().Count > 0)
if (sp.GetAttachmentsCount() > 0)
{
if (DebugLevel > 0)
m_log.DebugFormat(
@ -420,27 +424,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// Let's get all items at once, so they get cached
UUID[] items = new UUID[attachments.Count];
int i = 0;
foreach (AvatarAttachment attach in attachments)
items[i++] = attach.ItemID;
for (int i = 0; i < attachments.Count; ++i)
items[i] = attachments[i].ItemID;
m_scene.InventoryService.GetMultipleItems(sp.UUID, items);
foreach (AvatarAttachment attach in attachments)
for (int indx = 0; indx < attachments.Count; ++indx)
{
AvatarAttachment attach = attachments[indx];
uint attachmentPt = (uint)attach.AttachPoint;
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}",
// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName);
// For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
// But they're not used anyway, the item is being looked up for now, so let's proceed.
//if (UUID.Zero == assetID)
//{
// m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID);
// continue;
//}
try
{
string xmlData;
@ -482,24 +479,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (attachments.Count <= 0)
return;
Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>();
if (sp.PresenceType != PresenceType.Npc)
{
foreach (SceneObjectGroup so in attachments)
{
// Scripts MUST be snapshotted before the object is
// removed from the scene because doing otherwise will
// clobber the run flag
// This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
// scripts performing attachment operations at the same time. Getting object states stops the scripts.
scriptStates[so] = PrepareScriptInstanceForSave(so, false);
}
lock (sp.AttachmentsSyncLock)
{
foreach (SceneObjectGroup so in attachments)
UpdateDetachedObject(sp, so, scriptStates[so]);
for (int i = 0; i < attachments.Count; ++i)
{
SceneObjectGroup sog = attachments[i];
UpdateDetachedObject(sp, sog, PrepareScriptInstanceForSave(sog, false));
}
sp.ClearAttachments();
}
}
@ -507,8 +495,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
lock (sp.AttachmentsSyncLock)
{
foreach (SceneObjectGroup so in attachments)
UpdateDetachedObject(sp, so, String.Empty);
for (int i = 0; i < attachments.Count; ++i)
UpdateDetachedObject(sp, attachments[i], String.Empty);
sp.ClearAttachments();
}
}
@ -524,9 +512,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
"[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
m_scene.RegionInfo.RegionName, sp.Name, silent);
foreach (SceneObjectGroup sop in sp.GetAttachments())
List<SceneObjectGroup> attachments = sp.GetAttachments();
for(int i = 0; i < attachments.Count; ++i)
{
sop.Scene.DeleteSceneObject(sop, silent);
SceneObjectGroup sog = attachments[i];
sog.Scene.DeleteSceneObject(sog, silent);
}
sp.ClearAttachments();
@ -612,42 +603,62 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
attachPos = Vector3.Zero;
}
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
if (attachments.Contains(group))
if(attachmentPt > (uint)AttachmentPoint.LastValid)
{
m_log.WarnFormat("[ATTACHMENTS MODULE]: Invalid attachment point {0} SP {1}", attachmentPt, sp.Name);
return false;
}
List<SceneObjectGroup> attachments = sp.GetAttachments();
List<SceneObjectGroup> toRemove = new List<SceneObjectGroup>(attachments.Count);
bool doRemCheck = !append;
for(int i = 0; i < attachments.Count; ++i)
{
SceneObjectGroup sog = attachments[i];
// duplications ?
if (group.UUID == sog.UUID)
{
// if (DebugLevel > 0)
// m_log.WarnFormat(
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
// group.Name, group.LocalId, sp.Name, attachmentPt);
return false;
}
if(doRemCheck)
{
if(sog.AttachmentPoint == attachmentPt)
{
toRemove.Add(sog);
if(!m_wearReplacesAllOption)
doRemCheck = false;
}
}
}
if(attachments.Count - toRemove.Count >= Constants.MaxAgentAttachments)
{
m_log.WarnFormat("[ATTACHMENTS MODULE]: Max attachments exceded {0}",sp.Name);
return false;
}
// If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
while (attachments.Count >= 5)
{
if (attachments[0].FromItemID != UUID.Zero)
DetachSingleAttachmentToInv(sp, attachments[0]);
attachments.RemoveAt(0);
}
group.DetachFromBackup();
group.AttachmentPoint = attachmentPt;
group.RootPart.AttachedPos = attachPos;
// If we're not appending, remove the rest as well
if (attachments.Count != 0 && !append)
lock (sp.AttachmentsSyncLock)
{
foreach (SceneObjectGroup g in attachments)
if (toRemove.Count > 0)
{
for (int i = 0; i< toRemove.Count; ++i)
{
SceneObjectGroup g = toRemove[i];
if (g.FromItemID != UUID.Zero)
DetachSingleAttachmentToInv(sp, g);
}
}
group.DetachFromBackup();
lock (sp.AttachmentsSyncLock)
{
group.AttachmentPoint = attachmentPt;
group.RootPart.AttachedPos = attachPos;
if (addToInventory && sp.PresenceType != PresenceType.Npc)
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
@ -668,7 +679,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// and not all scripts are loaded at this point
m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
}
return true;
}
@ -1255,10 +1265,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
objatt.HasGroupChanged = false;
bool tainted = false;
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
tainted = true;
Vector3 lastPos = objatt.RootPart.OffsetPosition;
Vector3 lastAttPos = objatt.RootPart.AttachedPos;
bool doneAttach = false;
// FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
// course of events. If not, then it's probably not worth trying to recover the situation
// since this is more likely to trigger further exceptions and confuse later debugging. If
@ -1273,21 +1283,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
objatt.ResetOwnerChangeFlag();
}
AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append);
doneAttach = AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
doneAttach = false;
}
if(!doneAttach)
{
// Make sure the object doesn't stick around and bail
sp.RemoveAttachment(objatt);
m_scene.DeleteSceneObject(objatt, false);
return null;
}
if (tainted)
if ((attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) ||
lastPos != objatt.RootPart.OffsetPosition ||
lastAttPos != objatt.RootPart.AttachedPos)
objatt.HasGroupChanged = true;
return objatt;

View File

@ -53,7 +53,6 @@ namespace OpenSim.Region.Framework.Interfaces
/// All add and remove attachment operations must synchronize on this for the lifetime of their operations.
/// </remarks>
Object AttachmentsSyncLock { get; }
int MaxNumberAttachments { get; }
int GetAttachmentsCount();
/// <summary>
/// The scene objects attached to this avatar.

View File

@ -78,8 +78,6 @@ namespace OpenSim.Region.Framework.Scenes
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public int MaxNumberAttachments { get; } = 38; // per viewers limit
// ~ScenePresence()
// {
// m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name);

View File

@ -228,6 +228,7 @@ namespace OpenSim.Region.OptionalModules.Materials
private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
{
features["MaxMaterialsPerTransaction"] = m_maxMaterialsPerTransaction;
features["RenderMaterialsCapability"] = OSD.FromReal(3);
}
/// <summary>

View File

@ -14531,7 +14531,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ret.Add(new LSL_Integer(0));
break;
case ScriptBaseClass.OBJECT_ATTACHED_SLOTS_AVAILABLE:
ret.Add(new LSL_Integer(38 - av.GetAttachmentsCount()));
ret.Add(new LSL_Integer(Constants.MaxAgentAttachments - av.GetAttachmentsCount()));
break;
case ScriptBaseClass.OBJECT_CREATION_TIME:
ret.Add(new LSL_String(""));