Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork

avinationmerge
ubit 2013-04-28 19:46:57 +02:00
commit 7000b52aeb
41 changed files with 1218 additions and 520 deletions

View File

@ -30,6 +30,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
@ -68,6 +69,7 @@ namespace OpenSim.Framework.Capabilities
private IHttpServer m_httpListener; private IHttpServer m_httpListener;
private UUID m_agentID; private UUID m_agentID;
private string m_regionName; private string m_regionName;
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
public UUID AgentID 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);
}
} }
} }

View File

@ -1339,7 +1339,7 @@ namespace OpenSim.Data.MySQL
prim.Density = (float)(double)row["Density"]; prim.Density = (float)(double)row["Density"];
prim.GravityModifier = (float)(double)row["GravityModifier"]; prim.GravityModifier = (float)(double)row["GravityModifier"];
prim.Friction = (float)(double)row["Friction"]; prim.Friction = (float)(double)row["Friction"];
prim.Bounciness = (float)(double)row["Restitution"]; prim.Restitution = (float)(double)row["Restitution"];
SOPVehicle vehicle = null; SOPVehicle vehicle = null;
@ -1725,7 +1725,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("Density", (double)prim.Density); cmd.Parameters.AddWithValue("Density", (double)prim.Density);
cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier); cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier);
cmd.Parameters.AddWithValue("Friction", (double)prim.Friction); 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) if (prim.VehicleParams != null)
cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2());

View File

@ -497,8 +497,6 @@ namespace OpenSim.Framework
/// </remarks> /// </remarks>
public List<AvatarAttachment> GetAttachments() public List<AvatarAttachment> GetAttachments()
{ {
lock (m_attachments) lock (m_attachments)
{ {
List<AvatarAttachment> alist = new List<AvatarAttachment>(); List<AvatarAttachment> alist = new List<AvatarAttachment>();
@ -508,7 +506,8 @@ namespace OpenSim.Framework
alist.Add(new AvatarAttachment(attach)); alist.Add(new AvatarAttachment(attach));
} }
return alist; return alist;
} } }
}
internal void AppendAttachment(AvatarAttachment attach) internal void AppendAttachment(AvatarAttachment attach)
{ {

View File

@ -2097,4 +2097,112 @@ namespace OpenSim.Framework
} }
#endregion #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();
}
}
}
} }

View File

@ -343,6 +343,9 @@ namespace OpenSim.Region.ClientStack.Linden
m_log.DebugFormat( m_log.DebugFormat(
"[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID); "[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)) if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
{ {
m_log.WarnFormat( m_log.WarnFormat(
@ -1317,7 +1320,7 @@ namespace OpenSim.Region.ClientStack.Linden
object_data["PhysicsShapeType"] = obj.PhysicsShapeType; object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
object_data["Density"] = obj.Density; object_data["Density"] = obj.Density;
object_data["Friction"] = obj.Friction; object_data["Friction"] = obj.Friction;
object_data["Restitution"] = obj.Bounciness; object_data["Restitution"] = obj.Restitution;
object_data["GravityMultiplier"] = obj.GravityModifier; object_data["GravityMultiplier"] = obj.GravityModifier;
resp[uuid.ToString()] = object_data; resp[uuid.ToString()] = object_data;

View File

@ -467,8 +467,8 @@ namespace OpenSim.Region.ClientStack.Linden
responsedata["content_type"] = "text/plain"; responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false; responsedata["keepalive"] = false;
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["str_response_string"] = "Upstream error: "; responsedata["str_response_string"] = "<llsd></llsd>";
responsedata["error_status_text"] = "Upstream error:"; responsedata["error_status_text"] = "<llsd></llsd>";
responsedata["http_protocol_version"] = "HTTP/1.0"; responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata; return responsedata;
} }

View File

@ -59,6 +59,8 @@ namespace OpenSim.Region.ClientStack.Linden
// private static readonly ILog m_log = // private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
private Scene m_scene; private Scene m_scene;
/// <summary> /// <summary>
@ -94,6 +96,8 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
m_scene = s; m_scene = s;
m_scene.EventManager.OnRegisterCaps += RegisterCaps; m_scene.EventManager.OnRegisterCaps += RegisterCaps;
m_scene.RegisterModuleInterface<ISimulatorFeaturesModule>(this);
} }
public void RemoveRegion(Scene s) public void RemoveRegion(Scene s)
@ -156,7 +160,7 @@ namespace OpenSim.Region.ClientStack.Linden
IRequestHandler reqHandler IRequestHandler reqHandler
= new RestHTTPHandler( = new RestHTTPHandler(
"GET", "/CAPS/" + UUID.Random(), "GET", "/CAPS/" + UUID.Random(),
HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString()); x => { return HandleSimulatorFeaturesRequest(x, agentID); }, "SimulatorFeatures", agentID.ToString());
caps.RegisterHandler("SimulatorFeatures", reqHandler); caps.RegisterHandler("SimulatorFeatures", reqHandler);
} }
@ -185,18 +189,33 @@ namespace OpenSim.Region.ClientStack.Linden
return new OSDMap(m_features); 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"); // m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
OSDMap copy = DeepCopy();
SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest;
if (handlerOnSimulatorFeaturesRequest != null)
handlerOnSimulatorFeaturesRequest(agentID, ref copy);
//Send back data //Send back data
Hashtable responsedata = new Hashtable(); Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["content_type"] = "text/plain"; responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false; responsedata["keepalive"] = false;
lock (m_features) responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy);
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features);
return responsedata; return responsedata;
} }

View File

