Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
commit
7000b52aeb
|
@ -30,6 +30,7 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
|
@ -68,6 +69,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
private IHttpServer m_httpListener;
|
||||
private UUID m_agentID;
|
||||
private string m_regionName;
|
||||
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
|
||||
|
||||
public UUID AgentID
|
||||
{
|
||||
|
@ -171,5 +173,16 @@ namespace OpenSim.Framework.Capabilities
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
m_capsActive.Set();
|
||||
}
|
||||
|
||||
public bool WaitForActivation()
|
||||
{
|
||||
// Wait for 30s. If that elapses, return false and run without caps
|
||||
return m_capsActive.WaitOne(30000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -435,4 +435,4 @@ namespace OpenSim.Capabilities.Handlers
|
|||
return llsdItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1339,7 +1339,7 @@ namespace OpenSim.Data.MySQL
|
|||
prim.Density = (float)(double)row["Density"];
|
||||
prim.GravityModifier = (float)(double)row["GravityModifier"];
|
||||
prim.Friction = (float)(double)row["Friction"];
|
||||
prim.Bounciness = (float)(double)row["Restitution"];
|
||||
prim.Restitution = (float)(double)row["Restitution"];
|
||||
|
||||
SOPVehicle vehicle = null;
|
||||
|
||||
|
@ -1725,7 +1725,7 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("Density", (double)prim.Density);
|
||||
cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier);
|
||||
cmd.Parameters.AddWithValue("Friction", (double)prim.Friction);
|
||||
cmd.Parameters.AddWithValue("Restitution", (double)prim.Bounciness);
|
||||
cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution);
|
||||
|
||||
if (prim.VehicleParams != null)
|
||||
cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2());
|
||||
|
|
|
@ -497,8 +497,6 @@ namespace OpenSim.Framework
|
|||
/// </remarks>
|
||||
public List<AvatarAttachment> GetAttachments()
|
||||
{
|
||||
|
||||
|
||||
lock (m_attachments)
|
||||
{
|
||||
List<AvatarAttachment> alist = new List<AvatarAttachment>();
|
||||
|
@ -508,7 +506,8 @@ namespace OpenSim.Framework
|
|||
alist.Add(new AvatarAttachment(attach));
|
||||
}
|
||||
return alist;
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
internal void AppendAttachment(AvatarAttachment attach)
|
||||
{
|
||||
|
|
|
@ -2097,4 +2097,112 @@ namespace OpenSim.Framework
|
|||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class DoubleQueue<T> where T:class
|
||||
{
|
||||
private Queue<T> m_lowQueue = new Queue<T>();
|
||||
private Queue<T> m_highQueue = new Queue<T>();
|
||||
|
||||
private object m_syncRoot = new object();
|
||||
private Semaphore m_s = new Semaphore(0, 1);
|
||||
|
||||
public DoubleQueue()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Count
|
||||
{
|
||||
get { return m_highQueue.Count + m_lowQueue.Count; }
|
||||
}
|
||||
|
||||
public virtual void Enqueue(T data)
|
||||
{
|
||||
Enqueue(m_lowQueue, data);
|
||||
}
|
||||
|
||||
public virtual void EnqueueLow(T data)
|
||||
{
|
||||
Enqueue(m_lowQueue, data);
|
||||
}
|
||||
|
||||
public virtual void EnqueueHigh(T data)
|
||||
{
|
||||
Enqueue(m_highQueue, data);
|
||||
}
|
||||
|
||||
private void Enqueue(Queue<T> q, T data)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
m_lowQueue.Enqueue(data);
|
||||
m_s.WaitOne(0);
|
||||
m_s.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T Dequeue()
|
||||
{
|
||||
return Dequeue(Timeout.Infinite);
|
||||
}
|
||||
|
||||
public virtual T Dequeue(int tmo)
|
||||
{
|
||||
return Dequeue(TimeSpan.FromMilliseconds(tmo));
|
||||
}
|
||||
|
||||
public virtual T Dequeue(TimeSpan wait)
|
||||
{
|
||||
T res = null;
|
||||
|
||||
if (!Dequeue(wait, ref res))
|
||||
return null;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool Dequeue(int timeout, ref T res)
|
||||
{
|
||||
return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
|
||||
}
|
||||
|
||||
public bool Dequeue(TimeSpan wait, ref T res)
|
||||
{
|
||||
if (!m_s.WaitOne(wait))
|
||||
return false;
|
||||
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
if (m_highQueue.Count > 0)
|
||||
res = m_highQueue.Dequeue();
|
||||
else
|
||||
res = m_lowQueue.Dequeue();
|
||||
|
||||
if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
m_s.Release();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
// Make sure sem count is 0
|
||||
m_s.WaitOne(0);
|
||||
|
||||
m_lowQueue.Clear();
|
||||
m_highQueue.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,6 +343,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
m_log.DebugFormat(
|
||||
"[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
|
||||
|
||||
if (!m_HostCapsObj.WaitForActivation())
|
||||
return string.Empty;
|
||||
|
||||
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
|
@ -1317,7 +1320,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
|
||||
object_data["Density"] = obj.Density;
|
||||
object_data["Friction"] = obj.Friction;
|
||||
object_data["Restitution"] = obj.Bounciness;
|
||||
object_data["Restitution"] = obj.Restitution;
|
||||
object_data["GravityMultiplier"] = obj.GravityModifier;
|
||||
|
||||
resp[uuid.ToString()] = object_data;
|
||||
|
|
|
@ -467,8 +467,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["str_response_string"] = "Upstream error: ";
|
||||
responsedata["error_status_text"] = "Upstream error:";
|
||||
responsedata["str_response_string"] = "<llsd></llsd>";
|
||||
responsedata["error_status_text"] = "<llsd></llsd>";
|
||||
responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
return responsedata;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
|
||||
|
||||
private Scene m_scene;
|
||||
|
||||
/// <summary>
|
||||
|
@ -94,6 +96,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
{
|
||||
m_scene = s;
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
|
||||
m_scene.RegisterModuleInterface<ISimulatorFeaturesModule>(this);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene s)
|
||||
|
@ -156,7 +160,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
IRequestHandler reqHandler
|
||||
= new RestHTTPHandler(
|
||||
"GET", "/CAPS/" + UUID.Random(),
|
||||
HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString());
|
||||
x => { return HandleSimulatorFeaturesRequest(x, agentID); }, "SimulatorFeatures", agentID.ToString());
|
||||
|
||||
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
||||
}
|
||||
|
@ -185,18 +189,33 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return new OSDMap(m_features);
|
||||
}
|
||||
|
||||
private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod)
|
||||
private OSDMap DeepCopy()
|
||||
{
|
||||
// This isn't the cheapest way of doing this but the rate
|
||||
// of occurrence is low (on sim entry only) and it's a sure
|
||||
// way to get a true deep copy.
|
||||
OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlString(m_features));
|
||||
|
||||
return (OSDMap)copy;
|
||||
}
|
||||
|
||||
private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
|
||||
|
||||
OSDMap copy = DeepCopy();
|
||||
|
||||
SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest;
|
||||
if (handlerOnSimulatorFeaturesRequest != null)
|
||||
handlerOnSimulatorFeaturesRequest(agentID, ref copy);
|
||||
|
||||
//Send back data
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
|
||||
lock (m_features)
|
||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features);
|
||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy);
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
|
|
|
@ -190,8 +190,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
{
|
||||
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
|
||||
{
|
||||
cacheItems[i].TextureID =
|
||||
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID;
|
||||
Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
|
||||
if (face == null)
|
||||
{
|
||||
textureEntry.CreateFace(cacheItems[i].TextureIndex);
|
||||
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
|
||||
AppearanceManager.DEFAULT_AVATAR_TEXTURE;
|
||||
continue;
|
||||
}
|
||||
cacheItems[i].TextureID =face.TextureID;
|
||||
if (m_scene.AssetService != null)
|
||||
cacheItems[i].TextureAsset =
|
||||
m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
|
||||
|
@ -213,8 +220,16 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
{
|
||||
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
|
||||
{
|
||||
Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
|
||||
if (face == null)
|
||||
{
|
||||
textureEntry.CreateFace(cacheItems[i].TextureIndex);
|
||||
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
|
||||
AppearanceManager.DEFAULT_AVATAR_TEXTURE;
|
||||
continue;
|
||||
}
|
||||
cacheItems[i].TextureID =
|
||||
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID;
|
||||
face.TextureID;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -39,10 +39,13 @@ using OpenSim.Framework.Servers;
|
|||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
using OpenSim.Capabilities.Handlers;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
|
@ -52,11 +55,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")]
|
||||
public class WebFetchInvDescModule : INonSharedRegionModule
|
||||
{
|
||||
struct aPollRequest
|
||||
class aPollRequest
|
||||
{
|
||||
public PollServiceInventoryEventArgs thepoll;
|
||||
public UUID reqID;
|
||||
public Hashtable request;
|
||||
public ScenePresence presence;
|
||||
public List<UUID> folders;
|
||||
}
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
@ -71,8 +76,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
||||
private static Thread[] m_workerThreads = null;
|
||||
|
||||
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
|
||||
new OpenMetaverse.BlockingQueue<aPollRequest>();
|
||||
private static DoubleQueue<aPollRequest> m_queue =
|
||||
new DoubleQueue<aPollRequest>();
|
||||
|
||||
#region ISharedRegionModule Members
|
||||
|
||||
|
@ -143,12 +148,18 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
private class PollServiceInventoryEventArgs : PollServiceEventArgs
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Dictionary<UUID, Hashtable> responses =
|
||||
new Dictionary<UUID, Hashtable>();
|
||||
|
||||
public PollServiceInventoryEventArgs(UUID pId) :
|
||||
private Scene m_scene;
|
||||
|
||||
public PollServiceInventoryEventArgs(Scene scene, UUID pId) :
|
||||
base(null, null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
m_scene = scene;
|
||||
|
||||
HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); };
|
||||
GetEvents = (x, y) =>
|
||||
{
|
||||
|
@ -167,12 +178,68 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
Request = (x, y) =>
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(Id);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.ErrorFormat("[INVENTORY]: Unable to find ScenePresence for {0}", Id);
|
||||
return;
|
||||
}
|
||||
|
||||
aPollRequest reqinfo = new aPollRequest();
|
||||
reqinfo.thepoll = this;
|
||||
reqinfo.reqID = x;
|
||||
reqinfo.request = y;
|
||||
reqinfo.presence = sp;
|
||||
reqinfo.folders = new List<UUID>();
|
||||
|
||||
m_queue.Enqueue(reqinfo);
|
||||
// Decode the request here
|
||||
string request = y["body"].ToString();
|
||||
|
||||
request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
|
||||
|
||||
request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
|
||||
request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
|
||||
|
||||
Hashtable hash = new Hashtable();
|
||||
try
|
||||
{
|
||||
hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
|
||||
}
|
||||
catch (LLSD.LLSDParseException e)
|
||||
{
|
||||
m_log.ErrorFormat("[INVENTORY]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
|
||||
m_log.Error("Request: " + request);
|
||||
return;
|
||||
}
|
||||
catch (System.Xml.XmlException)
|
||||
{
|
||||
m_log.ErrorFormat("[INVENTORY]: XML Format error");
|
||||
}
|
||||
|
||||
ArrayList foldersrequested = (ArrayList)hash["folders"];
|
||||
|
||||
bool highPriority = false;
|
||||
|
||||
for (int i = 0; i < foldersrequested.Count; i++)
|
||||
{
|
||||
Hashtable inventoryhash = (Hashtable)foldersrequested[i];
|
||||
string folder = inventoryhash["folder_id"].ToString();
|
||||
UUID folderID;
|
||||
if (UUID.TryParse(folder, out folderID))
|
||||
{
|
||||
if (!reqinfo.folders.Contains(folderID))
|
||||
{
|
||||
if (sp.COF != UUID.Zero && sp.COF == folderID)
|
||||
highPriority = true;
|
||||
reqinfo.folders.Add(folderID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highPriority)
|
||||
m_queue.EnqueueHigh(reqinfo);
|
||||
else
|
||||
m_queue.EnqueueLow(reqinfo);
|
||||
};
|
||||
|
||||
NoEvents = (x, y) =>
|
||||
|
@ -208,7 +275,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
response["reusecontext"] = false;
|
||||
|
||||
response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(
|
||||
requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null);
|
||||
requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null);
|
||||
|
||||
lock (responses)
|
||||
responses[requestID] = response;
|
||||
|
@ -220,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||
|
||||
// Register this as a poll service
|
||||
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID);
|
||||
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID);
|
||||
|
||||
args.Type = PollServiceEventArgs.EventType.Inventory;
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||
|
|
|
@ -2654,7 +2654,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
byte physshapetype = part.PhysicsShapeType;
|
||||
float density = part.Density;
|
||||
float friction = part.Friction;
|
||||
float bounce = part.Bounciness;
|
||||
float bounce = part.Restitution;
|
||||
float gravmod = part.GravityModifier;
|
||||
|
||||
eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
|
||||
|
@ -3893,6 +3893,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
part.Shape.LightEntry = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
|
||||
{
|
||||
// Ensure that mesh has at least 8 valid faces
|
||||
part.Shape.ProfileBegin = 12500;
|
||||
part.Shape.ProfileEnd = 0;
|
||||
part.Shape.ProfileHollow = 27500;
|
||||
}
|
||||
}
|
||||
|
||||
++updatesThisCall;
|
||||
|
@ -4952,6 +4960,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
|
||||
rotation = part.RotationOffset * presence.Rotation;
|
||||
}
|
||||
angularVelocity = Vector3.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
angularVelocity = presence.AngularVelocity;
|
||||
rotation = presence.Rotation;
|
||||
}
|
||||
|
||||
attachPoint = 0;
|
||||
|
@ -4963,9 +4977,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// in that direction, even though we don't model this on the server. Implementing this in the future
|
||||
// may improve movement smoothness.
|
||||
// acceleration = new Vector3(1, 0, 0);
|
||||
|
||||
angularVelocity = Vector3.Zero;
|
||||
|
||||
|
||||
if (sendTexture)
|
||||
textureEntry = presence.Appearance.Texture.GetBytes();
|
||||
else
|
||||
|
|
|
@ -1903,112 +1903,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoubleQueue<T> where T:class
|
||||
{
|
||||
private Queue<T> m_lowQueue = new Queue<T>();
|
||||
private Queue<T> m_highQueue = new Queue<T>();
|
||||
|
||||
private object m_syncRoot = new object();
|
||||
private Semaphore m_s = new Semaphore(0, 1);
|
||||
|
||||
public DoubleQueue()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Count
|
||||
{
|
||||
get { return m_highQueue.Count + m_lowQueue.Count; }
|
||||
}
|
||||
|
||||
public virtual void Enqueue(T data)
|
||||
{
|
||||
Enqueue(m_lowQueue, data);
|
||||
}
|
||||
|
||||
public virtual void EnqueueLow(T data)
|
||||
{
|
||||
Enqueue(m_lowQueue, data);
|
||||
}
|
||||
|
||||
public virtual void EnqueueHigh(T data)
|
||||
{
|
||||
Enqueue(m_highQueue, data);
|
||||
}
|
||||
|
||||
private void Enqueue(Queue<T> q, T data)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
m_lowQueue.Enqueue(data);
|
||||
m_s.WaitOne(0);
|
||||
m_s.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T Dequeue()
|
||||
{
|
||||
return Dequeue(Timeout.Infinite);
|
||||
}
|
||||
|
||||
public virtual T Dequeue(int tmo)
|
||||
{
|
||||
return Dequeue(TimeSpan.FromMilliseconds(tmo));
|
||||
}
|
||||
|
||||
public virtual T Dequeue(TimeSpan wait)
|
||||
{
|
||||
T res = null;
|
||||
|
||||
if (!Dequeue(wait, ref res))
|
||||
return null;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool Dequeue(int timeout, ref T res)
|
||||
{
|
||||
return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
|
||||
}
|
||||
|
||||
public bool Dequeue(TimeSpan wait, ref T res)
|
||||
{
|
||||
if (!m_s.WaitOne(wait))
|
||||
return false;
|
||||
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
if (m_highQueue.Count > 0)
|
||||
res = m_highQueue.Dequeue();
|
||||
else
|
||||
res = m_lowQueue.Dequeue();
|
||||
|
||||
if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
m_s.Release();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
// Make sure sem count is 0
|
||||
m_s.WaitOne(0);
|
||||
|
||||
m_lowQueue.Clear();
|
||||
m_highQueue.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -260,10 +260,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
{
|
||||
CompleteTaskItemUpdate(m_updateTaskItemData);
|
||||
}
|
||||
// else if (m_storeLocal)
|
||||
// {
|
||||
// m_Scene.AssetService.Store(m_asset);
|
||||
// }
|
||||
else if (m_asset.Local)
|
||||
{
|
||||
m_Scene.AssetService.Store(m_asset);
|
||||
}
|
||||
}
|
||||
|
||||
m_log.DebugFormat(
|
||||
|
@ -339,7 +339,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
// to avoid a race condition when the appearance module retrieves the item to set the asset id in
|
||||
// the AvatarAppearance structure.
|
||||
item.AssetID = m_asset.FullID;
|
||||
m_Scene.InventoryService.UpdateItem(item);
|
||||
if (item.AssetID != UUID.Zero)
|
||||
m_Scene.InventoryService.UpdateItem(item);
|
||||
|
||||
if (m_uploadState == UploadState.Complete)
|
||||
{
|
||||
|
@ -390,6 +391,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
// m_asset.FullID, item.Name, ourClient.Name);
|
||||
|
||||
m_Scene.AssetService.Store(m_asset);
|
||||
if (m_asset.FullID != UUID.Zero)
|
||||
{
|
||||
item.AssetID = m_asset.FullID;
|
||||
m_Scene.InventoryService.UpdateItem(item);
|
||||
}
|
||||
|
||||
m_transactions.RemoveXferUploader(m_transactionID);
|
||||
}
|
||||
|
|
|
@ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
AssetBase asset = null;
|
||||
|
||||
string filename = GetFileName(id);
|
||||
if (File.Exists(filename))
|
||||
while (File.Exists(filename))
|
||||
{
|
||||
FileStream stream = null;
|
||||
try
|
||||
|
@ -380,6 +380,8 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
asset = (AssetBase)bformatter.Deserialize(stream);
|
||||
|
||||
m_DiskHits++;
|
||||
|
||||
break;
|
||||
}
|
||||
catch (System.Runtime.Serialization.SerializationException e)
|
||||
{
|
||||
|
@ -392,12 +394,24 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
// {different version of AssetBase} -- we should attempt to
|
||||
// delete it and re-cache
|
||||
File.Delete(filename);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// This is a sharing violation: File exists but can't be opened because it's
|
||||
// being written
|
||||
Thread.Sleep(100);
|
||||
|
||||
continue;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
||||
filename, id, e.Message, e.StackTrace);
|
||||
|
||||
break;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -236,9 +236,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
// If we're an NPC then skip all the item checks and manipulations since we don't have an
|
||||
// inventory right now.
|
||||
if (sp.PresenceType == PresenceType.Npc)
|
||||
RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null);
|
||||
RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null, true);
|
||||
else
|
||||
RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d);
|
||||
RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80, d);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -284,12 +284,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
sp.ClearAttachments();
|
||||
}
|
||||
|
||||
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp)
|
||||
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append)
|
||||
{
|
||||
if (!Enabled)
|
||||
return false;
|
||||
|
||||
if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp))
|
||||
if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, append))
|
||||
{
|
||||
m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
|
||||
return true;
|
||||
|
@ -298,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp)
|
||||
private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append)
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
|
@ -326,10 +326,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
|
||||
Vector3 attachPos = group.AbsolutePosition;
|
||||
|
||||
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
||||
// be removed when that functionality is implemented in opensim
|
||||
attachmentPt &= 0x7f;
|
||||
|
||||
// If the attachment point isn't the same as the one previously used
|
||||
// set it's offset position = 0 so that it appears on the attachment point
|
||||
// and not in a weird location somewhere unknown.
|
||||
|
@ -375,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
group.AbsolutePosition = attachPos;
|
||||
|
||||
if (sp.PresenceType != PresenceType.Npc)
|
||||
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp);
|
||||
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
|
||||
|
||||
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
||||
}
|
||||
|
@ -383,21 +379,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
return true;
|
||||
}
|
||||
|
||||
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp)
|
||||
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
|
||||
{
|
||||
// Remove any previous attachments
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
||||
|
||||
// At the moment we can only deal with a single attachment
|
||||
if (attachments.Count != 0)
|
||||
// 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)
|
||||
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
|
||||
// Error logging commented because UUID.Zero now means temp attachment
|
||||
// else
|
||||
// m_log.WarnFormat(
|
||||
// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
||||
// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
||||
attachments.RemoveAt(0);
|
||||
}
|
||||
|
||||
// If we're not appending, remove the rest as well
|
||||
if (attachments.Count != 0 && !append)
|
||||
{
|
||||
foreach (SceneObjectGroup g in attachments)
|
||||
{
|
||||
if (g.FromItemID != UUID.Zero)
|
||||
DetachSingleAttachmentToInvInternal(sp, g);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new attachment to inventory if we don't already have it.
|
||||
|
@ -407,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
if (newAttachmentItemID == UUID.Zero)
|
||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||
|
||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,8 +426,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
|
||||
// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
|
||||
|
||||
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
||||
// be removed when that functionality is implemented in opensim
|
||||
bool append = (AttachmentPt & 0x80) != 0;
|
||||
AttachmentPt &= 0x7f;
|
||||
|
||||
// Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
|
||||
|
@ -455,7 +455,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
return null;
|
||||
}
|
||||
|
||||
return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
|
||||
return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc, append);
|
||||
}
|
||||
|
||||
public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
|
||||
|
@ -847,7 +847,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
}
|
||||
|
||||
protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
|
||||
IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
|
||||
IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append)
|
||||
{
|
||||
if (m_invAccessModule == null)
|
||||
return null;
|
||||
|
@ -885,7 +885,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
// This will throw if the attachment fails
|
||||
try
|
||||
{
|
||||
AttachObjectInternal(sp, objatt, attachmentPt, false, false, false);
|
||||
AttachObjectInternal(sp, objatt, attachmentPt, false, false, false, append);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -936,7 +936,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
/// <param name="AttachmentPt"></param>
|
||||
/// <param name="itemID"></param>
|
||||
/// <param name="att"></param>
|
||||
private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
|
||||
private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
|
||||
|
@ -959,7 +959,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
if (item == null)
|
||||
return;
|
||||
|
||||
bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
|
||||
int attFlag = append ? 0x80 : 0;
|
||||
bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
|
@ -1043,12 +1044,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
|
||||
// be removed when that functionality is implemented in opensim
|
||||
bool append = (AttachmentPt & 0x80) != 0;
|
||||
AttachmentPt &= 0x7f;
|
||||
|
||||
// Calls attach with a Zero position
|
||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false))
|
||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false, append))
|
||||
{
|
||||
// m_log.Debug(
|
||||
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||
|
|
|
@ -197,7 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
|||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
|
||||
|
||||
m_numberOfAttachEventsFired = 0;
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(sp.HasAttachments(), Is.True);
|
||||
|
@ -254,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
|||
sp2.AbsolutePosition = new Vector3(0, 0, 0);
|
||||
sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
|
||||
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false);
|
||||
|
||||
Assert.That(sp.HasAttachments(), Is.False);
|
||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
|
|
|
@ -674,26 +674,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
|
||||
{
|
||||
IInventoryService invService = m_scene.InventoryService;
|
||||
|
||||
bool resetwearable = false;
|
||||
if (invService.GetRootFolder(userID) != null)
|
||||
{
|
||||
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
|
||||
{
|
||||
for (int j = 0; j < appearance.Wearables[i].Count; j++)
|
||||
{
|
||||
// Check if the default wearables are not set
|
||||
if (appearance.Wearables[i][j].ItemID == UUID.Zero)
|
||||
continue;
|
||||
{
|
||||
switch ((WearableType) i)
|
||||
{
|
||||
case WearableType.Eyes:
|
||||
case WearableType.Hair:
|
||||
case WearableType.Shape:
|
||||
case WearableType.Skin:
|
||||
//case WearableType.Underpants:
|
||||
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
|
||||
resetwearable = true;
|
||||
break;
|
||||
|
||||
// Ignore ruth's assets
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
|
||||
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
|
||||
continue;
|
||||
{
|
||||
switch ((WearableType)i)
|
||||
{
|
||||
case WearableType.Eyes:
|
||||
case WearableType.Hair:
|
||||
case WearableType.Shape:
|
||||
case WearableType.Skin:
|
||||
//case WearableType.Underpants:
|
||||
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
|
||||
|
||||
m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
|
||||
resetwearable = true;
|
||||
break;
|
||||
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
|
||||
baseItem = invService.GetItem(baseItem);
|
||||
|
||||
if (baseItem != null)
|
||||
{
|
||||
appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
|
||||
int unmodifiedWearableIndexForClosure = i;
|
||||
m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
|
||||
delegate(string x, object y, AssetBase z)
|
||||
{
|
||||
if (z == null)
|
||||
{
|
||||
TryAndRepairBrokenWearable(
|
||||
(WearableType)unmodifiedWearableIndexForClosure, invService,
|
||||
userID, appearance);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -701,17 +745,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
"[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
|
||||
appearance.Wearables[i][j].ItemID, (WearableType)i);
|
||||
|
||||
appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
|
||||
TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
|
||||
if (appearance.Wearables[(int) WearableType.Eyes] == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
|
||||
|
||||
TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
|
||||
appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
|
||||
appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
|
||||
TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
|
||||
if (appearance.Wearables[(int)WearableType.Shape] == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
|
||||
|
||||
TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
|
||||
appearance.Wearables[(int)WearableType.Shape][0].ItemID,
|
||||
appearance.Wearables[(int)WearableType.Shape][0].AssetID);
|
||||
TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
|
||||
if (appearance.Wearables[(int)WearableType.Hair] == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
|
||||
|
||||
TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
|
||||
appearance.Wearables[(int)WearableType.Hair][0].ItemID,
|
||||
appearance.Wearables[(int)WearableType.Hair][0].AssetID);
|
||||
TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
|
||||
if (appearance.Wearables[(int)WearableType.Skin] == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
|
||||
|
||||
TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
|
||||
appearance.Wearables[(int)WearableType.Skin][0].ItemID,
|
||||
appearance.Wearables[(int)WearableType.Skin][0].AssetID);
|
||||
TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
|
||||
resetwearable = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (resetwearable)
|
||||
{
|
||||
ScenePresence presence = null;
|
||||
if (m_scene.TryGetScenePresence(userID, out presence))
|
||||
{
|
||||
presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
|
||||
presence.Appearance.Serial++);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
|
||||
}
|
||||
}
|
||||
private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
|
||||
{
|
||||
UUID defaultwearable = GetDefaultItem(type);
|
||||
if (defaultwearable != UUID.Zero)
|
||||
{
|
||||
UUID newInvItem = UUID.Random();
|
||||
InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID)
|
||||
{
|
||||
AssetID =
|
||||
defaultwearable,
|
||||
AssetType
|
||||
=
|
||||
(int)
|
||||
AssetType
|
||||
.Bodypart,
|
||||
CreatorId
|
||||
=
|
||||
userID
|
||||
.ToString
|
||||
(),
|
||||
//InvType = (int)InventoryType.Wearable,
|
||||
|
||||
Description
|
||||
=
|
||||
"Failed Wearable Replacement",
|
||||
Folder =
|
||||
invService
|
||||
.GetFolderForType
|
||||
(userID,
|
||||
AssetType
|
||||
.Bodypart)
|
||||
.ID,
|
||||
Flags = (uint) type,
|
||||
Name = Enum.GetName(typeof (WearableType), type),
|
||||
BasePermissions = (uint) PermissionMask.Copy,
|
||||
CurrentPermissions = (uint) PermissionMask.Copy,
|
||||
EveryOnePermissions = (uint) PermissionMask.Copy,
|
||||
GroupPermissions = (uint) PermissionMask.Copy,
|
||||
NextPermissions = (uint) PermissionMask.Copy
|
||||
};
|
||||
invService.AddItem(itembase);
|
||||
UUID LinkInvItem = UUID.Random();
|
||||
itembase = new InventoryItemBase(LinkInvItem, userID)
|
||||
{
|
||||
AssetID =
|
||||
newInvItem,
|
||||
AssetType
|
||||
=
|
||||
(int)
|
||||
AssetType
|
||||
.Link,
|
||||
CreatorId
|
||||
=
|
||||
userID
|
||||
.ToString
|
||||
(),
|
||||
InvType = (int) InventoryType.Wearable,
|
||||
|
||||
Description
|
||||
=
|
||||
"Failed Wearable Replacement",
|
||||
Folder =
|
||||
invService
|
||||
.GetFolderForType
|
||||
(userID,
|
||||
AssetType
|
||||
.CurrentOutfitFolder)
|
||||
.ID,
|
||||
Flags = (uint) type,
|
||||
Name = Enum.GetName(typeof (WearableType), type),
|
||||
BasePermissions = (uint) PermissionMask.Copy,
|
||||
CurrentPermissions = (uint) PermissionMask.Copy,
|
||||
EveryOnePermissions = (uint) PermissionMask.Copy,
|
||||
GroupPermissions = (uint) PermissionMask.Copy,
|
||||
NextPermissions = (uint) PermissionMask.Copy
|
||||
};
|
||||
invService.AddItem(itembase);
|
||||
appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type));
|
||||
ScenePresence presence = null;
|
||||
if (m_scene.TryGetScenePresence(userID, out presence))
|
||||
{
|
||||
m_scene.SendInventoryUpdate(presence.ControllingClient,
|
||||
invService.GetFolderForType(userID,
|
||||
AssetType
|
||||
.CurrentOutfitFolder),
|
||||
false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
private UUID GetDefaultItem(WearableType wearable)
|
||||
{
|
||||
// These are ruth
|
||||
UUID ret = UUID.Zero;
|
||||
switch (wearable)
|
||||
{
|
||||
case WearableType.Eyes:
|
||||
ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
|
||||
break;
|
||||
case WearableType.Hair:
|
||||
ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
|
||||
break;
|
||||
case WearableType.Pants:
|
||||
ret = new UUID("00000000-38f9-1111-024e-222222111120");
|
||||
break;
|
||||
case WearableType.Shape:
|
||||
ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
|
||||
break;
|
||||
case WearableType.Shirt:
|
||||
ret = new UUID("00000000-38f9-1111-024e-222222111110");
|
||||
break;
|
||||
case WearableType.Skin:
|
||||
ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
|
||||
break;
|
||||
case WearableType.Undershirt:
|
||||
ret = new UUID("16499ebb-3208-ec27-2def-481881728f47");
|
||||
break;
|
||||
case WearableType.Underpants:
|
||||
ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d");
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Client Event Handlers
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
/// <summary>
|
||||
/// Each agent has its own capabilities handler.
|
||||
/// </summary>
|
||||
protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>();
|
||||
protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
|
||||
|
||||
protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>();
|
||||
protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
|
||||
|
@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
get { return null; }
|
||||
}
|
||||
|
||||
public void CreateCaps(UUID agentId)
|
||||
public void CreateCaps(UUID agentId, uint circuitCode)
|
||||
{
|
||||
int flags = m_scene.GetUserFlags(agentId);
|
||||
if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
|
||||
|
@ -108,9 +108,9 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
|
||||
String capsObjectPath = GetCapsPath(agentId);
|
||||
|
||||
if (m_capsObjects.ContainsKey(agentId))
|
||||
if (m_capsObjects.ContainsKey(circuitCode))
|
||||
{
|
||||
Caps oldCaps = m_capsObjects[agentId];
|
||||
Caps oldCaps = m_capsObjects[circuitCode];
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ",
|
||||
|
@ -125,12 +125,12 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
(MainServer.Instance == null) ? 0: MainServer.Instance.Port,
|
||||
capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
|
||||
|
||||
m_capsObjects[agentId] = caps;
|
||||
m_capsObjects[circuitCode] = caps;
|
||||
|
||||
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
|
||||
}
|
||||
|
||||
public void RemoveCaps(UUID agentId)
|
||||
public void RemoveCaps(UUID agentId, uint circuitCode)
|
||||
{
|
||||
if (childrenSeeds.ContainsKey(agentId))
|
||||
{
|
||||
|
@ -139,11 +139,11 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
|
||||
lock (m_capsObjects)
|
||||
{
|
||||
if (m_capsObjects.ContainsKey(agentId))
|
||||
if (m_capsObjects.ContainsKey(circuitCode))
|
||||
{
|
||||
m_capsObjects[agentId].DeregisterHandlers();
|
||||
m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]);
|
||||
m_capsObjects.Remove(agentId);
|
||||
m_capsObjects[circuitCode].DeregisterHandlers();
|
||||
m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
|
||||
m_capsObjects.Remove(circuitCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -154,19 +154,30 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public Caps GetCapsForUser(UUID agentId)
|
||||
public Caps GetCapsForUser(uint circuitCode)
|
||||
{
|
||||
lock (m_capsObjects)
|
||||
{
|
||||
if (m_capsObjects.ContainsKey(agentId))
|
||||
if (m_capsObjects.ContainsKey(circuitCode))
|
||||
{
|
||||
return m_capsObjects[agentId];
|
||||
return m_capsObjects[circuitCode];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ActivateCaps(uint circuitCode)
|
||||
{
|
||||
lock (m_capsObjects)
|
||||
{
|
||||
if (m_capsObjects.ContainsKey(circuitCode))
|
||||
{
|
||||
m_capsObjects[circuitCode].Activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAgentCapsSeeds(AgentCircuitData agent)
|
||||
{
|
||||
capsPaths[agent.AgentID] = agent.CapsPath;
|
||||
|
@ -237,9 +248,9 @@ namespace OpenSim.Region.CoreModules.Framework
|
|||
StringBuilder caps = new StringBuilder();
|
||||
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
||||
|
||||
foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects)
|
||||
foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
|
||||
{
|
||||
caps.AppendFormat("** User {0}:\n", kvp.Key);
|
||||
caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
|
||||
|
||||
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); )
|
||||
{
|
||||
|
|
|
@ -150,7 +150,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
{
|
||||
client.OnTeleportHomeRequest += TriggerTeleportHome;
|
||||
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
||||
client.OnTeleportCancel += TeleportCancel;
|
||||
}
|
||||
|
||||
public virtual void Close() {}
|
||||
|
@ -995,11 +994,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
return neighbourRegion;
|
||||
}
|
||||
|
||||
private void TeleportCancel(IClientAPI remoteClient)
|
||||
{
|
||||
m_entityTransferStateMachine.ResetFromTransit(remoteClient.AgentId);
|
||||
}
|
||||
|
||||
public bool Cross(ScenePresence agent, bool isFlying)
|
||||
{
|
||||
uint x;
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
|||
public string url;
|
||||
public UUID urlcode;
|
||||
public Dictionary<UUID, RequestData> requests;
|
||||
public bool isSsl;
|
||||
}
|
||||
|
||||
public class RequestData
|
||||
|
@ -184,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
|||
urlData.engine = engine;
|
||||
urlData.url = url;
|
||||
urlData.urlcode = urlcode;
|
||||
urlData.isSsl = false;
|
||||
urlData.requests = new Dictionary<UUID, RequestData>();
|
||||
|
||||
m_UrlMap[url] = urlData;
|
||||
|
@ -229,6 +231,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
|||
urlData.engine = engine;
|
||||
urlData.url = url;
|
||||
urlData.urlcode = urlcode;
|
||||
urlData.isSsl = true;
|
||||
urlData.requests = new Dictionary<UUID, RequestData>();
|
||||
|
||||
|
||||
|
@ -394,7 +397,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
|||
|
||||
private void RemoveUrl(UrlData data)
|
||||
{
|
||||
m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
|
||||
if (data.isSsl)
|
||||
m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
|
||||
else
|
||||
m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
|
||||
}
|
||||
|
||||
private Hashtable NoEvents(UUID requestID, UUID sessionID)
|
||||
|
|
|
@ -262,6 +262,8 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
|
|||
return "modInvokeR";
|
||||
else if (sid.ReturnType == typeof(object[]))
|
||||
return "modInvokeL";
|
||||
else if (sid.ReturnType == typeof(void))
|
||||
return "modInvokeN";
|
||||
|
||||
m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <param name="AttachmentPt"></param>
|
||||
/// <param name="silent"></param>
|
||||
/// <returns>true if the object was successfully attached, false otherwise</returns>
|
||||
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo, bool temp);
|
||||
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo, bool temp, bool append);
|
||||
|
||||
/// <summary>
|
||||
/// Rez an attachment from user inventory and change inventory status to match.
|
||||
|
|
|
@ -40,19 +40,19 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
/// <param name="capsObjectPath"></param>
|
||||
void CreateCaps(UUID agentId);
|
||||
void CreateCaps(UUID agentId, uint circuitCode);
|
||||
|
||||
/// <summary>
|
||||
/// Remove the caps handler for a given agent.
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
void RemoveCaps(UUID agentId);
|
||||
void RemoveCaps(UUID agentId, uint circuitCode);
|
||||
|
||||
/// <summary>
|
||||
/// Will return null if the agent doesn't have a caps handler registered
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
Caps GetCapsForUser(UUID agentId);
|
||||
Caps GetCapsForUser(uint circuitCode);
|
||||
|
||||
void SetAgentCapsSeeds(AgentCircuitData agent);
|
||||
|
||||
|
@ -65,5 +65,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
void DropChildSeed(UUID agentID, ulong handle);
|
||||
|
||||
string GetCapsPath(UUID agentId);
|
||||
|
||||
void ActivateCaps(uint circuitCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,18 +26,22 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
namespace OpenSim.Region.Framework.Interfaces
|
||||
{
|
||||
public delegate void SimulatorFeaturesRequestDelegate(UUID agentID, ref OSDMap features);
|
||||
|
||||
/// <summary>
|
||||
/// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability.
|
||||
/// </summary>
|
||||
public interface ISimulatorFeaturesModule
|
||||
{
|
||||
event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
|
||||
void AddFeature(string name, OSD value);
|
||||
bool RemoveFeature(string name);
|
||||
bool TryGetFeature(string name, out OSD value);
|
||||
OSDMap GetFeatures();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,115 @@ using log4net;
|
|||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
public class KeyframeTimer
|
||||
{
|
||||
private static Dictionary<Scene, KeyframeTimer>m_timers =
|
||||
new Dictionary<Scene, KeyframeTimer>();
|
||||
|
||||
private Timer m_timer;
|
||||
private Dictionary<KeyframeMotion, object> m_motions = new Dictionary<KeyframeMotion, object>();
|
||||
private object m_lockObject = new object();
|
||||
private object m_timerLock = new object();
|
||||
private const double m_tickDuration = 50.0;
|
||||
private Scene m_scene;
|
||||
|
||||
public double TickDuration
|
||||
{
|
||||
get { return m_tickDuration; }
|
||||
}
|
||||
|
||||
public KeyframeTimer(Scene scene)
|
||||
{
|
||||
m_timer = new Timer();
|
||||
m_timer.Interval = TickDuration;
|
||||
m_timer.AutoReset = true;
|
||||
m_timer.Elapsed += OnTimer;
|
||||
|
||||
m_scene = scene;
|
||||
|
||||
m_timer.Start();
|
||||
}
|
||||
|
||||
private void OnTimer(object sender, ElapsedEventArgs ea)
|
||||
{
|
||||
if (!Monitor.TryEnter(m_timerLock))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
List<KeyframeMotion> motions;
|
||||
|
||||
lock (m_lockObject)
|
||||
{
|
||||
motions = new List<KeyframeMotion>(m_motions.Keys);
|
||||
}
|
||||
|
||||
foreach (KeyframeMotion m in motions)
|
||||
{
|
||||
try
|
||||
{
|
||||
m.OnTimer(TickDuration);
|
||||
}
|
||||
catch (Exception inner)
|
||||
{
|
||||
// Don't stop processing
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Keep running no matter what
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(m_timerLock);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Add(KeyframeMotion motion)
|
||||
{
|
||||
KeyframeTimer timer;
|
||||
|
||||
if (motion.Scene == null)
|
||||
return;
|
||||
|
||||
lock (m_timers)
|
||||
{
|
||||
if (!m_timers.TryGetValue(motion.Scene, out timer))
|
||||
{
|
||||
timer = new KeyframeTimer(motion.Scene);
|
||||
m_timers[motion.Scene] = timer;
|
||||
}
|
||||
}
|
||||
|
||||
lock (timer.m_lockObject)
|
||||
{
|
||||
timer.m_motions[motion] = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Remove(KeyframeMotion motion)
|
||||
{
|
||||
KeyframeTimer timer;
|
||||
|
||||
if (motion.Scene == null)
|
||||
return;
|
||||
|
||||
lock (m_timers)
|
||||
{
|
||||
if (!m_timers.TryGetValue(motion.Scene, out timer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lock (timer.m_lockObject)
|
||||
{
|
||||
timer.m_motions.Remove(motion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class KeyframeMotion
|
||||
{
|
||||
|
@ -63,18 +172,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
private Keyframe[] m_keyframes;
|
||||
|
||||
[NonSerialized()]
|
||||
protected Timer m_timer = null;
|
||||
|
||||
// timer lock
|
||||
[NonSerialized()]
|
||||
private object m_onTimerLock;
|
||||
|
||||
// timer overrun detect
|
||||
// prevents overlap or timer events threads frozen on the lock
|
||||
[NonSerialized()]
|
||||
private bool m_inOnTimer;
|
||||
|
||||
// skip timer events.
|
||||
//timer.stop doesn't assure there aren't event threads still being fired
|
||||
[NonSerialized()]
|
||||
|
@ -97,12 +194,21 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation;
|
||||
|
||||
private bool m_running = false;
|
||||
|
||||
[NonSerialized()]
|
||||
private bool m_selected = false;
|
||||
|
||||
private int m_iterations = 0;
|
||||
|
||||
private const double timerInterval = 50.0;
|
||||
private int m_skipLoops = 0;
|
||||
|
||||
[NonSerialized()]
|
||||
private Scene m_scene;
|
||||
|
||||
public Scene Scene
|
||||
{
|
||||
get { return m_scene; }
|
||||
}
|
||||
|
||||
public DataFormat Data
|
||||
{
|
||||
|
@ -139,31 +245,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
private void StartTimer()
|
||||
{
|
||||
if (m_timer == null)
|
||||
return;
|
||||
KeyframeTimer.Add(this);
|
||||
m_timerStopped = false;
|
||||
m_timer.Start();
|
||||
}
|
||||
|
||||
private void StopTimer()
|
||||
{
|
||||
if (m_timer == null || m_timerStopped)
|
||||
return;
|
||||
m_timerStopped = true;
|
||||
m_timer.Stop();
|
||||
KeyframeTimer.Remove(this);
|
||||
}
|
||||
|
||||
private void RemoveTimer()
|
||||
{
|
||||
if (m_timer == null)
|
||||
return;
|
||||
m_timerStopped = true;
|
||||
m_timer.Stop();
|
||||
m_timer.Elapsed -= OnTimer;
|
||||
m_timer = null;
|
||||
}
|
||||
|
||||
|
||||
public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data)
|
||||
{
|
||||
KeyframeMotion newMotion = null;
|
||||
|
@ -177,12 +268,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
newMotion.m_group = grp;
|
||||
|
||||
if (grp != null && grp.IsSelected)
|
||||
newMotion.m_selected = true;
|
||||
if (grp != null)
|
||||
{
|
||||
newMotion.m_scene = grp.Scene;
|
||||
if (grp.IsSelected)
|
||||
newMotion.m_selected = true;
|
||||
}
|
||||
|
||||
newMotion.m_onTimerLock = new object();
|
||||
newMotion.m_timerStopped = false;
|
||||
newMotion.m_inOnTimer = false;
|
||||
newMotion.m_running = true;
|
||||
newMotion.m_isCrossing = false;
|
||||
newMotion.m_waitingCrossing = false;
|
||||
}
|
||||
|
@ -196,37 +290,36 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void UpdateSceneObject(SceneObjectGroup grp)
|
||||
{
|
||||
// lock (m_onTimerLock)
|
||||
m_isCrossing = false;
|
||||
m_waitingCrossing = false;
|
||||
StopTimer();
|
||||
|
||||
if (grp == null)
|
||||
return;
|
||||
|
||||
m_group = grp;
|
||||
m_scene = grp.Scene;
|
||||
|
||||
Vector3 grppos = grp.AbsolutePosition;
|
||||
Vector3 offset = grppos - m_serializedPosition;
|
||||
// avoid doing it more than once
|
||||
// current this will happen draging a prim to other region
|
||||
m_serializedPosition = grppos;
|
||||
|
||||
m_basePosition += offset;
|
||||
m_currentFrame.Position += offset;
|
||||
|
||||
m_nextPosition += offset;
|
||||
|
||||
for (int i = 0; i < m_frames.Count; i++)
|
||||
{
|
||||
m_isCrossing = false;
|
||||
m_waitingCrossing = false;
|
||||
StopTimer();
|
||||
|
||||
if (grp == null)
|
||||
return;
|
||||
|
||||
m_group = grp;
|
||||
Vector3 grppos = grp.AbsolutePosition;
|
||||
Vector3 offset = grppos - m_serializedPosition;
|
||||
// avoid doing it more than once
|
||||
// current this will happen draging a prim to other region
|
||||
m_serializedPosition = grppos;
|
||||
|
||||
m_basePosition += offset;
|
||||
m_currentFrame.Position += offset;
|
||||
|
||||
m_nextPosition += offset;
|
||||
|
||||
for (int i = 0; i < m_frames.Count; i++)
|
||||
{
|
||||
Keyframe k = m_frames[i];
|
||||
k.Position += offset;
|
||||
m_frames[i]=k;
|
||||
}
|
||||
|
||||
if (m_running)
|
||||
Start();
|
||||
Keyframe k = m_frames[i];
|
||||
k.Position += offset;
|
||||
m_frames[i]=k;
|
||||
}
|
||||
|
||||
if (m_running)
|
||||
Start();
|
||||
}
|
||||
|
||||
public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data)
|
||||
|
@ -239,11 +332,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_basePosition = grp.AbsolutePosition;
|
||||
m_baseRotation = grp.GroupRotation;
|
||||
m_scene = grp.Scene;
|
||||
}
|
||||
|
||||
m_onTimerLock = new object();
|
||||
m_timerStopped = true;
|
||||
m_inOnTimer = false;
|
||||
m_isCrossing = false;
|
||||
m_waitingCrossing = false;
|
||||
}
|
||||
|
@ -260,6 +352,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data);
|
||||
|
||||
newmotion.m_group = newgrp;
|
||||
newmotion.m_scene = newgrp.Scene;
|
||||
|
||||
if (m_keyframes != null)
|
||||
{
|
||||
|
@ -296,7 +389,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public void Delete()
|
||||
{
|
||||
m_running = false;
|
||||
RemoveTimer();
|
||||
StopTimer();
|
||||
m_isCrossing = false;
|
||||
m_waitingCrossing = false;
|
||||
m_frames.Clear();
|
||||
|
@ -309,27 +402,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_waitingCrossing = false;
|
||||
if (m_keyframes != null && m_group != null && m_keyframes.Length > 0)
|
||||
{
|
||||
if (m_timer == null)
|
||||
{
|
||||
m_timer = new Timer();
|
||||
m_timer.Interval = timerInterval;
|
||||
m_timer.AutoReset = true;
|
||||
m_timer.Elapsed += OnTimer;
|
||||
}
|
||||
else
|
||||
{
|
||||
StopTimer();
|
||||
m_timer.Interval = timerInterval;
|
||||
}
|
||||
|
||||
m_inOnTimer = false;
|
||||
StartTimer();
|
||||
m_running = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_running = false;
|
||||
RemoveTimer();
|
||||
StopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,7 +418,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_isCrossing = false;
|
||||
m_waitingCrossing = false;
|
||||
|
||||
RemoveTimer();
|
||||
StopTimer();
|
||||
|
||||
m_basePosition = m_group.AbsolutePosition;
|
||||
m_baseRotation = m_group.GroupRotation;
|
||||
|
@ -354,7 +433,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public void Pause()
|
||||
{
|
||||
m_running = false;
|
||||
RemoveTimer();
|
||||
StopTimer();
|
||||
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
|
@ -377,15 +456,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
int start = 0;
|
||||
int end = m_keyframes.Length;
|
||||
// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
|
||||
// end = m_keyframes.Length - 1;
|
||||
|
||||
if (direction < 0)
|
||||
{
|
||||
start = m_keyframes.Length - 1;
|
||||
end = -1;
|
||||
// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
|
||||
// end = 0;
|
||||
}
|
||||
|
||||
for (int i = start; i != end ; i += direction)
|
||||
|
@ -463,189 +538,172 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
protected void OnTimer(object sender, ElapsedEventArgs e)
|
||||
public void OnTimer(double tickDuration)
|
||||
{
|
||||
if (m_timerStopped) // trap events still in air even after a timer.stop
|
||||
return;
|
||||
|
||||
if (m_inOnTimer) // don't let overruns to happen
|
||||
if (m_skipLoops > 0)
|
||||
{
|
||||
m_log.Warn("[KeyFrame]: timer overrun");
|
||||
m_skipLoops--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_timerStopped) // trap events still in air even after a timer.stop
|
||||
return;
|
||||
|
||||
if (m_group == null)
|
||||
return;
|
||||
|
||||
lock (m_onTimerLock)
|
||||
bool update = false;
|
||||
|
||||
if (m_selected)
|
||||
{
|
||||
|
||||
m_inOnTimer = true;
|
||||
|
||||
bool update = false;
|
||||
|
||||
try
|
||||
if (m_group.RootPart.Velocity != Vector3.Zero)
|
||||
{
|
||||
if (m_selected)
|
||||
{
|
||||
if (m_group.RootPart.Velocity != Vector3.Zero)
|
||||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
|
||||
}
|
||||
m_inOnTimer = false;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_isCrossing)
|
||||
{
|
||||
// if crossing and timer running then cross failed
|
||||
// wait some time then
|
||||
// retry to set the position that evtually caused the outbound
|
||||
// if still outside region this will call startCrossing below
|
||||
m_isCrossing = false;
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
if (!m_isCrossing)
|
||||
{
|
||||
StopTimer();
|
||||
StartTimer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_frames.Count == 0)
|
||||
{
|
||||
GetNextList();
|
||||
|
||||
if (m_frames.Count == 0)
|
||||
{
|
||||
Stop();
|
||||
Scene scene = m_group.Scene;
|
||||
|
||||
IScriptModule[] scriptModules = scene.RequestModuleInterfaces<IScriptModule>();
|
||||
foreach (IScriptModule m in scriptModules)
|
||||
{
|
||||
if (m == null)
|
||||
continue;
|
||||
m.PostObjectEvent(m_group.RootPart.UUID, "moving_end", new object[0]);
|
||||
}
|
||||
|
||||
if (m_isCrossing)
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentFrame = m_frames[0];
|
||||
m_currentFrame.TimeMS += (int)tickDuration;
|
||||
|
||||
//force a update on a keyframe transition
|
||||
update = true;
|
||||
}
|
||||
|
||||
m_currentFrame.TimeMS -= (int)tickDuration;
|
||||
|
||||
// Do the frame processing
|
||||
double steps = (double)m_currentFrame.TimeMS / tickDuration;
|
||||
|
||||
if (steps <= 0.0)
|
||||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
|
||||
m_nextPosition = (Vector3)m_currentFrame.Position;
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
|
||||
// we are sending imediate updates, no doing force a extra terseUpdate
|
||||
// m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation);
|
||||
|
||||
m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation;
|
||||
m_frames.RemoveAt(0);
|
||||
if (m_frames.Count > 0)
|
||||
m_currentFrame = m_frames[0];
|
||||
|
||||
update = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal;
|
||||
|
||||
Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition;
|
||||
Vector3 motionThisFrame = v / (float)steps;
|
||||
v = v * 1000 / m_currentFrame.TimeMS;
|
||||
|
||||
if (Vector3.Mag(motionThisFrame) >= 0.05f)
|
||||
{
|
||||
// m_group.AbsolutePosition += motionThisFrame;
|
||||
m_nextPosition = m_group.AbsolutePosition + motionThisFrame;
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
|
||||
m_group.RootPart.Velocity = v;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation)
|
||||
{
|
||||
Quaternion current = m_group.GroupRotation;
|
||||
|
||||
Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete);
|
||||
step.Normalize();
|
||||
/* use simpler change detection
|
||||
* float angle = 0;
|
||||
|
||||
float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W;
|
||||
float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
|
||||
float aa_bb = aa * bb;
|
||||
|
||||
if (aa_bb == 0)
|
||||
{
|
||||
// if crossing and timer running then cross failed
|
||||
// wait some time then
|
||||
// retry to set the position that evtually caused the outbound
|
||||
// if still outside region this will call startCrossing below
|
||||
m_isCrossing = false;
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
if (!m_isCrossing)
|
||||
{
|
||||
StopTimer();
|
||||
m_timer.Interval = timerInterval;
|
||||
StartTimer();
|
||||
}
|
||||
m_inOnTimer = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_frames.Count == 0)
|
||||
{
|
||||
GetNextList();
|
||||
|
||||
if (m_frames.Count == 0)
|
||||
{
|
||||
Stop();
|
||||
m_inOnTimer = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentFrame = m_frames[0];
|
||||
m_currentFrame.TimeMS += (int)timerInterval;
|
||||
|
||||
//force a update on a keyframe transition
|
||||
update = true;
|
||||
}
|
||||
|
||||
m_currentFrame.TimeMS -= (int)timerInterval;
|
||||
|
||||
// Do the frame processing
|
||||
double steps = (double)m_currentFrame.TimeMS / timerInterval;
|
||||
|
||||
if (steps <= 0.0)
|
||||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
m_group.RootPart.AngularVelocity = Vector3.Zero;
|
||||
|
||||
m_nextPosition = (Vector3)m_currentFrame.Position;
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
|
||||
// we are sending imediate updates, no doing force a extra terseUpdate
|
||||
// m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation);
|
||||
|
||||
m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation;
|
||||
m_frames.RemoveAt(0);
|
||||
if (m_frames.Count > 0)
|
||||
m_currentFrame = m_frames[0];
|
||||
|
||||
update = true;
|
||||
angle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal;
|
||||
float ab = current.X * step.X +
|
||||
current.Y * step.Y +
|
||||
current.Z * step.Z +
|
||||
current.W * step.W;
|
||||
float q = (ab * ab) / aa_bb;
|
||||
|
||||
Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition;
|
||||
Vector3 motionThisFrame = v / (float)steps;
|
||||
v = v * 1000 / m_currentFrame.TimeMS;
|
||||
|
||||
if (Vector3.Mag(motionThisFrame) >= 0.05f)
|
||||
if (q > 1.0f)
|
||||
{
|
||||
// m_group.AbsolutePosition += motionThisFrame;
|
||||
m_nextPosition = m_group.AbsolutePosition + motionThisFrame;
|
||||
m_group.AbsolutePosition = m_nextPosition;
|
||||
|
||||
m_group.RootPart.Velocity = v;
|
||||
update = true;
|
||||
angle = 0;
|
||||
}
|
||||
|
||||
if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation)
|
||||
else
|
||||
{
|
||||
Quaternion current = m_group.GroupRotation;
|
||||
|
||||
Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete);
|
||||
step.Normalize();
|
||||
/* use simpler change detection
|
||||
* float angle = 0;
|
||||
|
||||
float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W;
|
||||
float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
|
||||
float aa_bb = aa * bb;
|
||||
|
||||
if (aa_bb == 0)
|
||||
{
|
||||
angle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float ab = current.X * step.X +
|
||||
current.Y * step.Y +
|
||||
current.Z * step.Z +
|
||||
current.W * step.W;
|
||||
float q = (ab * ab) / aa_bb;
|
||||
|
||||
if (q > 1.0f)
|
||||
{
|
||||
angle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = (float)Math.Acos(2 * q - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (angle > 0.01f)
|
||||
*/
|
||||
if(Math.Abs(step.X - current.X) > 0.001f
|
||||
|| Math.Abs(step.Y - current.Y) > 0.001f
|
||||
|| Math.Abs(step.Z - current.Z) > 0.001f)
|
||||
// assuming w is a dependente var
|
||||
|
||||
{
|
||||
// m_group.UpdateGroupRotationR(step);
|
||||
m_group.RootPart.RotationOffset = step;
|
||||
|
||||
//m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2);
|
||||
update = true;
|
||||
}
|
||||
angle = (float)Math.Acos(2 * q - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
if (angle > 0.01f)
|
||||
*/
|
||||
if(Math.Abs(step.X - current.X) > 0.001f
|
||||
|| Math.Abs(step.Y - current.Y) > 0.001f
|
||||
|| Math.Abs(step.Z - current.Z) > 0.001f)
|
||||
// assuming w is a dependente var
|
||||
|
||||
{
|
||||
// m_group.UpdateGroupRotationR(step);
|
||||
m_group.RootPart.RotationOffset = step;
|
||||
|
||||
//m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2);
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
catch ( Exception ex)
|
||||
{
|
||||
// still happening sometimes
|
||||
// lets try to see where
|
||||
m_log.Warn("[KeyFrame]: timer overrun" + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
finally
|
||||
{
|
||||
// make sure we do not let this frozen
|
||||
m_inOnTimer = false;
|
||||
}
|
||||
if (update)
|
||||
{
|
||||
m_group.SendGroupRootTerseUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,7 +735,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_isCrossing = true;
|
||||
m_waitingCrossing = true;
|
||||
|
||||
// to remove / retune to smoth crossings
|
||||
// to remove / retune to smoth crossings
|
||||
if (m_group.RootPart.Velocity != Vector3.Zero)
|
||||
{
|
||||
m_group.RootPart.Velocity = Vector3.Zero;
|
||||
|
@ -696,9 +754,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_group.SendGroupRootTerseUpdate();
|
||||
// m_group.RootPart.ScheduleTerseUpdate();
|
||||
|
||||
if (m_running && m_timer != null)
|
||||
if (m_running)
|
||||
{
|
||||
m_timer.Interval = 60000;
|
||||
StopTimer();
|
||||
m_skipLoops = 1200; // 60 seconds
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -401,17 +401,17 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (item.Owner != remoteClient.AgentId)
|
||||
return;
|
||||
|
||||
if (UUID.Zero == transactionID)
|
||||
{
|
||||
item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
|
||||
item.Name = itemUpd.Name;
|
||||
item.Description = itemUpd.Description;
|
||||
item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
|
||||
item.Name = itemUpd.Name;
|
||||
item.Description = itemUpd.Description;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
|
||||
// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
|
||||
// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
|
||||
|
||||
if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid
|
||||
{
|
||||
if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
|
||||
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
|
||||
item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
|
||||
|
@ -446,7 +446,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
InventoryService.UpdateItem(item);
|
||||
}
|
||||
else
|
||||
|
||||
if (UUID.Zero != transactionID)
|
||||
{
|
||||
if (AgentTransactionsModule != null)
|
||||
{
|
||||
|
|
|
@ -2769,8 +2769,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (newPosition != Vector3.Zero)
|
||||
newObject.RootPart.GroupPosition = newPosition;
|
||||
if (newObject.RootPart.KeyframeMotion != null)
|
||||
newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
|
||||
|
||||
if (!AddSceneObject(newObject))
|
||||
{
|
||||
|
@ -2798,6 +2796,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// before we restart the scripts, or else some functions won't work.
|
||||
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
|
||||
newObject.ResumeScripts();
|
||||
|
||||
if (newObject.RootPart.KeyframeMotion != null)
|
||||
newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
|
||||
}
|
||||
|
||||
// Do this as late as possible so that listeners have full access to the incoming object
|
||||
|
@ -2865,7 +2866,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
|
||||
if (AttachmentsModule != null)
|
||||
AttachmentsModule.AttachObject(sp, grp, 0, false, false, false);
|
||||
AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2970,6 +2971,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
SubscribeToClientEvents(client);
|
||||
|
||||
sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
|
||||
InventoryFolderBase cof = InventoryService.GetFolderForType(client.AgentId, (AssetType)46);
|
||||
if (cof == null)
|
||||
sp.COF = UUID.Zero;
|
||||
else
|
||||
sp.COF = cof.ID;
|
||||
|
||||
m_log.DebugFormat("[SCENE]: COF for {0} is {1}", client.AgentId, sp.COF);
|
||||
m_eventManager.TriggerOnNewPresence(sp);
|
||||
|
||||
sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
|
||||
|
@ -3615,7 +3623,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
|
||||
// unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
|
||||
if (closeChildAgents && CapsModule != null)
|
||||
CapsModule.RemoveCaps(agentID);
|
||||
CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode);
|
||||
|
||||
// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
|
||||
// // this method is doing is HORRIBLE!!!
|
||||
|
@ -3846,20 +3854,36 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
ScenePresence sp = GetScenePresence(agent.AgentID);
|
||||
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
// If we have noo presence here or if that presence is a zombie root
|
||||
// presence that will be kicled, we need a new CAPS object.
|
||||
if (sp == null || (sp != null && !sp.IsChildAgent))
|
||||
{
|
||||
// We have a zombie from a crashed session.
|
||||
// Or the same user is trying to be root twice here, won't work.
|
||||
// Kill it.
|
||||
m_log.WarnFormat(
|
||||
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
|
||||
sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||
if (CapsModule != null)
|
||||
{
|
||||
lock (agent)
|
||||
{
|
||||
CapsModule.SetAgentCapsSeeds(agent);
|
||||
CapsModule.CreateCaps(agent.AgentID, agent.circuitcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sp.ControllingClient.Close(true, true);
|
||||
sp = null;
|
||||
if (sp != null)
|
||||
{
|
||||
if (!sp.IsChildAgent)
|
||||
{
|
||||
// We have a zombie from a crashed session.
|
||||
// Or the same user is trying to be root twice here, won't work.
|
||||
// Kill it.
|
||||
m_log.WarnFormat(
|
||||
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
|
||||
sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||
|
||||
sp.ControllingClient.Close(true, true);
|
||||
sp = null;
|
||||
}
|
||||
}
|
||||
|
||||
lock (agent)
|
||||
|
@ -3900,7 +3924,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (vialogin || (!m_seeIntoBannedRegion))
|
||||
{
|
||||
if (!AuthorizeUser(agent, out reason))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -3915,11 +3941,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
|
||||
agent.AgentID, agent.circuitcode);
|
||||
|
||||
if (CapsModule != null)
|
||||
{
|
||||
CapsModule.SetAgentCapsSeeds(agent);
|
||||
CapsModule.CreateCaps(agent.AgentID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3945,6 +3966,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
agent.teleportFlags = teleportFlags;
|
||||
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
|
||||
|
||||
if (CapsModule != null)
|
||||
{
|
||||
CapsModule.ActivateCaps(agent.circuitcode);
|
||||
}
|
||||
|
||||
if (vialogin)
|
||||
{
|
||||
// CleanDroppedAttachments();
|
||||
|
@ -5122,7 +5148,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
|
||||
{
|
||||
if (grp.RootPart.Expires <= DateTime.Now)
|
||||
if (grp.GetSittingAvatarsCount() == 0 && grp.RootPart.Expires <= DateTime.Now)
|
||||
DeleteSceneObject(grp, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1689,6 +1689,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (ParentGroup != null)
|
||||
ParentGroup.HasGroupChanged = true;
|
||||
|
||||
PhysicsActor pa = PhysActor;
|
||||
if (pa != null)
|
||||
pa.Density = Density;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1708,6 +1712,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (ParentGroup != null)
|
||||
ParentGroup.HasGroupChanged = true;
|
||||
|
||||
PhysicsActor pa = PhysActor;
|
||||
if (pa != null)
|
||||
pa.GravModifier = GravityModifier;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1726,10 +1733,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (ParentGroup != null)
|
||||
ParentGroup.HasGroupChanged = true;
|
||||
|
||||
PhysicsActor pa = PhysActor;
|
||||
if (pa != null)
|
||||
pa.Friction = Friction;
|
||||
}
|
||||
}
|
||||
|
||||
public float Bounciness
|
||||
public float Restitution
|
||||
{
|
||||
get { return m_bounce; }
|
||||
set
|
||||
|
@ -1744,6 +1755,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (ParentGroup != null)
|
||||
ParentGroup.HasGroupChanged = true;
|
||||
|
||||
PhysicsActor pa = PhysActor;
|
||||
if (pa != null)
|
||||
pa.Restitution = Restitution;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4493,8 +4508,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
GravityModifier = physdata.GravitationModifier;
|
||||
if(Friction != physdata.Friction)
|
||||
Friction = physdata.Friction;
|
||||
if(Bounciness != physdata.Bounce)
|
||||
Bounciness = physdata.Bounce;
|
||||
if(Restitution != physdata.Bounce)
|
||||
Restitution = physdata.Bounce;
|
||||
}
|
||||
/// <summary>
|
||||
/// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
|
||||
|
@ -4657,6 +4672,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
|
||||
pa.SetMaterial(Material);
|
||||
|
||||
pa.Density = Density;
|
||||
pa.GravModifier = GravityModifier;
|
||||
pa.Friction = Friction;
|
||||
pa.Restitution = Restitution;
|
||||
|
||||
if (VolumeDetectActive) // change if not the default only
|
||||
pa.SetVolumeDetect(1);
|
||||
|
||||
|
|
|
@ -204,6 +204,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
private const int LAND_VELOCITYMAG_MAX = 12;
|
||||
|
||||
private const float FLY_ROLL_MAX_RADIANS = 1.1f;
|
||||
|
||||
private const float FLY_ROLL_RADIANS_PER_UPDATE = 0.06f;
|
||||
private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f;
|
||||
|
||||
private float m_health = 100f;
|
||||
|
||||
protected ulong crossingFromRegion;
|
||||
|
@ -438,6 +443,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
get { return (IClientCore)ControllingClient; }
|
||||
}
|
||||
|
||||
public UUID COF { get; set; }
|
||||
|
||||
// public Vector3 ParentPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -606,6 +613,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
// Used for limited viewer 'fake' user rotations.
|
||||
private Vector3 m_AngularVelocity = Vector3.Zero;
|
||||
|
||||
public Vector3 AngularVelocity
|
||||
{
|
||||
get { return m_AngularVelocity; }
|
||||
}
|
||||
|
||||
public bool IsChildAgent { get; set; }
|
||||
public bool IsLoggingIn { get; set; }
|
||||
|
||||
|
@ -736,6 +751,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Constructor(s)
|
||||
|
||||
public ScenePresence(
|
||||
|
@ -1225,6 +1242,85 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
ControllingClient.StopFlying(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect.
|
||||
/// </summary>
|
||||
/// <param name="amount">Postive or negative roll amount in radians</param>
|
||||
private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown)
|
||||
{
|
||||
|
||||
float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS);
|
||||
m_AngularVelocity.Z = rollAmount;
|
||||
|
||||
// APPLY EXTRA consideration for flying up and flying down during this time.
|
||||
// if we're turning left
|
||||
if (amount > 0)
|
||||
{
|
||||
|
||||
// If we're at the max roll and pressing up, we want to swing BACK a bit
|
||||
// Automatically adds noise
|
||||
if (PressingUp)
|
||||
{
|
||||
if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS - 0.04f)
|
||||
m_AngularVelocity.Z -= 0.9f;
|
||||
}
|
||||
// If we're at the max roll and pressing down, we want to swing MORE a bit
|
||||
if (PressingDown)
|
||||
{
|
||||
if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS && m_AngularVelocity.Z < FLY_ROLL_MAX_RADIANS + 0.6f)
|
||||
m_AngularVelocity.Z += 0.6f;
|
||||
}
|
||||
}
|
||||
else // we're turning right.
|
||||
{
|
||||
// If we're at the max roll and pressing up, we want to swing BACK a bit
|
||||
// Automatically adds noise
|
||||
if (PressingUp)
|
||||
{
|
||||
if (m_AngularVelocity.Z <= (-FLY_ROLL_MAX_RADIANS))
|
||||
m_AngularVelocity.Z += 0.6f;
|
||||
}
|
||||
// If we're at the max roll and pressing down, we want to swing MORE a bit
|
||||
if (PressingDown)
|
||||
{
|
||||
if (m_AngularVelocity.Z >= -FLY_ROLL_MAX_RADIANS - 0.6f)
|
||||
m_AngularVelocity.Z -= 0.6f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// incrementally sets roll amount to zero
|
||||
/// </summary>
|
||||
/// <param name="amount">Positive roll amount in radians</param>
|
||||
/// <returns></returns>
|
||||
private float CalculateFlyingRollResetToZero(float amount)
|
||||
{
|
||||
const float rollMinRadians = 0f;
|
||||
|
||||
if (m_AngularVelocity.Z > 0)
|
||||
{
|
||||
|
||||
float leftOverToMin = m_AngularVelocity.Z - rollMinRadians;
|
||||
if (amount > leftOverToMin)
|
||||
return -leftOverToMin;
|
||||
else
|
||||
return -amount;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians;
|
||||
if (amount > leftOverToMin)
|
||||
return leftOverToMin;
|
||||
else
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// neighbouring regions we have enabled a child agent in
|
||||
// holds the seed cap for the child agent in that region
|
||||
private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
|
||||
|
@ -1430,17 +1526,42 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_doingCamRayCast = false;
|
||||
if (hitYN && localid != LocalId)
|
||||
{
|
||||
CameraConstraintActive = true;
|
||||
pNormal.X = (float)Math.Round(pNormal.X, 2);
|
||||
pNormal.Y = (float)Math.Round(pNormal.Y, 2);
|
||||
pNormal.Z = (float)Math.Round(pNormal.Z, 2);
|
||||
pNormal.Normalize();
|
||||
collisionPoint.X = (float)Math.Round(collisionPoint.X, 1);
|
||||
collisionPoint.Y = (float)Math.Round(collisionPoint.Y, 1);
|
||||
collisionPoint.Z = (float)Math.Round(collisionPoint.Z, 1);
|
||||
SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
|
||||
bool IsPrim = group != null;
|
||||
if (IsPrim)
|
||||
{
|
||||
SceneObjectPart part = group.GetPart(localid);
|
||||
if (part != null && !part.VolumeDetectActive)
|
||||
{
|
||||
CameraConstraintActive = true;
|
||||
pNormal.X = (float) Math.Round(pNormal.X, 2);
|
||||
pNormal.Y = (float) Math.Round(pNormal.Y, 2);
|
||||
pNormal.Z = (float) Math.Round(pNormal.Z, 2);
|
||||
pNormal.Normalize();
|
||||
collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
|
||||
collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
|
||||
collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
|
||||
|
||||
Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z, Vector3.Dot(collisionPoint, pNormal));
|
||||
UpdateCameraCollisionPlane(plane);
|
||||
Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
|
||||
Vector3.Dot(collisionPoint, pNormal));
|
||||
UpdateCameraCollisionPlane(plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CameraConstraintActive = true;
|
||||
pNormal.X = (float) Math.Round(pNormal.X, 2);
|
||||
pNormal.Y = (float) Math.Round(pNormal.Y, 2);
|
||||
pNormal.Z = (float) Math.Round(pNormal.Z, 2);
|
||||
pNormal.Normalize();
|
||||
collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
|
||||
collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
|
||||
collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
|
||||
|
||||
Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
|
||||
Vector3.Dot(collisionPoint, pNormal));
|
||||
UpdateCameraCollisionPlane(plane);
|
||||
}
|
||||
}
|
||||
else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
|
||||
!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
|
||||
|
@ -1741,6 +1862,33 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
|
||||
((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
|
||||
|
||||
|
||||
//m_log.Debug("[CONTROL]: " +flags);
|
||||
// Applies a satisfying roll effect to the avatar when flying.
|
||||
if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0))
|
||||
{
|
||||
|
||||
ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
|
||||
|
||||
|
||||
}
|
||||
else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) &&
|
||||
((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0))
|
||||
{
|
||||
ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_AngularVelocity.Z != 0)
|
||||
m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (Flying && IsColliding && controlland)
|
||||
{
|
||||
// nesting this check because LengthSquared() is expensive and we don't
|
||||
|
|
|
@ -633,7 +633,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
|
||||
private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader)
|
||||
{
|
||||
obj.Bounciness = reader.ReadElementContentAsFloat("Bounce", String.Empty);
|
||||
obj.Restitution = reader.ReadElementContentAsFloat("Bounce", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessGravityModifier(SceneObjectPart obj, XmlTextReader reader)
|
||||
|
@ -1363,8 +1363,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
writer.WriteElementString("Density", sop.Density.ToString().ToLower());
|
||||
if (sop.Friction != 0.6f)
|
||||
writer.WriteElementString("Friction", sop.Friction.ToString().ToLower());
|
||||
if (sop.Bounciness != 0.5f)
|
||||
writer.WriteElementString("Bounce", sop.Bounciness.ToString().ToLower());
|
||||
if (sop.Restitution != 0.5f)
|
||||
writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower());
|
||||
if (sop.GravityModifier != 1.0f)
|
||||
writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower());
|
||||
WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset());
|
||||
|
|
|
@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
|||
hostPart.ParentGroup.RootPart.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true) ? 1 : 0;
|
||||
return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true, true) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ namespace OpenSim.Region.Physics.Manager
|
|||
public virtual float Density { get; set; }
|
||||
public virtual float GravModifier { get; set; }
|
||||
public virtual float Friction { get; set; }
|
||||
public virtual float Bounce { get; set; }
|
||||
public virtual float Restitution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Position of this actor.
|
||||
|
|
|
@ -1014,8 +1014,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
offset.Y += contact.pos.Y;
|
||||
offset.Z += contact.pos.Z;
|
||||
|
||||
_position = offset;
|
||||
return false;
|
||||
//_position = offset;
|
||||
//return false;
|
||||
}
|
||||
|
||||
offset.X = contact.pos.X - _position.X;
|
||||
|
|
|
@ -3332,7 +3332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
|
||||
|
||||
if (attachmentsModule != null)
|
||||
return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
|
||||
return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -4724,7 +4724,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
UUID av = new UUID();
|
||||
if (!UUID.TryParse(agent,out av))
|
||||
{
|
||||
//LSLError("First parameter to llDialog needs to be a key");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7222,20 +7221,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
}
|
||||
if (buttons.Length > 12)
|
||||
{
|
||||
LSLError("No more than 12 buttons can be shown");
|
||||
return;
|
||||
ShoutError("button list too long, must be 12 or fewer entries");
|
||||
}
|
||||
string[] buts = new string[buttons.Length];
|
||||
for (int i = 0; i < buttons.Length; i++)
|
||||
int length = buttons.Length;
|
||||
if (length > 12)
|
||||
length = 12;
|
||||
|
||||
string[] buts = new string[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (buttons.Data[i].ToString() == String.Empty)
|
||||
{
|
||||
LSLError("button label cannot be blank");
|
||||
ShoutError("button label cannot be blank");
|
||||
return;
|
||||
}
|
||||
if (buttons.Data[i].ToString().Length > 24)
|
||||
{
|
||||
llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
|
||||
ShoutError("button label cannot be longer than 24 characters");
|
||||
return;
|
||||
}
|
||||
buts[i] = buttons.Data[i].ToString();
|
||||
|
@ -7843,7 +7845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
|
||||
physdata.Density = part.Density;
|
||||
physdata.Friction = part.Friction;
|
||||
physdata.Bounce = part.Bounciness;
|
||||
physdata.Bounce = part.Restitution;
|
||||
physdata.GravitationModifier = part.GravityModifier;
|
||||
|
||||
if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
|
||||
|
@ -8236,7 +8238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
ExtraPhysicsData physdata = new ExtraPhysicsData();
|
||||
physdata.Density = part.Density;
|
||||
physdata.Bounce = part.Bounciness;
|
||||
physdata.Bounce = part.Restitution;
|
||||
physdata.GravitationModifier = part.GravityModifier;
|
||||
physdata.PhysShapeType = (PhysShapeType)shape_type;
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
public void modInvokeN(string fname, params object[] parms)
|
||||
{
|
||||
Type returntype = m_comms.LookupReturnType(fname);
|
||||
if (returntype != typeof(string))
|
||||
if (returntype != typeof(void))
|
||||
MODError(String.Format("return type mismatch for {0}",fname));
|
||||
|
||||
modInvoke(fname,parms);
|
||||
|
@ -264,6 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
if (result != null)
|
||||
return result;
|
||||
|
||||
Type returntype = m_comms.LookupReturnType(fname);
|
||||
if (returntype == typeof(void))
|
||||
return null;
|
||||
|
||||
MODError(String.Format("Invocation of {0} failed; null return value",fname));
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -1619,7 +1619,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
}
|
||||
}
|
||||
|
||||
public Object osParseJSONNew(string JSON)
|
||||
private Object osParseJSONNew(string JSON)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
|
||||
|
||||
|
|
|
@ -259,7 +259,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
|
||||
string osGetScriptEngineName();
|
||||
string osGetSimulatorVersion();
|
||||
Object osParseJSONNew(string JSON);
|
||||
Hashtable osParseJSON(string JSON);
|
||||
|
||||
void osMessageObject(key objectUUID,string message);
|
||||
|
|
|
@ -430,11 +430,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
return m_OSSL_Functions.osParseJSON(JSON);
|
||||
}
|
||||
|
||||
public Object osParseJSONNew(string JSON)
|
||||
{
|
||||
return m_OSSL_Functions.osParseJSONNew(JSON);
|
||||
}
|
||||
|
||||
public void osMessageObject(key objectUUID,string message)
|
||||
{
|
||||
m_OSSL_Functions.osMessageObject(objectUUID,message);
|
||||
|
|
|
@ -512,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
|||
else if (o is LSL_Types.LSLFloat)
|
||||
size += 8;
|
||||
else if (o is LSL_Types.LSLString)
|
||||
size += ((LSL_Types.LSLString)o).m_string.Length;
|
||||
size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
|
||||
else if (o is LSL_Types.key)
|
||||
size += ((LSL_Types.key)o).value.Length;
|
||||
else if (o is LSL_Types.Vector3)
|
||||
|
|
|
@ -180,11 +180,18 @@ namespace OpenSim.Services.Interfaces
|
|||
|
||||
// Attachments
|
||||
List<AvatarAttachment> attachments = appearance.GetAttachments();
|
||||
Dictionary<int, List<string>> atts = new Dictionary<int, List<string>>();
|
||||
foreach (AvatarAttachment attach in attachments)
|
||||
{
|
||||
if (attach.ItemID != UUID.Zero)
|
||||
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
|
||||
{
|
||||
if (!atts.ContainsKey(attach.AttachPoint))
|
||||
atts[attach.AttachPoint] = new List<string>();
|
||||
atts[attach.AttachPoint].Add(attach.ItemID.ToString());
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<int, List<string>> kvp in atts)
|
||||
Data["_ap_" + kvp.Key] = string.Join(",", kvp.Value.ToArray());
|
||||
}
|
||||
|
||||
public AvatarAppearance ToAvatarAppearance()
|
||||
|
@ -320,10 +327,16 @@ namespace OpenSim.Services.Interfaces
|
|||
if (!Int32.TryParse(pointStr, out point))
|
||||
continue;
|
||||
|
||||
UUID uuid = UUID.Zero;
|
||||
UUID.TryParse(_kvp.Value, out uuid);
|
||||
List<string> idList = new List<string>(_kvp.Value.Split(new char[] {','}));
|
||||
|
||||
appearance.SetAttachment(point, uuid, UUID.Zero);
|
||||
appearance.SetAttachment(point, UUID.Zero, UUID.Zero);
|
||||
foreach (string id in idList)
|
||||
{
|
||||
UUID uuid = UUID.Zero;
|
||||
UUID.TryParse(id, out uuid);
|
||||
|
||||
appearance.SetAttachment(point | 0x80, uuid, UUID.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
if (appearance.Wearables[AvatarWearable.BODY].Count == 0)
|
||||
|
|
|
@ -1597,9 +1597,10 @@
|
|||
<Reference name="System.Drawing"/>
|
||||
<Reference name="System.Xml"/>
|
||||
<Reference name="System.Web"/>
|
||||
<Reference name="OpenMetaverse" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverse.StructuredData" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverse" path="../../../../../bin/"/>
|
||||
|
||||
<Reference name="OpenSim.Region.Framework"/>
|
||||
<Reference name="OpenSim.Capabilities"/>
|
||||
<Reference name="OpenSim.Capabilities.Handlers"/>
|
||||
|
|
Loading…
Reference in New Issue