mirror of
https://github.com/opensim/opensim.git
synced 2026-08-07 17:55:48 +08:00
Merge branch 'master' into varregion
This commit is contained in:
@@ -33,6 +33,7 @@ using OpenSim.Framework;
|
||||
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
{
|
||||
@@ -119,6 +120,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if the xfer is a terrain xfer
|
||||
IEstateModule estateModule = m_Scene.RequestModuleInterface<IEstateModule>();
|
||||
if (estateModule != null)
|
||||
{
|
||||
if (estateModule.IsTerrainXfer(xferID))
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.ErrorFormat(
|
||||
"[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}",
|
||||
xferID, packetID, data.Length);
|
||||
|
||||
@@ -42,14 +42,22 @@ using log4net;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
public class FriendsRequestHandler : BaseStreamHandler
|
||||
public class FriendsRequestHandler : BaseStreamHandlerBasicDOSProtector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private FriendsModule m_FriendsModule;
|
||||
|
||||
public FriendsRequestHandler(FriendsModule fmodule)
|
||||
: base("POST", "/friends")
|
||||
: base("POST", "/friends", new BasicDosProtectorOptions()
|
||||
{
|
||||
AllowXForwardedFor = true,
|
||||
ForgetTimeSpan = TimeSpan.FromMinutes(2),
|
||||
MaxRequestsInTimeframe = 20,
|
||||
ReportingName = "FRIENDSDOSPROTECTOR",
|
||||
RequestTimeSpan = TimeSpan.FromSeconds(5),
|
||||
ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod
|
||||
})
|
||||
{
|
||||
m_FriendsModule = fmodule;
|
||||
}
|
||||
|
||||
@@ -757,64 +757,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
SceneObjectGroup group = null;
|
||||
|
||||
string xmlData = Utils.BytesToString(rezAsset.Data);
|
||||
List<SceneObjectGroup> objlist = new List<SceneObjectGroup>();
|
||||
List<Vector3> veclist = new List<Vector3>();
|
||||
List<SceneObjectGroup> objlist;
|
||||
List<Vector3> veclist;
|
||||
Vector3 bbox;
|
||||
float offsetHeight;
|
||||
byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
|
||||
Vector3 pos;
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.LoadXml(xmlData);
|
||||
XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
|
||||
if (e == null || attachment) // Single
|
||||
bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);
|
||||
|
||||
if (single)
|
||||
{
|
||||
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
|
||||
|
||||
objlist.Add(g);
|
||||
veclist.Add(Vector3.Zero);
|
||||
|
||||
float offsetHeight = 0;
|
||||
pos = m_Scene.GetNewRezLocation(
|
||||
RayStart, RayEnd, RayTargetID, Quaternion.Identity,
|
||||
BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
|
||||
BypassRayCast, bRayEndIsIntersection, true, bbox, false);
|
||||
pos.Z += offsetHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlElement coll = (XmlElement)e;
|
||||
float bx = Convert.ToSingle(coll.GetAttribute("x"));
|
||||
float by = Convert.ToSingle(coll.GetAttribute("y"));
|
||||
float bz = Convert.ToSingle(coll.GetAttribute("z"));
|
||||
Vector3 bbox = new Vector3(bx, by, bz);
|
||||
|
||||
pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
|
||||
RayTargetID, Quaternion.Identity,
|
||||
BypassRayCast, bRayEndIsIntersection, true,
|
||||
bbox, false);
|
||||
|
||||
pos -= bbox / 2;
|
||||
|
||||
XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
|
||||
foreach (XmlNode n in groups)
|
||||
{
|
||||
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
|
||||
|
||||
objlist.Add(g);
|
||||
XmlElement el = (XmlElement)n;
|
||||
|
||||
string rawX = el.GetAttribute("offsetx");
|
||||
string rawY = el.GetAttribute("offsety");
|
||||
string rawZ = el.GetAttribute("offsetz");
|
||||
//
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>",
|
||||
// g.Name, rawX, rawY, rawZ);
|
||||
|
||||
float x = Convert.ToSingle(rawX);
|
||||
float y = Convert.ToSingle(rawY);
|
||||
float z = Convert.ToSingle(rawZ);
|
||||
veclist.Add(new Vector3(x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
|
||||
|
||||
@@ -829,26 +829,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
|
||||
private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID)
|
||||
{
|
||||
if (TerrainUploader != null)
|
||||
lock (this)
|
||||
{
|
||||
lock (TerrainUploader)
|
||||
if ((TerrainUploader != null) && (XferID == TerrainUploader.XferID))
|
||||
{
|
||||
if (XferID == TerrainUploader.XferID)
|
||||
{
|
||||
remoteClient.OnXferReceive -= TerrainUploader.XferReceive;
|
||||
remoteClient.OnAbortXfer -= AbortTerrainXferHandler;
|
||||
TerrainUploader.TerrainUploadDone -= HandleTerrainApplication;
|
||||
remoteClient.OnXferReceive -= TerrainUploader.XferReceive;
|
||||
remoteClient.OnAbortXfer -= AbortTerrainXferHandler;
|
||||
TerrainUploader.TerrainUploadDone -= HandleTerrainApplication;
|
||||
|
||||
TerrainUploader = null;
|
||||
remoteClient.SendAlertMessage("Terrain Upload aborted by the client");
|
||||
}
|
||||
TerrainUploader = null;
|
||||
remoteClient.SendAlertMessage("Terrain Upload aborted by the client");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient)
|
||||
{
|
||||
lock (TerrainUploader)
|
||||
lock (this)
|
||||
{
|
||||
remoteClient.OnXferReceive -= TerrainUploader.XferReceive;
|
||||
remoteClient.OnAbortXfer -= AbortTerrainXferHandler;
|
||||
@@ -907,22 +904,32 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
|
||||
private void handleUploadTerrain(IClientAPI remote_client, string clientFileName)
|
||||
{
|
||||
if (TerrainUploader == null)
|
||||
lock (this)
|
||||
{
|
||||
|
||||
TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName);
|
||||
lock (TerrainUploader)
|
||||
if (TerrainUploader == null)
|
||||
{
|
||||
m_log.DebugFormat("Starting to receive uploaded terrain");
|
||||
TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName);
|
||||
remote_client.OnXferReceive += TerrainUploader.XferReceive;
|
||||
remote_client.OnAbortXfer += AbortTerrainXferHandler;
|
||||
TerrainUploader.TerrainUploadDone += HandleTerrainApplication;
|
||||
TerrainUploader.RequestStartXfer(remote_client);
|
||||
}
|
||||
else
|
||||
{
|
||||
remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!");
|
||||
}
|
||||
TerrainUploader.RequestStartXfer(remote_client);
|
||||
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
public bool IsTerrainXfer(ulong xferID)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!");
|
||||
if (TerrainUploader == null)
|
||||
return false;
|
||||
else
|
||||
return TerrainUploader.XferID == xferID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
/// <param name="data"></param>
|
||||
public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
|
||||
{
|
||||
if (mXferID == xferID)
|
||||
if (mXferID != xferID)
|
||||
return;
|
||||
|
||||
lock (this)
|
||||
{
|
||||
if (m_asset.Data.Length > 1)
|
||||
{
|
||||
@@ -99,7 +102,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
if ((packetID & 0x80000000) != 0)
|
||||
{
|
||||
SendCompleteMessage(remoteClient);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||
regionimage = regionimage.Replace("-", "");
|
||||
m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage);
|
||||
|
||||
MainServer.Instance.AddHTTPHandler(regionimage, OnHTTPGetMapImage);
|
||||
MainServer.Instance.AddHTTPHandler(regionimage,
|
||||
new GenericHTTPDOSProtector(OnHTTPGetMapImage, OnHTTPThrottled, new BasicDosProtectorOptions()
|
||||
{
|
||||
AllowXForwardedFor = false,
|
||||
ForgetTimeSpan = TimeSpan.FromMinutes(2),
|
||||
MaxRequestsInTimeframe = 4,
|
||||
ReportingName = "MAPDOSPROTECTOR",
|
||||
RequestTimeSpan = TimeSpan.FromSeconds(10),
|
||||
ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod
|
||||
}).Process);
|
||||
MainServer.Instance.AddLLSDHandler(
|
||||
"/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest);
|
||||
|
||||
@@ -1081,6 +1090,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||
block.Y = (ushort)(r.RegionLocY / Constants.RegionSize);
|
||||
}
|
||||
|
||||
public Hashtable OnHTTPThrottled(Hashtable keysvals)
|
||||
{
|
||||
Hashtable reply = new Hashtable();
|
||||
int statuscode = 500;
|
||||
reply["str_response_string"] = "";
|
||||
reply["int_response_code"] = statuscode;
|
||||
reply["content_type"] = "text/plain";
|
||||
return reply;
|
||||
}
|
||||
|
||||
public Hashtable OnHTTPGetMapImage(Hashtable keysvals)
|
||||
{
|
||||
m_log.Debug("[WORLD MAP]: Sending map image jpeg");
|
||||
|
||||
@@ -234,15 +234,17 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
List<TaskInventoryItem> GetInventoryItems(InventoryType type);
|
||||
|
||||
/// <summary>
|
||||
/// Get the scene object referenced by an inventory item.
|
||||
/// Get the scene object(s) referenced by an inventory item.
|
||||
/// </summary>
|
||||
///
|
||||
/// This is returned in a 'rez ready' state. That is, name, description, permissions and other details have
|
||||
/// been adjusted to reflect the part and item from which it originates.
|
||||
///
|
||||
/// <param name="item"></param>
|
||||
/// <returns>The scene object. Null if the scene object asset couldn't be found</returns>
|
||||
SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item);
|
||||
/// <param name="item">Inventory item</param>
|
||||
/// <param name="objlist">The scene objects</param>
|
||||
/// <param name="veclist">Relative offsets for each object</param>
|
||||
/// <returns>true = success, false = the scene object asset couldn't be found</returns>
|
||||
bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist);
|
||||
|
||||
/// <summary>
|
||||
/// Update an existing inventory item.
|
||||
|
||||
@@ -54,5 +54,10 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
|
||||
void setEstateTerrainBaseTexture(int level, UUID texture);
|
||||
void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the transfer ID is being used for a terrain transfer.
|
||||
/// </summary>
|
||||
bool IsTerrainXfer(ulong xferID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Timers;
|
||||
using System.Xml;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using log4net;
|
||||
@@ -2134,6 +2135,69 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the list of Scene Objects in an asset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns one object if the asset is a regular object, and multiple objects for a coalesced object.
|
||||
/// </remarks>
|
||||
/// <param name="assetData">Asset data</param>
|
||||
/// <param name="attachment">Whether the item is an attachment</param>
|
||||
/// <param name="objlist">The objects included in the asset</param>
|
||||
/// <param name="veclist">Relative positions of the objects</param>
|
||||
/// <param name="bbox">Bounding box of all the objects</param>
|
||||
/// <param name="offsetHeight">Offset in the Z axis from the centre of the bounding box
|
||||
/// to the centre of the root prim (relevant only when returning a single object)</param>
|
||||
/// <returns>true = returning a single object; false = multiple objects</returns>
|
||||
public bool GetObjectsToRez(byte[] assetData, bool attachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist,
|
||||
out Vector3 bbox, out float offsetHeight)
|
||||
{
|
||||
objlist = new List<SceneObjectGroup>();
|
||||
veclist = new List<Vector3>();
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
string xmlData = Utils.BytesToString(assetData);
|
||||
doc.LoadXml(xmlData);
|
||||
XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
|
||||
|
||||
if (e == null || attachment) // Single
|
||||
{
|
||||
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
|
||||
objlist.Add(g);
|
||||
veclist.Add(new Vector3(0, 0, 0));
|
||||
bbox = g.GetAxisAlignedBoundingBox(out offsetHeight);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlElement coll = (XmlElement)e;
|
||||
float bx = Convert.ToSingle(coll.GetAttribute("x"));
|
||||
float by = Convert.ToSingle(coll.GetAttribute("y"));
|
||||
float bz = Convert.ToSingle(coll.GetAttribute("z"));
|
||||
bbox = new Vector3(bx, by, bz);
|
||||
offsetHeight = 0;
|
||||
|
||||
XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
|
||||
foreach (XmlNode n in groups)
|
||||
{
|
||||
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
|
||||
objlist.Add(g);
|
||||
|
||||
XmlElement el = (XmlElement)n;
|
||||
string rawX = el.GetAttribute("offsetx");
|
||||
string rawY = el.GetAttribute("offsety");
|
||||
string rawZ = el.GetAttribute("offsetz");
|
||||
|
||||
float x = Convert.ToSingle(rawX);
|
||||
float y = Convert.ToSingle(rawY);
|
||||
float z = Convert.ToSingle(rawZ);
|
||||
veclist.Add(new Vector3(x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event Handler Rez an object into a scene
|
||||
/// Calls the non-void event handler
|
||||
@@ -2209,19 +2273,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// will be used if it exists.</param>
|
||||
/// <param name="vel">The velocity of the rezzed object.</param>
|
||||
/// <param name="param"></param>
|
||||
/// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns>
|
||||
public virtual SceneObjectGroup RezObject(
|
||||
/// <returns>The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful</returns>
|
||||
public virtual List<SceneObjectGroup> RezObject(
|
||||
SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param)
|
||||
{
|
||||
if (null == item)
|
||||
return null;
|
||||
|
||||
List<SceneObjectGroup> objlist;
|
||||
List<Vector3> veclist;
|
||||
|
||||
SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item);
|
||||
|
||||
if (null == group)
|
||||
bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist);
|
||||
if (!success)
|
||||
return null;
|
||||
|
||||
if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
|
||||
|
||||
int totalPrims = 0;
|
||||
foreach (SceneObjectGroup group in objlist)
|
||||
totalPrims += group.PrimCount;
|
||||
|
||||
if (!Permissions.CanRezObject(totalPrims, item.OwnerID, pos))
|
||||
return null;
|
||||
|
||||
if (!Permissions.BypassPermissions())
|
||||
@@ -2230,23 +2300,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
|
||||
}
|
||||
|
||||
|
||||
if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
|
||||
for (int i = 0; i < objlist.Count; i++)
|
||||
{
|
||||
group.RootPart.AttachedPos = group.AbsolutePosition;
|
||||
group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
|
||||
SceneObjectGroup group = objlist[i];
|
||||
Vector3 curpos = pos + veclist[i];
|
||||
|
||||
if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
|
||||
{
|
||||
group.RootPart.AttachedPos = group.AbsolutePosition;
|
||||
group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
|
||||
}
|
||||
|
||||
group.FromPartID = sourcePart.UUID;
|
||||
AddNewSceneObject(group, true, curpos, rot, vel);
|
||||
|
||||
// We can only call this after adding the scene object, since the scene object references the scene
|
||||
// to find out if scripts should be activated at all.
|
||||
group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
|
||||
|
||||
group.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
|
||||
group.FromPartID = sourcePart.UUID;
|
||||
AddNewSceneObject(group, true, pos, rot, vel);
|
||||
|
||||
// We can only call this after adding the scene object, since the scene object references the scene
|
||||
// to find out if scripts should be activated at all.
|
||||
group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
|
||||
|
||||
group.ScheduleGroupForFullUpdate();
|
||||
|
||||
return group;
|
||||
|
||||
return objlist;
|
||||
}
|
||||
|
||||
public virtual bool returnObjects(SceneObjectGroup[] returnobjects,
|
||||
|
||||
@@ -733,8 +733,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item)
|
||||
|
||||
public bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist)
|
||||
{
|
||||
AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
|
||||
|
||||
@@ -743,66 +743,75 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.WarnFormat(
|
||||
"[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}",
|
||||
item.AssetID, item.Name, m_part.Name);
|
||||
return null;
|
||||
objlist = null;
|
||||
veclist = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
string xmlData = Utils.BytesToString(rezAsset.Data);
|
||||
SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
|
||||
Vector3 bbox;
|
||||
float offsetHeight;
|
||||
|
||||
group.ResetIDs();
|
||||
bool single = m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight);
|
||||
|
||||
SceneObjectPart rootPart = group.GetPart(group.UUID);
|
||||
|
||||
// Since renaming the item in the inventory does not affect the name stored
|
||||
// in the serialization, transfer the correct name from the inventory to the
|
||||
// object itself before we rez.
|
||||
rootPart.Name = item.Name;
|
||||
rootPart.Description = item.Description;
|
||||
|
||||
SceneObjectPart[] partList = group.Parts;
|
||||
|
||||
group.SetGroup(m_part.GroupID, null);
|
||||
|
||||
// TODO: Remove magic number badness
|
||||
if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
|
||||
for (int i = 0; i < objlist.Count; i++)
|
||||
{
|
||||
if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
|
||||
{
|
||||
foreach (SceneObjectPart part in partList)
|
||||
{
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
|
||||
part.EveryoneMask = item.EveryonePermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
|
||||
part.NextOwnerMask = item.NextPermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
|
||||
part.GroupMask = item.GroupPermissions;
|
||||
}
|
||||
|
||||
group.ApplyNextOwnerPermissions();
|
||||
}
|
||||
}
|
||||
SceneObjectGroup group = objlist[i];
|
||||
|
||||
group.ResetIDs();
|
||||
|
||||
SceneObjectPart rootPart = group.GetPart(group.UUID);
|
||||
|
||||
// Since renaming the item in the inventory does not affect the name stored
|
||||
// in the serialization, transfer the correct name from the inventory to the
|
||||
// object itself before we rez.
|
||||
rootPart.Name = item.Name;
|
||||
rootPart.Description = item.Description;
|
||||
|
||||
SceneObjectPart[] partList = group.Parts;
|
||||
|
||||
group.SetGroup(m_part.GroupID, null);
|
||||
|
||||
foreach (SceneObjectPart part in partList)
|
||||
{
|
||||
// TODO: Remove magic number badness
|
||||
if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
|
||||
if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
|
||||
{
|
||||
part.LastOwnerID = part.OwnerID;
|
||||
part.OwnerID = item.OwnerID;
|
||||
part.Inventory.ChangeInventoryOwner(item.OwnerID);
|
||||
if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
|
||||
{
|
||||
foreach (SceneObjectPart part in partList)
|
||||
{
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
|
||||
part.EveryoneMask = item.EveryonePermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
|
||||
part.NextOwnerMask = item.NextPermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
|
||||
part.GroupMask = item.GroupPermissions;
|
||||
}
|
||||
|
||||
group.ApplyNextOwnerPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
|
||||
part.EveryoneMask = item.EveryonePermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
|
||||
part.NextOwnerMask = item.NextPermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
|
||||
part.GroupMask = item.GroupPermissions;
|
||||
|
||||
foreach (SceneObjectPart part in partList)
|
||||
{
|
||||
// TODO: Remove magic number badness
|
||||
if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
|
||||
{
|
||||
part.LastOwnerID = part.OwnerID;
|
||||
part.OwnerID = item.OwnerID;
|
||||
part.Inventory.ChangeInventoryOwner(item.OwnerID);
|
||||
}
|
||||
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
|
||||
part.EveryoneMask = item.EveryonePermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
|
||||
part.NextOwnerMask = item.NextPermissions;
|
||||
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
|
||||
part.GroupMask = item.GroupPermissions;
|
||||
}
|
||||
|
||||
rootPart.TrimPermissions();
|
||||
}
|
||||
|
||||
rootPart.TrimPermissions();
|
||||
|
||||
return group;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -39,6 +39,7 @@ using OpenSim.Framework.Communications;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using System.Text;
|
||||
using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
@@ -421,44 +422,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
string Subject = im.message.Substring(0, im.message.IndexOf('|'));
|
||||
string Message = im.message.Substring(Subject.Length + 1);
|
||||
|
||||
InventoryItemBase item = null;
|
||||
bool hasAttachment = false;
|
||||
UUID itemID = UUID.Zero; //Assignment to quiet compiler
|
||||
UUID ownerID = UUID.Zero; //Assignment to quiet compiler
|
||||
byte[] bucket;
|
||||
|
||||
if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0))
|
||||
{
|
||||
bucket = new byte[19];
|
||||
bucket[0] = 0; //dunno
|
||||
bucket[1] = 0; //dunno
|
||||
GroupID.ToBytes(bucket, 2);
|
||||
bucket[18] = 0; //dunno
|
||||
}
|
||||
else
|
||||
if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
|
||||
{
|
||||
string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
|
||||
binBucket = binBucket.Remove(0, 14).Trim();
|
||||
if (m_debugEnabled)
|
||||
{
|
||||
m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket);
|
||||
|
||||
OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
|
||||
|
||||
foreach (string key in binBucketOSD.Keys)
|
||||
OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
|
||||
if (binBucketOSD is OSD)
|
||||
{
|
||||
OSDMap binBucketMap = (OSDMap)binBucketOSD;
|
||||
|
||||
itemID = binBucketMap["item_id"].AsUUID();
|
||||
ownerID = binBucketMap["owner_id"].AsUUID();
|
||||
|
||||
//Attempt to get the details of the attached item.
|
||||
//If sender doesn't own the attachment, the item
|
||||
//variable will be set to null and attachment will
|
||||
//not be included with the group notice.
|
||||
Scene scene = (Scene)remoteClient.Scene;
|
||||
item = new InventoryItemBase(itemID, ownerID);
|
||||
item = scene.InventoryService.GetItem(item);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (binBucketOSD.ContainsKey(key))
|
||||
{
|
||||
m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString());
|
||||
}
|
||||
//Got item details so include the attachment.
|
||||
hasAttachment = true;
|
||||
}
|
||||
}
|
||||
|
||||
// treat as if no attachment
|
||||
bucket = new byte[19];
|
||||
bucket[0] = 0; //dunno
|
||||
bucket[1] = 0; //dunno
|
||||
GroupID.ToBytes(bucket, 2);
|
||||
bucket[18] = 0; //dunno
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType());
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAttachment)
|
||||
{
|
||||
//Bucket contains information about attachment.
|
||||
//
|
||||
//Byte offset and description of bucket data:
|
||||
//0: 1 byte indicating if attachment is present
|
||||
//1: 1 byte indicating the type of attachment
|
||||
//2: 16 bytes - Group UUID
|
||||
//18: 16 bytes - UUID of the attachment owner
|
||||
//34: 16 bytes - UUID of the attachment
|
||||
//50: variable - Name of the attachment
|
||||
//??: NUL byte to terminate the attachment name
|
||||
byte[] name = Encoding.UTF8.GetBytes(item.Name);
|
||||
bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name
|
||||
bucket[0] = 1; //Has attachment flag
|
||||
bucket[1] = (byte)item.InvType; //Type of Attachment
|
||||
GroupID.ToBytes(bucket, 2);
|
||||
ownerID.ToBytes(bucket, 18);
|
||||
itemID.ToBytes(bucket, 34);
|
||||
name.CopyTo(bucket, 50);
|
||||
}
|
||||
else
|
||||
{
|
||||
bucket = new byte[19];
|
||||
bucket[0] = 0; //Has attachment flag
|
||||
bucket[1] = 0; //Type of attachment
|
||||
GroupID.ToBytes(bucket, 2);
|
||||
bucket[18] = 0; //NUL terminate name of attachment
|
||||
}
|
||||
|
||||
|
||||
m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
|
||||
if (OnNewGroupNotice != null)
|
||||
{
|
||||
@@ -483,7 +515,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
|
||||
if (member.AcceptNotices)
|
||||
{
|
||||
// Build notice IIM
|
||||
// Build notice IM
|
||||
GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
|
||||
|
||||
msg.toAgentID = member.AgentID.Guid;
|
||||
@@ -492,10 +524,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted)
|
||||
{
|
||||
//Is bucket large enough to hold UUID of the attachment?
|
||||
if (im.binaryBucket.Length < 16)
|
||||
return;
|
||||
|
||||
UUID noticeID = new UUID(im.imSessionID);
|
||||
|
||||
GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID);
|
||||
if (notice != null)
|
||||
{
|
||||
UUID giver = new UUID(notice.BinaryBucket, 18);
|
||||
UUID attachmentUUID = new UUID(notice.BinaryBucket, 34);
|
||||
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
|
||||
|
||||
InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
|
||||
giver, attachmentUUID);
|
||||
|
||||
if (itemCopy == null)
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
|
||||
return;
|
||||
}
|
||||
|
||||
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Interop, received special 210 code for ejecting a group member
|
||||
// this only works within the comms servers domain, and won't work hypergrid
|
||||
// TODO:FIXME: Use a presense server of some kind to find out where the
|
||||
// TODO:FIXME: Use a presence server of some kind to find out where the
|
||||
// client actually is, and try contacting that region directly to notify them,
|
||||
// or provide the notification via xmlrpc update queue
|
||||
if ((im.dialog == 210))
|
||||
@@ -873,26 +935,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null);
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
msg.imSessionID = UUID.Zero.Guid;
|
||||
msg.fromAgentID = data.GroupID.Guid;
|
||||
msg.toAgentID = GetRequestingAgentID(remoteClient).Guid;
|
||||
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||
msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName;
|
||||
msg.message = data.noticeData.Subject + "|" + data.Message;
|
||||
msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
|
||||
msg.fromGroup = true;
|
||||
msg.offline = (byte)0;
|
||||
msg.ParentEstateID = 0;
|
||||
msg.Position = Vector3.Zero;
|
||||
msg.RegionID = UUID.Zero.Guid;
|
||||
msg.binaryBucket = data.BinaryBucket;
|
||||
GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
|
||||
|
||||
OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog)
|
||||
@@ -900,10 +946,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
msg.imSessionID = UUID.Zero.Guid;
|
||||
byte[] bucket;
|
||||
|
||||
msg.imSessionID = groupNoticeID.Guid;
|
||||
msg.toAgentID = agentID.Guid;
|
||||
msg.dialog = dialog;
|
||||
// msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice;
|
||||
msg.fromGroup = true;
|
||||
msg.offline = (byte)0;
|
||||
msg.ParentEstateID = 0;
|
||||
@@ -917,13 +964,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
msg.timestamp = info.noticeData.Timestamp;
|
||||
msg.fromAgentName = info.noticeData.FromName;
|
||||
msg.message = info.noticeData.Subject + "|" + info.Message;
|
||||
msg.binaryBucket = info.BinaryBucket;
|
||||
|
||||
if (info.BinaryBucket[0] > 0)
|
||||
{
|
||||
//32 is due to not needing space for two of the UUIDs.
|
||||
//(Don't need UUID of attachment or its owner in IM)
|
||||
//50 offset gets us to start of attachment name.
|
||||
//We are skipping the attachment flag, type, and
|
||||
//the three UUID fields at the start of the bucket.
|
||||
bucket = new byte[info.BinaryBucket.Length-32];
|
||||
bucket[0] = 1; //Has attachment
|
||||
bucket[1] = info.BinaryBucket[1];
|
||||
Array.Copy(info.BinaryBucket, 50,
|
||||
bucket, 18, info.BinaryBucket.Length-50);
|
||||
}
|
||||
else
|
||||
{
|
||||
bucket = new byte[19];
|
||||
bucket[0] = 0; //No attachment
|
||||
bucket[1] = 0; //Attachment type
|
||||
bucket[18] = 0; //NUL terminate name
|
||||
}
|
||||
|
||||
info.GroupID.ToBytes(bucket, 2);
|
||||
msg.binaryBucket = bucket;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID);
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID);
|
||||
|
||||
msg.fromAgentID = UUID.Zero.Guid;
|
||||
msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ;
|
||||
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||
msg.fromAgentName = string.Empty;
|
||||
msg.message = string.Empty;
|
||||
msg.binaryBucket = new byte[0];
|
||||
@@ -1047,7 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
// Message to ejector
|
||||
// Interop, received special 210 code for ejecting a group member
|
||||
// this only works within the comms servers domain, and won't work hypergrid
|
||||
// TODO:FIXME: Use a presense server of some kind to find out where the
|
||||
// TODO:FIXME: Use a presence server of some kind to find out where the
|
||||
// client actually is, and try contacting that region directly to notify them,
|
||||
// or provide the notification via xmlrpc update queue
|
||||
|
||||
|
||||
@@ -1125,7 +1125,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
// If body is already heigher, use its height as target height
|
||||
if (VehiclePosition.Z > m_VhoverTargetHeight)
|
||||
{
|
||||
m_VhoverTargetHeight = VehiclePosition.Z;
|
||||
|
||||
// A 'misfeature' of this flag is that if the vehicle is above it's hover height,
|
||||
// the vehicle's buoyancy goes away. This is an SL bug that got used by so many
|
||||
// scripts that it could not be changed.
|
||||
// So, if above the height, reapply gravity if buoyancy had it turned off.
|
||||
if (m_VehicleBuoyancy != 0)
|
||||
{
|
||||
Vector3 appliedGravity = ControllingPrim.ComputeGravity(ControllingPrim.Buoyancy) * m_vehicleMass;
|
||||
VehicleAddForce(appliedGravity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
|
||||
@@ -354,6 +354,8 @@ public sealed class BSTerrainManager : IDisposable
|
||||
// Return a new position that is over known terrain if the position is outside our terrain.
|
||||
public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos)
|
||||
{
|
||||
float edgeEpsilon = 0.1f;
|
||||
|
||||
Vector3 ret = pPos;
|
||||
|
||||
// First, base addresses are never negative so correct for that possible problem.
|
||||
@@ -378,10 +380,19 @@ public sealed class BSTerrainManager : IDisposable
|
||||
// NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region.
|
||||
|
||||
// Must be off the top of a region. Find an adjacent region to move into.
|
||||
// The returned terrain is always 'lower'. That is, closer to <0,0>.
|
||||
Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ);
|
||||
|
||||
ret.X = Math.Min(ret.X, adjacentTerrainBase.X + (ret.X % DefaultRegionSize.X));
|
||||
ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + (ret.X % DefaultRegionSize.Y));
|
||||
if (adjacentTerrainBase.X < terrainBaseXYZ.X)
|
||||
{
|
||||
// moving down into a new region in the X dimension. New position will be the max in the new base.
|
||||
ret.X = adjacentTerrainBase.X + DefaultRegionSize.X - edgeEpsilon;
|
||||
}
|
||||
if (adjacentTerrainBase.Y < terrainBaseXYZ.Y)
|
||||
{
|
||||
// moving down into a new region in the X dimension. New position will be the max in the new base.
|
||||
ret.Y = adjacentTerrainBase.Y + DefaultRegionSize.Y - edgeEpsilon;
|
||||
}
|
||||
DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}",
|
||||
BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret);
|
||||
|
||||
|
||||
@@ -2970,37 +2970,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
// need the magnitude later
|
||||
// float velmag = (float)Util.GetMagnitude(llvel);
|
||||
|
||||
SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param);
|
||||
List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param);
|
||||
|
||||
// If either of these are null, then there was an unknown error.
|
||||
if (new_group == null)
|
||||
if (new_groups == null)
|
||||
return;
|
||||
|
||||
// objects rezzed with this method are die_at_edge by default.
|
||||
new_group.RootPart.SetDieAtEdge(true);
|
||||
|
||||
new_group.ResumeScripts();
|
||||
|
||||
m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
|
||||
"object_rez", new Object[] {
|
||||
new LSL_String(
|
||||
new_group.RootPart.UUID.ToString()) },
|
||||
new DetectParams[0]));
|
||||
|
||||
float groupmass = new_group.GetMass();
|
||||
|
||||
PhysicsActor pa = new_group.RootPart.PhysActor;
|
||||
|
||||
//Recoil.
|
||||
if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
|
||||
foreach (SceneObjectGroup group in new_groups)
|
||||
{
|
||||
Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
|
||||
if (recoil != Vector3.Zero)
|
||||
// objects rezzed with this method are die_at_edge by default.
|
||||
group.RootPart.SetDieAtEdge(true);
|
||||
|
||||
group.ResumeScripts();
|
||||
|
||||
m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
|
||||
"object_rez", new Object[] {
|
||||
new LSL_String(
|
||||
group.RootPart.UUID.ToString()) },
|
||||
new DetectParams[0]));
|
||||
|
||||
float groupmass = group.GetMass();
|
||||
|
||||
PhysicsActor pa = group.RootPart.PhysActor;
|
||||
|
||||
//Recoil.
|
||||
if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
|
||||
{
|
||||
llApplyImpulse(recoil, 0);
|
||||
Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
|
||||
if (recoil != Vector3.Zero)
|
||||
{
|
||||
llApplyImpulse(recoil, 0);
|
||||
}
|
||||
}
|
||||
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
|
||||
}
|
||||
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
|
||||
});
|
||||
|
||||
//ScriptSleep((int)((groupmass * velmag) / 10));
|
||||
|
||||
Reference in New Issue
Block a user