@ -190,8 +190,15 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
{ {
cacheItems[i].TextureID = Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; 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) if (m_scene.AssetService != null)
cacheItems[i].TextureAsset = cacheItems[i].TextureAsset =
m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
@ -213,8 +220,16 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) 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 = cacheItems[i].TextureID =
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; face.TextureID;
} }
else else
{ {

View File

@ -39,10 +39,13 @@ using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Capabilities;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps; using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers; using OpenSim.Capabilities.Handlers;
using OpenSim.Framework.Monitoring; using OpenSim.Framework.Monitoring;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Region.ClientStack.Linden namespace OpenSim.Region.ClientStack.Linden
{ {
@ -52,11 +55,13 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")]
public class WebFetchInvDescModule : INonSharedRegionModule public class WebFetchInvDescModule : INonSharedRegionModule
{ {
struct aPollRequest class aPollRequest
{ {
public PollServiceInventoryEventArgs thepoll; public PollServiceInventoryEventArgs thepoll;
public UUID reqID; public UUID reqID;
public Hashtable request; public Hashtable request;
public ScenePresence presence;
public List<UUID> folders;
} }
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 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 Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
private static Thread[] m_workerThreads = null; private static Thread[] m_workerThreads = null;
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue = private static DoubleQueue<aPollRequest> m_queue =
new OpenMetaverse.BlockingQueue<aPollRequest>(); new DoubleQueue<aPollRequest>();
#region ISharedRegionModule Members #region ISharedRegionModule Members
@ -143,12 +148,18 @@ namespace OpenSim.Region.ClientStack.Linden
private class PollServiceInventoryEventArgs : PollServiceEventArgs private class PollServiceInventoryEventArgs : PollServiceEventArgs
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<UUID, Hashtable> responses = private Dictionary<UUID, Hashtable> responses =
new Dictionary<UUID, Hashtable>(); 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) base(null, null, null, null, pId, int.MaxValue)
{ {
m_scene = scene;
HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); };
GetEvents = (x, y) => GetEvents = (x, y) =>
{ {
@ -167,12 +178,68 @@ namespace OpenSim.Region.ClientStack.Linden
Request = (x, y) => 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(); aPollRequest reqinfo = new aPollRequest();
reqinfo.thepoll = this; reqinfo.thepoll = this;
reqinfo.reqID = x; reqinfo.reqID = x;
reqinfo.request = y; 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) => NoEvents = (x, y) =>
@ -220,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden
string capUrl = "/CAPS/" + UUID.Random() + "/"; string capUrl = "/CAPS/" + UUID.Random() + "/";
// Register this as a poll service // Register this as a poll service
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID); PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID);
args.Type = PollServiceEventArgs.EventType.Inventory; args.Type = PollServiceEventArgs.EventType.Inventory;
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);

View File

@ -2654,7 +2654,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
byte physshapetype = part.PhysicsShapeType; byte physshapetype = part.PhysicsShapeType;
float density = part.Density; float density = part.Density;
float friction = part.Friction; float friction = part.Friction;
float bounce = part.Bounciness; float bounce = part.Restitution;
float gravmod = part.GravityModifier; float gravmod = part.GravityModifier;
eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
@ -3893,6 +3893,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
part.Shape.LightEntry = false; 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; ++updatesThisCall;
@ -4952,6 +4960,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset; position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
rotation = part.RotationOffset * presence.Rotation; rotation = part.RotationOffset * presence.Rotation;
} }
angularVelocity = Vector3.Zero;
}
else
{
angularVelocity = presence.AngularVelocity;
rotation = presence.Rotation;
} }
attachPoint = 0; attachPoint = 0;
@ -4964,8 +4978,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// may improve movement smoothness. // may improve movement smoothness.
// acceleration = new Vector3(1, 0, 0); // acceleration = new Vector3(1, 0, 0);
angularVelocity = Vector3.Zero;
if (sendTexture) if (sendTexture)
textureEntry = presence.Appearance.Texture.GetBytes(); textureEntry = presence.Appearance.Texture.GetBytes();
else else

View File

@ -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();
}
}
}
} }

View File

@ -260,10 +260,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{ {
CompleteTaskItemUpdate(m_updateTaskItemData); CompleteTaskItemUpdate(m_updateTaskItemData);
} }
// else if (m_storeLocal) else if (m_asset.Local)
// { {
// m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
// } }
} }
m_log.DebugFormat( m_log.DebugFormat(
@ -339,6 +339,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
// to avoid a race condition when the appearance module retrieves the item to set the asset id in // to avoid a race condition when the appearance module retrieves the item to set the asset id in
// the AvatarAppearance structure. // the AvatarAppearance structure.
item.AssetID = m_asset.FullID; item.AssetID = m_asset.FullID;
if (item.AssetID != UUID.Zero)
m_Scene.InventoryService.UpdateItem(item); m_Scene.InventoryService.UpdateItem(item);
if (m_uploadState == UploadState.Complete) if (m_uploadState == UploadState.Complete)
@ -390,6 +391,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
// m_asset.FullID, item.Name, ourClient.Name); // m_asset.FullID, item.Name, ourClient.Name);
m_Scene.AssetService.Store(m_asset); 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); m_transactions.RemoveXferUploader(m_transactionID);
} }

View File

@ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Asset
AssetBase asset = null; AssetBase asset = null;
string filename = GetFileName(id); string filename = GetFileName(id);
if (File.Exists(filename)) while (File.Exists(filename))
{ {
FileStream stream = null; FileStream stream = null;
try try
@ -380,6 +380,8 @@ namespace OpenSim.Region.CoreModules.Asset
asset = (AssetBase)bformatter.Deserialize(stream); asset = (AssetBase)bformatter.Deserialize(stream);
m_DiskHits++; m_DiskHits++;
break;
} }
catch (System.Runtime.Serialization.SerializationException e) catch (System.Runtime.Serialization.SerializationException e)
{ {
@ -392,12 +394,24 @@ namespace OpenSim.Region.CoreModules.Asset
// {different version of AssetBase} -- we should attempt to // {different version of AssetBase} -- we should attempt to
// delete it and re-cache // delete it and re-cache
File.Delete(filename); 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) catch (Exception e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
filename, id, e.Message, e.StackTrace); filename, id, e.Message, e.StackTrace);
break;
} }
finally finally
{ {

View File

@ -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 // If we're an NPC then skip all the item checks and manipulations since we don't have an
// inventory right now. // inventory right now.
if (sp.PresenceType == PresenceType.Npc) if (sp.PresenceType == PresenceType.Npc)
RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null, true);
else else
RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d); RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80, d);
} }
catch (Exception e) catch (Exception e)
{ {
@ -284,12 +284,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
sp.ClearAttachments(); 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) if (!Enabled)
return false; 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); m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
return true; return true;
@ -298,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return false; 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) lock (sp.AttachmentsSyncLock)
{ {
@ -326,10 +326,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
Vector3 attachPos = group.AbsolutePosition; 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 // 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 // set it's offset position = 0 so that it appears on the attachment point
// and not in a weird location somewhere unknown. // and not in a weird location somewhere unknown.
@ -375,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
group.AbsolutePosition = attachPos; group.AbsolutePosition = attachPos;
if (sp.PresenceType != PresenceType.Npc) if (sp.PresenceType != PresenceType.Npc)
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
AttachToAgent(sp, group, attachmentPt, attachPos, silent); AttachToAgent(sp, group, attachmentPt, attachPos, silent);
} }
@ -383,21 +379,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return true; 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); List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
// At the moment we can only deal with a single attachment // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
if (attachments.Count != 0) while (attachments.Count >= 5)
{ {
if (attachments[0].FromItemID != UUID.Zero) if (attachments[0].FromItemID != UUID.Zero)
DetachSingleAttachmentToInvInternal(sp, attachments[0]); DetachSingleAttachmentToInvInternal(sp, attachments[0]);
// Error logging commented because UUID.Zero now means temp attachment attachments.RemoveAt(0);
// 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!", // If we're not appending, remove the rest as well
// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); 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. // 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) if (newAttachmentItemID == UUID.Zero)
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; 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}", // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
// (AttachmentPoint)AttachmentPt, itemID, sp.Name); // (AttachmentPoint)AttachmentPt, itemID, sp.Name);
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should bool append = (AttachmentPt & 0x80) != 0;
// be removed when that functionality is implemented in opensim
AttachmentPt &= 0x7f; AttachmentPt &= 0x7f;
// Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). // 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 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) public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@ -847,7 +847,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 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) if (m_invAccessModule == null)
return null; return null;
@ -885,7 +885,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// This will throw if the attachment fails // This will throw if the attachment fails
try try
{ {
AttachObjectInternal(sp, objatt, attachmentPt, false, false, false); AttachObjectInternal(sp, objatt, attachmentPt, false, false, false, append);
} }
catch (Exception e) catch (Exception e)
{ {
@ -936,7 +936,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// <param name="AttachmentPt"></param> /// <param name="AttachmentPt"></param>
/// <param name="itemID"></param> /// <param name="itemID"></param>
/// <param name="att"></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( // m_log.DebugFormat(
// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", // "[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) if (item == null)
return; 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) if (changed && m_scene.AvatarFactory != null)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
@ -1043,12 +1044,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return; return;
} }
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should bool append = (AttachmentPt & 0x80) != 0;
// be removed when that functionality is implemented in opensim
AttachmentPt &= 0x7f; AttachmentPt &= 0x7f;
// Calls attach with a Zero position // 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( // m_log.Debug(
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId

View File

@ -197,7 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
m_numberOfAttachEventsFired = 0; 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 // Check status on scene presence
Assert.That(sp.HasAttachments(), Is.True); 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.AbsolutePosition = new Vector3(0, 0, 0);
sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 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(sp.HasAttachments(), Is.False);
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));

View File

@ -674,19 +674,52 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
{ {
IInventoryService invService = m_scene.InventoryService; IInventoryService invService = m_scene.InventoryService;
bool resetwearable = false;
if (invService.GetRootFolder(userID) != null) if (invService.GetRootFolder(userID) != null)
{ {
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
{ {
for (int j = 0; j < appearance.Wearables[i].Count; j++) 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) 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 }
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
continue; 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)
{
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); InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
baseItem = invService.GetItem(baseItem); baseItem = invService.GetItem(baseItem);
@ -694,6 +727,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (baseItem != null) if (baseItem != null)
{ {
appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 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 else
{ {
@ -701,17 +745,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
"[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
appearance.Wearables[i][j].ItemID, (WearableType)i); 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 else
{ {
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 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 #endregion
#region Client Event Handlers #region Client Event Handlers

View File

@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework
/// <summary> /// <summary>
/// Each agent has its own capabilities handler. /// Each agent has its own capabilities handler.
/// </summary> /// </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, string> capsPaths = new Dictionary<UUID, string>();
protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Framework
get { return null; } get { return null; }
} }
public void CreateCaps(UUID agentId) public void CreateCaps(UUID agentId, uint circuitCode)
{ {
int flags = m_scene.GetUserFlags(agentId); int flags = m_scene.GetUserFlags(agentId);
if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
@ -108,9 +108,9 @@ namespace OpenSim.Region.CoreModules.Framework
String capsObjectPath = GetCapsPath(agentId); 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( m_log.DebugFormat(
"[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", "[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, (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
capsObjectPath, agentId, m_scene.RegionInfo.RegionName); capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
m_capsObjects[agentId] = caps; m_capsObjects[circuitCode] = caps;
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
} }
public void RemoveCaps(UUID agentId) public void RemoveCaps(UUID agentId, uint circuitCode)
{ {
if (childrenSeeds.ContainsKey(agentId)) if (childrenSeeds.ContainsKey(agentId))
{ {
@ -139,11 +139,11 @@ namespace OpenSim.Region.CoreModules.Framework
lock (m_capsObjects) lock (m_capsObjects)
{ {
if (m_capsObjects.ContainsKey(agentId)) if (m_capsObjects.ContainsKey(circuitCode))
{ {
m_capsObjects[agentId].DeregisterHandlers(); m_capsObjects[circuitCode].DeregisterHandlers();
m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
m_capsObjects.Remove(agentId); m_capsObjects.Remove(circuitCode);
} }
else else
{ {
@ -154,19 +154,30 @@ namespace OpenSim.Region.CoreModules.Framework
} }
} }
public Caps GetCapsForUser(UUID agentId) public Caps GetCapsForUser(uint circuitCode)
{ {
lock (m_capsObjects) lock (m_capsObjects)
{ {
if (m_capsObjects.ContainsKey(agentId)) if (m_capsObjects.ContainsKey(circuitCode))
{ {
return m_capsObjects[agentId]; return m_capsObjects[circuitCode];
} }
} }
return null; return null;
} }
public void ActivateCaps(uint circuitCode)
{
lock (m_capsObjects)
{
if (m_capsObjects.ContainsKey(circuitCode))
{
m_capsObjects[circuitCode].Activate();
}
}
}
public void SetAgentCapsSeeds(AgentCircuitData agent) public void SetAgentCapsSeeds(AgentCircuitData agent)
{ {
capsPaths[agent.AgentID] = agent.CapsPath; capsPaths[agent.AgentID] = agent.CapsPath;
@ -237,9 +248,9 @@ namespace OpenSim.Region.CoreModules.Framework
StringBuilder caps = new StringBuilder(); StringBuilder caps = new StringBuilder();
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); 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(); ) for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); )
{ {

View File

@ -150,7 +150,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{ {
client.OnTeleportHomeRequest += TriggerTeleportHome; client.OnTeleportHomeRequest += TriggerTeleportHome;
client.OnTeleportLandmarkRequest += RequestTeleportLandmark; client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
client.OnTeleportCancel += TeleportCancel;
} }
public virtual void Close() {} public virtual void Close() {}
@ -995,11 +994,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return neighbourRegion; return neighbourRegion;
} }
private void TeleportCancel(IClientAPI remoteClient)
{
m_entityTransferStateMachine.ResetFromTransit(remoteClient.AgentId);
}
public bool Cross(ScenePresence agent, bool isFlying) public bool Cross(ScenePresence agent, bool isFlying)
{ {
uint x; uint x;

View File

@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
public string url; public string url;
public UUID urlcode; public UUID urlcode;
public Dictionary<UUID, RequestData> requests; public Dictionary<UUID, RequestData> requests;
public bool isSsl;
} }
public class RequestData public class RequestData
@ -184,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
urlData.engine = engine; urlData.engine = engine;
urlData.url = url; urlData.url = url;
urlData.urlcode = urlcode; urlData.urlcode = urlcode;
urlData.isSsl = false;
urlData.requests = new Dictionary<UUID, RequestData>(); urlData.requests = new Dictionary<UUID, RequestData>();
m_UrlMap[url] = urlData; m_UrlMap[url] = urlData;
@ -229,6 +231,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
urlData.engine = engine; urlData.engine = engine;
urlData.url = url; urlData.url = url;
urlData.urlcode = urlcode; urlData.urlcode = urlcode;
urlData.isSsl = true;
urlData.requests = new Dictionary<UUID, RequestData>(); urlData.requests = new Dictionary<UUID, RequestData>();
@ -394,6 +397,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
private void RemoveUrl(UrlData data) private void RemoveUrl(UrlData data)
{ {
if (data.isSsl)
m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
else
m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
} }

View File

@ -262,6 +262,8 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
return "modInvokeR"; return "modInvokeR";
else if (sid.ReturnType == typeof(object[])) else if (sid.ReturnType == typeof(object[]))
return "modInvokeL"; 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); m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
} }

View File

@ -84,7 +84,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="AttachmentPt"></param> /// <param name="AttachmentPt"></param>
/// <param name="silent"></param> /// <param name="silent"></param>
/// <returns>true if the object was successfully attached, false otherwise</returns> /// <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> /// <summary>
/// Rez an attachment from user inventory and change inventory status to match. /// Rez an attachment from user inventory and change inventory status to match.

View File

@ -40,19 +40,19 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary> /// </summary>
/// <param name="agentId"></param> /// <param name="agentId"></param>
/// <param name="capsObjectPath"></param> /// <param name="capsObjectPath"></param>
void CreateCaps(UUID agentId); void CreateCaps(UUID agentId, uint circuitCode);
/// <summary> /// <summary>
/// Remove the caps handler for a given agent. /// Remove the caps handler for a given agent.
/// </summary> /// </summary>
/// <param name="agentId"></param> /// <param name="agentId"></param>
void RemoveCaps(UUID agentId); void RemoveCaps(UUID agentId, uint circuitCode);
/// <summary> /// <summary>
/// Will return null if the agent doesn't have a caps handler registered /// Will return null if the agent doesn't have a caps handler registered
/// </summary> /// </summary>
/// <param name="agentId"></param> /// <param name="agentId"></param>
Caps GetCapsForUser(UUID agentId); Caps GetCapsForUser(uint circuitCode);
void SetAgentCapsSeeds(AgentCircuitData agent); void SetAgentCapsSeeds(AgentCircuitData agent);
@ -65,5 +65,7 @@ namespace OpenSim.Region.Framework.Interfaces
void DropChildSeed(UUID agentID, ulong handle); void DropChildSeed(UUID agentID, ulong handle);
string GetCapsPath(UUID agentId); string GetCapsPath(UUID agentId);
void ActivateCaps(uint circuitCode);
} }
} }

View File

@ -26,15 +26,19 @@
*/ */
using System; using System;
using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
{ {
public delegate void SimulatorFeaturesRequestDelegate(UUID agentID, ref OSDMap features);
/// <summary> /// <summary>
/// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability. /// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability.
/// </summary> /// </summary>
public interface ISimulatorFeaturesModule public interface ISimulatorFeaturesModule
{ {
event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
void AddFeature(string name, OSD value); void AddFeature(string name, OSD value);
bool RemoveFeature(string name); bool RemoveFeature(string name);
bool TryGetFeature(string name, out OSD value); bool TryGetFeature(string name, out OSD value);

View File

@ -22,6 +22,115 @@ using log4net;
namespace OpenSim.Region.Framework.Scenes 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] [Serializable]
public class KeyframeMotion public class KeyframeMotion
{ {
@ -63,18 +172,6 @@ namespace OpenSim.Region.Framework.Scenes
private Keyframe[] m_keyframes; 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. // skip timer events.
//timer.stop doesn't assure there aren't event threads still being fired //timer.stop doesn't assure there aren't event threads still being fired
[NonSerialized()] [NonSerialized()]
@ -97,12 +194,21 @@ namespace OpenSim.Region.Framework.Scenes
private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation; private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation;
private bool m_running = false; private bool m_running = false;
[NonSerialized()] [NonSerialized()]
private bool m_selected = false; private bool m_selected = false;
private int m_iterations = 0; 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 public DataFormat Data
{ {
@ -139,31 +245,16 @@ namespace OpenSim.Region.Framework.Scenes
private void StartTimer() private void StartTimer()
{ {
if (m_timer == null) KeyframeTimer.Add(this);
return;
m_timerStopped = false; m_timerStopped = false;
m_timer.Start();
} }
private void StopTimer() private void StopTimer()
{ {
if (m_timer == null || m_timerStopped)
return;
m_timerStopped = true; 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) public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data)
{ {
KeyframeMotion newMotion = null; KeyframeMotion newMotion = null;
@ -177,12 +268,15 @@ namespace OpenSim.Region.Framework.Scenes
newMotion.m_group = grp; newMotion.m_group = grp;
if (grp != null && grp.IsSelected) if (grp != null)
{
newMotion.m_scene = grp.Scene;
if (grp.IsSelected)
newMotion.m_selected = true; newMotion.m_selected = true;
}
newMotion.m_onTimerLock = new object();
newMotion.m_timerStopped = false; newMotion.m_timerStopped = false;
newMotion.m_inOnTimer = false; newMotion.m_running = true;
newMotion.m_isCrossing = false; newMotion.m_isCrossing = false;
newMotion.m_waitingCrossing = false; newMotion.m_waitingCrossing = false;
} }
@ -196,8 +290,6 @@ namespace OpenSim.Region.Framework.Scenes
public void UpdateSceneObject(SceneObjectGroup grp) public void UpdateSceneObject(SceneObjectGroup grp)
{ {
// lock (m_onTimerLock)
{
m_isCrossing = false; m_isCrossing = false;
m_waitingCrossing = false; m_waitingCrossing = false;
StopTimer(); StopTimer();
@ -206,6 +298,8 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
m_group = grp; m_group = grp;
m_scene = grp.Scene;
Vector3 grppos = grp.AbsolutePosition; Vector3 grppos = grp.AbsolutePosition;
Vector3 offset = grppos - m_serializedPosition; Vector3 offset = grppos - m_serializedPosition;
// avoid doing it more than once // avoid doing it more than once
@ -227,7 +321,6 @@ namespace OpenSim.Region.Framework.Scenes
if (m_running) if (m_running)
Start(); Start();
} }
}
public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data) public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data)
{ {
@ -239,11 +332,10 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_basePosition = grp.AbsolutePosition; m_basePosition = grp.AbsolutePosition;
m_baseRotation = grp.GroupRotation; m_baseRotation = grp.GroupRotation;
m_scene = grp.Scene;
} }
m_onTimerLock = new object();
m_timerStopped = true; m_timerStopped = true;
m_inOnTimer = false;
m_isCrossing = false; m_isCrossing = false;
m_waitingCrossing = false; m_waitingCrossing = false;
} }
@ -260,6 +352,7 @@ namespace OpenSim.Region.Framework.Scenes
KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data); KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data);
newmotion.m_group = newgrp; newmotion.m_group = newgrp;
newmotion.m_scene = newgrp.Scene;
if (m_keyframes != null) if (m_keyframes != null)
{ {
@ -296,7 +389,7 @@ namespace OpenSim.Region.Framework.Scenes
public void Delete() public void Delete()
{ {
m_running = false; m_running = false;
RemoveTimer(); StopTimer();
m_isCrossing = false; m_isCrossing = false;
m_waitingCrossing = false; m_waitingCrossing = false;
m_frames.Clear(); m_frames.Clear();
@ -309,27 +402,13 @@ namespace OpenSim.Region.Framework.Scenes
m_waitingCrossing = false; m_waitingCrossing = false;
if (m_keyframes != null && m_group != null && m_keyframes.Length > 0) 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(); StartTimer();
m_running = true; m_running = true;
} }
else else
{ {
m_running = false; m_running = false;
RemoveTimer(); StopTimer();
} }
} }
@ -339,7 +418,7 @@ namespace OpenSim.Region.Framework.Scenes
m_isCrossing = false; m_isCrossing = false;
m_waitingCrossing = false; m_waitingCrossing = false;
RemoveTimer(); StopTimer();
m_basePosition = m_group.AbsolutePosition; m_basePosition = m_group.AbsolutePosition;
m_baseRotation = m_group.GroupRotation; m_baseRotation = m_group.GroupRotation;
@ -354,7 +433,7 @@ namespace OpenSim.Region.Framework.Scenes
public void Pause() public void Pause()
{ {
m_running = false; m_running = false;
RemoveTimer(); StopTimer();
m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.Velocity = Vector3.Zero;
m_group.RootPart.AngularVelocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero;
@ -377,15 +456,11 @@ namespace OpenSim.Region.Framework.Scenes
int start = 0; int start = 0;
int end = m_keyframes.Length; int end = m_keyframes.Length;
// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
// end = m_keyframes.Length - 1;
if (direction < 0) if (direction < 0)
{ {
start = m_keyframes.Length - 1; start = m_keyframes.Length - 1;
end = -1; end = -1;
// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
// end = 0;
} }
for (int i = start; i != end ; i += direction) for (int i = start; i != end ; i += direction)
@ -463,39 +538,30 @@ 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 if (m_skipLoops > 0)
return;
if (m_inOnTimer) // don't let overruns to happen
{ {
m_log.Warn("[KeyFrame]: timer overrun"); m_skipLoops--;
return; return;
} }
if (m_timerStopped) // trap events still in air even after a timer.stop
return;
if (m_group == null) if (m_group == null)
return; return;
lock (m_onTimerLock)
{
m_inOnTimer = true;
bool update = false; bool update = false;
try
{
if (m_selected) if (m_selected)
{ {
if (m_group.RootPart.Velocity != Vector3.Zero) if (m_group.RootPart.Velocity != Vector3.Zero)
{ {
m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.Velocity = Vector3.Zero;
m_group.SendGroupRootTerseUpdate(); m_group.SendGroupRootTerseUpdate();
// m_group.RootPart.ScheduleTerseUpdate();
} }
m_inOnTimer = false;
return; return;
} }
@ -510,10 +576,8 @@ namespace OpenSim.Region.Framework.Scenes
if (!m_isCrossing) if (!m_isCrossing)
{ {
StopTimer(); StopTimer();
m_timer.Interval = timerInterval;
StartTimer(); StartTimer();
} }
m_inOnTimer = false;
return; return;
} }
@ -524,21 +588,30 @@ namespace OpenSim.Region.Framework.Scenes
if (m_frames.Count == 0) if (m_frames.Count == 0)
{ {
Stop(); Stop();
m_inOnTimer = false; 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]);
}
return; return;
} }
m_currentFrame = m_frames[0]; m_currentFrame = m_frames[0];
m_currentFrame.TimeMS += (int)timerInterval; m_currentFrame.TimeMS += (int)tickDuration;
//force a update on a keyframe transition //force a update on a keyframe transition
update = true; update = true;
} }
m_currentFrame.TimeMS -= (int)timerInterval; m_currentFrame.TimeMS -= (int)tickDuration;
// Do the frame processing // Do the frame processing
double steps = (double)m_currentFrame.TimeMS / timerInterval; double steps = (double)m_currentFrame.TimeMS / tickDuration;
if (steps <= 0.0) if (steps <= 0.0)
{ {
@ -549,7 +622,7 @@ namespace OpenSim.Region.Framework.Scenes
m_group.AbsolutePosition = m_nextPosition; m_group.AbsolutePosition = m_nextPosition;
// we are sending imediate updates, no doing force a extra terseUpdate // we are sending imediate updates, no doing force a extra terseUpdate
// m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); // m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation);
m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation; m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation;
m_frames.RemoveAt(0); m_frames.RemoveAt(0);
@ -583,7 +656,7 @@ namespace OpenSim.Region.Framework.Scenes
Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete); Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete);
step.Normalize(); step.Normalize();
/* use simpler change detection /* use simpler change detection
* float angle = 0; * float angle = 0;
float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; 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 bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
@ -612,7 +685,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
if (angle > 0.01f) if (angle > 0.01f)
*/ */
if(Math.Abs(step.X - current.X) > 0.001f if(Math.Abs(step.X - current.X) > 0.001f
|| Math.Abs(step.Y - current.Y) > 0.001f || Math.Abs(step.Y - current.Y) > 0.001f
|| Math.Abs(step.Z - current.Z) > 0.001f) || Math.Abs(step.Z - current.Z) > 0.001f)
@ -629,23 +702,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
if (update) if (update)
{
m_group.SendGroupRootTerseUpdate(); m_group.SendGroupRootTerseUpdate();
// m_group.RootPart.ScheduleTerseUpdate();
}
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;
}
} }
} }
@ -677,7 +735,7 @@ namespace OpenSim.Region.Framework.Scenes
m_isCrossing = true; m_isCrossing = true;
m_waitingCrossing = true; m_waitingCrossing = true;
// to remove / retune to smoth crossings // to remove / retune to smoth crossings
if (m_group.RootPart.Velocity != Vector3.Zero) if (m_group.RootPart.Velocity != Vector3.Zero)
{ {
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.SendGroupRootTerseUpdate();
// m_group.RootPart.ScheduleTerseUpdate(); // m_group.RootPart.ScheduleTerseUpdate();
if (m_running && m_timer != null) if (m_running)
{ {
m_timer.Interval = 60000; StopTimer();
m_skipLoops = 1200; // 60 seconds
StartTimer(); StartTimer();
} }
} }

View File

@ -401,8 +401,6 @@ namespace OpenSim.Region.Framework.Scenes
if (item.Owner != remoteClient.AgentId) if (item.Owner != remoteClient.AgentId)
return; return;
if (UUID.Zero == transactionID)
{
item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255); item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
item.Name = itemUpd.Name; item.Name = itemUpd.Name;
item.Description = itemUpd.Description; item.Description = itemUpd.Description;
@ -412,6 +410,8 @@ namespace OpenSim.Region.Framework.Scenes
// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags, // itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions); // 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)) if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
@ -446,7 +446,8 @@ namespace OpenSim.Region.Framework.Scenes
InventoryService.UpdateItem(item); InventoryService.UpdateItem(item);
} }
else
if (UUID.Zero != transactionID)
{ {
if (AgentTransactionsModule != null) if (AgentTransactionsModule != null)
{ {

View File

@ -2769,8 +2769,6 @@ namespace OpenSim.Region.Framework.Scenes
if (newPosition != Vector3.Zero) if (newPosition != Vector3.Zero)
newObject.RootPart.GroupPosition = newPosition; newObject.RootPart.GroupPosition = newPosition;
if (newObject.RootPart.KeyframeMotion != null)
newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
if (!AddSceneObject(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. // before we restart the scripts, or else some functions won't work.
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
newObject.ResumeScripts(); 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 // 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); RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
if (AttachmentsModule != null) if (AttachmentsModule != null)
AttachmentsModule.AttachObject(sp, grp, 0, false, false, false); AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true);
} }
else else
{ {
@ -2970,6 +2971,13 @@ namespace OpenSim.Region.Framework.Scenes
SubscribeToClientEvents(client); SubscribeToClientEvents(client);
sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); 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); m_eventManager.TriggerOnNewPresence(sp);
sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; 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 // 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 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
if (closeChildAgents && CapsModule != null) 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 // // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
// // this method is doing is HORRIBLE!!! // // this method is doing is HORRIBLE!!!
@ -3846,10 +3854,25 @@ namespace OpenSim.Region.Framework.Scenes
return false; return false;
} }
ScenePresence sp = GetScenePresence(agent.AgentID); 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))
{
if (CapsModule != null)
{
lock (agent)
{
CapsModule.SetAgentCapsSeeds(agent);
CapsModule.CreateCaps(agent.AgentID, agent.circuitcode);
}
}
}
if (sp != null)
{
if (!sp.IsChildAgent)
{ {
// We have a zombie from a crashed session. // We have a zombie from a crashed session.
// Or the same user is trying to be root twice here, won't work. // Or the same user is trying to be root twice here, won't work.
@ -3861,6 +3884,7 @@ namespace OpenSim.Region.Framework.Scenes
sp.ControllingClient.Close(true, true); sp.ControllingClient.Close(true, true);
sp = null; sp = null;
} }
}
lock (agent) lock (agent)
{ {
@ -3900,9 +3924,11 @@ namespace OpenSim.Region.Framework.Scenes
if (vialogin || (!m_seeIntoBannedRegion)) if (vialogin || (!m_seeIntoBannedRegion))
{ {
if (!AuthorizeUser(agent, out reason)) if (!AuthorizeUser(agent, out reason))
{
return false; return false;
} }
} }
}
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
@ -3915,11 +3941,6 @@ namespace OpenSim.Region.Framework.Scenes
RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
agent.AgentID, agent.circuitcode); agent.AgentID, agent.circuitcode);
if (CapsModule != null)
{
CapsModule.SetAgentCapsSeeds(agent);
CapsModule.CreateCaps(agent.AgentID);
}
} }
else else
{ {
@ -3945,6 +3966,11 @@ namespace OpenSim.Region.Framework.Scenes
agent.teleportFlags = teleportFlags; agent.teleportFlags = teleportFlags;
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
if (CapsModule != null)
{
CapsModule.ActivateCaps(agent.circuitcode);
}
if (vialogin) if (vialogin)
{ {
// CleanDroppedAttachments(); // CleanDroppedAttachments();
@ -5122,7 +5148,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 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); DeleteSceneObject(grp, false);
} }
} }

View File

@ -1689,6 +1689,10 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup != null) if (ParentGroup != null)
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
PhysicsActor pa = PhysActor;
if (pa != null)
pa.Density = Density;
} }
} }
@ -1708,6 +1712,9 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup != null) if (ParentGroup != null)
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
PhysicsActor pa = PhysActor;
if (pa != null)
pa.GravModifier = GravityModifier;
} }
} }
@ -1726,10 +1733,14 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup != null) if (ParentGroup != null)
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
PhysicsActor pa = PhysActor;
if (pa != null)
pa.Friction = Friction;
} }
} }
public float Bounciness public float Restitution
{ {
get { return m_bounce; } get { return m_bounce; }
set set
@ -1744,6 +1755,10 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup != null) if (ParentGroup != null)
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
PhysicsActor pa = PhysActor;
if (pa != null)
pa.Restitution = Restitution;
} }
} }
@ -4493,8 +4508,8 @@ namespace OpenSim.Region.Framework.Scenes
GravityModifier = physdata.GravitationModifier; GravityModifier = physdata.GravitationModifier;
if(Friction != physdata.Friction) if(Friction != physdata.Friction)
Friction = physdata.Friction; Friction = physdata.Friction;
if(Bounciness != physdata.Bounce) if(Restitution != physdata.Bounce)
Bounciness = physdata.Bounce; Restitution = physdata.Bounce;
} }
/// <summary> /// <summary>
/// Update the flags on this prim. This covers properties such as phantom, physics and temporary. /// 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.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
pa.SetMaterial(Material); pa.SetMaterial(Material);
pa.Density = Density;
pa.GravModifier = GravityModifier;
pa.Friction = Friction;
pa.Restitution = Restitution;
if (VolumeDetectActive) // change if not the default only if (VolumeDetectActive) // change if not the default only
pa.SetVolumeDetect(1); pa.SetVolumeDetect(1);

View File

@ -204,6 +204,11 @@ namespace OpenSim.Region.Framework.Scenes
private const int LAND_VELOCITYMAG_MAX = 12; 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; private float m_health = 100f;
protected ulong crossingFromRegion; protected ulong crossingFromRegion;
@ -438,6 +443,8 @@ namespace OpenSim.Region.Framework.Scenes
get { return (IClientCore)ControllingClient; } get { return (IClientCore)ControllingClient; }
} }
public UUID COF { get; set; }
// public Vector3 ParentPosition { get; set; } // public Vector3 ParentPosition { get; set; }
/// <summary> /// <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 IsChildAgent { get; set; }
public bool IsLoggingIn { get; set; } public bool IsLoggingIn { get; set; }
@ -736,6 +751,8 @@ namespace OpenSim.Region.Framework.Scenes
#endregion #endregion
#region Constructor(s) #region Constructor(s)
public ScenePresence( public ScenePresence(
@ -1225,6 +1242,85 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.StopFlying(this); 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 // neighbouring regions we have enabled a child agent in
// holds the seed cap for the child agent in that region // holds the seed cap for the child agent in that region
private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
@ -1429,19 +1525,44 @@ namespace OpenSim.Region.Framework.Scenes
m_doingCamRayCast = false; m_doingCamRayCast = false;
if (hitYN && localid != LocalId) if (hitYN && localid != LocalId)
{
SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
bool IsPrim = group != null;
if (IsPrim)
{
SceneObjectPart part = group.GetPart(localid);
if (part != null && !part.VolumeDetectActive)
{ {
CameraConstraintActive = true; CameraConstraintActive = true;
pNormal.X = (float)Math.Round(pNormal.X, 2); pNormal.X = (float) Math.Round(pNormal.X, 2);
pNormal.Y = (float)Math.Round(pNormal.Y, 2); pNormal.Y = (float) Math.Round(pNormal.Y, 2);
pNormal.Z = (float)Math.Round(pNormal.Z, 2); pNormal.Z = (float) Math.Round(pNormal.Z, 2);
pNormal.Normalize(); pNormal.Normalize();
collisionPoint.X = (float)Math.Round(collisionPoint.X, 1); collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
collisionPoint.Y = (float)Math.Round(collisionPoint.Y, 1); collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
collisionPoint.Z = (float)Math.Round(collisionPoint.Z, 1); collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z, Vector3.Dot(collisionPoint, pNormal)); Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
Vector3.Dot(collisionPoint, pNormal));
UpdateCameraCollisionPlane(plane); 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) || else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
!Rotation.ApproxEquals(m_lastRotation, ROTATION_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) || bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_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) if (Flying && IsColliding && controlland)
{ {
// nesting this check because LengthSquared() is expensive and we don't // nesting this check because LengthSquared() is expensive and we don't

View File

@ -633,7 +633,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader) 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) 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()); writer.WriteElementString("Density", sop.Density.ToString().ToLower());
if (sop.Friction != 0.6f) if (sop.Friction != 0.6f)
writer.WriteElementString("Friction", sop.Friction.ToString().ToLower()); writer.WriteElementString("Friction", sop.Friction.ToString().ToLower());
if (sop.Bounciness != 0.5f) if (sop.Restitution != 0.5f)
writer.WriteElementString("Bounce", sop.Bounciness.ToString().ToLower()); writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower());
if (sop.GravityModifier != 1.0f) if (sop.GravityModifier != 1.0f)
writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower()); writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower());
WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset()); WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset());

View File

@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); 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;
} }
} }
} }

View File

@ -274,7 +274,7 @@ namespace OpenSim.Region.Physics.Manager
public virtual float Density { get; set; } public virtual float Density { get; set; }
public virtual float GravModifier { get; set; } public virtual float GravModifier { get; set; }
public virtual float Friction { get; set; } public virtual float Friction { get; set; }
public virtual float Bounce { get; set; } public virtual float Restitution { get; set; }
/// <summary> /// <summary>
/// Position of this actor. /// Position of this actor.

View File

@ -1014,8 +1014,8 @@ namespace OpenSim.Region.Physics.OdePlugin
offset.Y += contact.pos.Y; offset.Y += contact.pos.Y;
offset.Z += contact.pos.Z; offset.Z += contact.pos.Z;
_position = offset; //_position = offset;
return false; //return false;
} }
offset.X = contact.pos.X - _position.X; offset.X = contact.pos.X - _position.X;

View File

@ -3332,7 +3332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null) 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 else
return false; return false;
} }
@ -4724,7 +4724,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
UUID av = new UUID(); UUID av = new UUID();
if (!UUID.TryParse(agent,out av)) if (!UUID.TryParse(agent,out av))
{ {
//LSLError("First parameter to llDialog needs to be a key");
return; return;
} }
@ -7222,20 +7221,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
if (buttons.Length > 12) if (buttons.Length > 12)
{ {
LSLError("No more than 12 buttons can be shown"); ShoutError("button list too long, must be 12 or fewer entries");
return;
} }
string[] buts = new string[buttons.Length]; int length = buttons.Length;
for (int i = 0; i < buttons.Length; i++) if (length > 12)
length = 12;
string[] buts = new string[length];
for (int i = 0; i < length; i++)
{ {
if (buttons.Data[i].ToString() == String.Empty) if (buttons.Data[i].ToString() == String.Empty)
{ {
LSLError("button label cannot be blank"); ShoutError("button label cannot be blank");
return; return;
} }
if (buttons.Data[i].ToString().Length > 24) 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; return;
} }
buts[i] = buttons.Data[i].ToString(); buts[i] = buttons.Data[i].ToString();
@ -7843,7 +7845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType; physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
physdata.Density = part.Density; physdata.Density = part.Density;
physdata.Friction = part.Friction; physdata.Friction = part.Friction;
physdata.Bounce = part.Bounciness; physdata.Bounce = part.Restitution;
physdata.GravitationModifier = part.GravityModifier; physdata.GravitationModifier = part.GravityModifier;
if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0) if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
@ -8236,7 +8238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ExtraPhysicsData physdata = new ExtraPhysicsData(); ExtraPhysicsData physdata = new ExtraPhysicsData();
physdata.Density = part.Density; physdata.Density = part.Density;
physdata.Bounce = part.Bounciness; physdata.Bounce = part.Restitution;
physdata.GravitationModifier = part.GravityModifier; physdata.GravitationModifier = part.GravityModifier;
physdata.PhysShapeType = (PhysShapeType)shape_type; physdata.PhysShapeType = (PhysShapeType)shape_type;

View File

@ -123,7 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void modInvokeN(string fname, params object[] parms) public void modInvokeN(string fname, params object[] parms)
{ {
Type returntype = m_comms.LookupReturnType(fname); Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(string)) if (returntype != typeof(void))
MODError(String.Format("return type mismatch for {0}",fname)); MODError(String.Format("return type mismatch for {0}",fname));
modInvoke(fname,parms); modInvoke(fname,parms);
@ -264,6 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (result != null) if (result != null)
return result; 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)); MODError(String.Format("Invocation of {0} failed; null return value",fname));
} }
catch (Exception e) catch (Exception e)

View File

@ -1619,7 +1619,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
} }
public Object osParseJSONNew(string JSON) private Object osParseJSONNew(string JSON)
{ {
CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");

View File

@ -259,7 +259,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
string osGetScriptEngineName(); string osGetScriptEngineName();
string osGetSimulatorVersion(); string osGetSimulatorVersion();
Object osParseJSONNew(string JSON);
Hashtable osParseJSON(string JSON); Hashtable osParseJSON(string JSON);
void osMessageObject(key objectUUID,string message); void osMessageObject(key objectUUID,string message);

View File

@ -430,11 +430,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
return m_OSSL_Functions.osParseJSON(JSON); return m_OSSL_Functions.osParseJSON(JSON);
} }
public Object osParseJSONNew(string JSON)
{
return m_OSSL_Functions.osParseJSONNew(JSON);
}
public void osMessageObject(key objectUUID,string message) public void osMessageObject(key objectUUID,string message)
{ {
m_OSSL_Functions.osMessageObject(objectUUID,message); m_OSSL_Functions.osMessageObject(objectUUID,message);

View File

@ -512,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
else if (o is LSL_Types.LSLFloat) else if (o is LSL_Types.LSLFloat)
size += 8; size += 8;
else if (o is LSL_Types.LSLString) 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) else if (o is LSL_Types.key)
size += ((LSL_Types.key)o).value.Length; size += ((LSL_Types.key)o).value.Length;
else if (o is LSL_Types.Vector3) else if (o is LSL_Types.Vector3)

View File

@ -180,12 +180,19 @@ namespace OpenSim.Services.Interfaces
// Attachments // Attachments
List<AvatarAttachment> attachments = appearance.GetAttachments(); List<AvatarAttachment> attachments = appearance.GetAttachments();
Dictionary<int, List<string>> atts = new Dictionary<int, List<string>>();
foreach (AvatarAttachment attach in attachments) foreach (AvatarAttachment attach in attachments)
{ {
if (attach.ItemID != UUID.Zero) 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() public AvatarAppearance ToAvatarAppearance()
{ {
@ -320,10 +327,16 @@ namespace OpenSim.Services.Interfaces
if (!Int32.TryParse(pointStr, out point)) if (!Int32.TryParse(pointStr, out point))
continue; continue;
UUID uuid = UUID.Zero; List<string> idList = new List<string>(_kvp.Value.Split(new char[] {','}));
UUID.TryParse(_kvp.Value, out uuid);
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) if (appearance.Wearables[AvatarWearable.BODY].Count == 0)

View File

@ -1597,9 +1597,10 @@
<Reference name="System.Drawing"/> <Reference name="System.Drawing"/>
<Reference name="System.Xml"/> <Reference name="System.Xml"/>
<Reference name="System.Web"/> <Reference name="System.Web"/>
<Reference name="OpenMetaverse" path="../../../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../../../bin/"/> <Reference name="OpenMetaverse.StructuredData" path="../../../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../../../bin/"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Capabilities"/> <Reference name="OpenSim.Capabilities"/>
<Reference name="OpenSim.Capabilities.Handlers"/> <Reference name="OpenSim.Capabilities.Handlers"/>