Merge branch 'avination' into careminster

Conflicts:
	OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
	OpenSim/Region/Framework/Scenes/Scene.cs
avinationmerge
Melanie 2012-09-27 17:29:44 +01:00
commit 001ec0e2e6
36 changed files with 1664 additions and 502 deletions

View File

@ -187,7 +187,11 @@ namespace OpenSim.Capabilities.Handlers
response["headers"] = headers;
string range = String.Empty;
if (((Hashtable)request["headers"])["Range"] != null)
if (((Hashtable)request["headers"])["range"] != null)
range = (string)((Hashtable)request["headers"])["range"];
else if (((Hashtable)request["headers"])["Range"] != null)
range = (string)((Hashtable)request["headers"])["Range"];
if (!String.IsNullOrEmpty(range)) // JP2's only
@ -227,17 +231,22 @@ namespace OpenSim.Capabilities.Handlers
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
// Always return PartialContent, even if the range covered the entire data length
// We were accidentally sending back 404 before in this situation
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
response["content-type"] = texture.Metadata.ContentType;
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
byte[] d = new byte[len];
Array.Copy(texture.Data, start, d, 0, len);
response["bin_response_data"] = d;
if (start == 0 && len == texture.Data.Length) // well redudante maybe
{
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
response["bin_response_data"] = texture.Data;
}
else
{
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
byte[] d = new byte[len];
Array.Copy(texture.Data, start, d, 0, len);
response["bin_response_data"] = d;
}
// response.Body.Write(texture.Data, start, len);
}
}

View File

@ -30,12 +30,15 @@ using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
[LLSDType("MAP")]
public class LLSDAssetUploadComplete
{
public string new_asset = String.Empty;
public UUID new_inventory_item = UUID.Zero;
// public UUID new_texture_folder_id = UUID.Zero;
public string state = String.Empty;
public LLSDAssetUploadError error = null;
//public bool success = false;
public LLSDAssetUploadComplete()

View File

@ -45,6 +45,10 @@ namespace OpenSim.Framework.Capabilities
public string asset_type = String.Empty;
public string description = String.Empty;
public UUID folder_id = UUID.Zero;
public UUID texture_folder_id = UUID.Zero;
public int next_owner_mask = 0;
public int group_mask = 0;
public int everyone_mask = 0;
public string inventory_type = String.Empty;
public string name = String.Empty;
public LLSDAssetResource asset_resources = new LLSDAssetResource();

View File

@ -26,9 +26,17 @@
*/
using System;
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDAssetUploadError
{
public string message = String.Empty;
public UUID identifier = UUID.Zero;
}
[OSDMap]
public class LLSDAssetUploadResponsePricebrkDown
{
@ -56,11 +64,13 @@ namespace OpenSim.Framework.Capabilities
public string state = String.Empty;
public int upload_price = 0;
public LLSDAssetUploadResponseData data = null;
public LLSDAssetUploadError error = null;
public LLSDAssetUploadResponse()
{
}
}
[OSDMap]
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
{

View File

@ -150,7 +150,8 @@ namespace OpenSim.Framework
Type == (sbyte)AssetType.SnapshotFolder ||
Type == (sbyte)AssetType.TrashFolder ||
Type == (sbyte)AssetType.ImageJPEG ||
Type == (sbyte) AssetType.ImageTGA ||
Type == (sbyte)AssetType.ImageTGA ||
Type == (sbyte)AssetType.Mesh ||
Type == (sbyte) AssetType.LSLBytecode);
}
}

View File

@ -425,7 +425,7 @@ namespace OpenSim.Framework.Console
return false;
}
private Hashtable GetEvents(UUID RequestID, UUID sessionID, string request)
private Hashtable GetEvents(UUID RequestID, UUID sessionID)
{
ConsoleConnection c = null;

View File

@ -1171,6 +1171,7 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="Item"></param>
void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId);
void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId);
void SendRemoveInventoryItem(UUID itemID);

View File

@ -45,7 +45,8 @@ namespace OpenSim.Framework
/// <summary>
/// Total number of queues (priorities) available
/// </summary>
public const uint NumberOfQueues = 12;
public const uint NumberOfQueues = 12; // includes immediate queues, m_queueCounts need to be set acording
/// <summary>
/// Number of queuest (priorities) that are processed immediately
@ -60,7 +61,8 @@ namespace OpenSim.Framework
// each pass. weighted towards the higher priority queues
private uint m_nextQueue = 0;
private uint m_countFromQueue = 0;
private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 };
// first queues are imediate, so no counts
private uint[] m_queueCounts = {0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1};
// next request is a counter of the number of updates queued, it provides
// a total ordering on the updates coming through the queue and is more
@ -137,7 +139,7 @@ namespace OpenSim.Framework
/// </summary>
public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
{
// If there is anything in priority queue 0, return it first no
// If there is anything in imediate queues, return it first no
// matter what else. Breaks fairness. But very useful.
for (int iq = 0; iq < NumberOfImmediateQueues; iq++)
{
@ -172,14 +174,13 @@ namespace OpenSim.Framework
}
// Find the next non-immediate queue with updates in it
for (int i = 0; i < NumberOfQueues; ++i)
for (uint i = NumberOfImmediateQueues; i < NumberOfQueues; ++i)
{
m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues);
m_countFromQueue = m_queueCounts[m_nextQueue];
m_nextQueue++;
if(m_nextQueue >= NumberOfQueues)
m_nextQueue = NumberOfImmediateQueues;
// if this is one of the immediate queues, just skip it
if (m_nextQueue < NumberOfImmediateQueues)
continue;
m_countFromQueue = m_queueCounts[m_nextQueue];
if (m_heaps[m_nextQueue].Count > 0)
{
@ -189,7 +190,6 @@ namespace OpenSim.Framework
m_lookupTable.Remove(item.Value.Entity.LocalId);
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
value = item.Value;
return true;
}
}

View File

@ -334,6 +334,7 @@ namespace OpenSim.Framework.Servers.HttpServer
StreamReader reader = new StreamReader(requestStream, encoding);
string requestBody = reader.ReadToEnd();
reader.Close();
Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable();
@ -648,7 +649,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting
int tickdiff = requestEndTick - requestStartTick;
if (tickdiff > 3000 && requestHandler.Name != "GetTexture")
if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
{
m_log.InfoFormat(
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
@ -1555,6 +1556,8 @@ namespace OpenSim.Framework.Servers.HttpServer
else
responseString = (string)responsedata["str_response_string"];
contentType = (string)responsedata["content_type"];
if (responseString == null)
responseString = String.Empty;
}
catch
{

View File

@ -34,7 +34,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public delegate void RequestMethod(UUID requestID, Hashtable request);
public delegate bool HasEventsMethod(UUID requestID, UUID pId);
public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId, string request);
public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId);
public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId);
@ -46,7 +46,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public RequestMethod Request;
public UUID Id;
public int TimeOutms;
public EventType Type;
public EventType Type;
public enum EventType : int
{

View File

@ -33,6 +33,7 @@ using log4net;
using HttpServer;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using Amib.Threading;
/*
@ -185,6 +186,8 @@ namespace OpenSim.Framework.Servers.HttpServer
private bool m_running = true;
private int slowCount = 0;
private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
// private int m_timeout = 1000; // increase timeout 250; now use the event one
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
@ -202,7 +205,7 @@ namespace OpenSim.Framework.Servers.HttpServer
String.Format("PollServiceWorkerThread{0}", i),
ThreadPriority.Normal,
false,
true,
false,
null,
int.MaxValue);
}
@ -275,15 +278,7 @@ namespace OpenSim.Framework.Servers.HttpServer
Thread.Sleep(1000); // let the world move
foreach (Thread t in m_workerThreads)
{
try
{
t.Abort();
}
catch
{
}
}
Watchdog.AbortThread(t.ManagedThreadId);
try
{
@ -326,13 +321,9 @@ namespace OpenSim.Framework.Servers.HttpServer
private void PoolWorkerJob()
{
PollServiceHttpRequest req;
StreamReader str;
// while (true)
while (m_running)
{
req = m_requests.Dequeue(5000);
PollServiceHttpRequest req = m_requests.Dequeue(5000);
Watchdog.UpdateThread();
if (req != null)
@ -341,35 +332,41 @@ namespace OpenSim.Framework.Servers.HttpServer
{
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
{
try
{
str = new StreamReader(req.Request.Body);
}
catch (System.ArgumentException)
{
// Stream was not readable means a child agent
// was closed due to logout, leaving the
// Event Queue request orphaned.
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
if (responsedata == null)
continue;
}
try
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal)
{
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
DoHTTPGruntWork(m_server, req, responsedata);
try
{
DoHTTPGruntWork(m_server, req, responsedata);
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
{
// Ignore it, no need to reply
}
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
else
{
// Ignore it, no need to reply
m_threadPool.QueueWorkItem(x =>
{
try
{
DoHTTPGruntWork(m_server, req, responsedata);
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
{
// Ignore it, no need to reply
}
return null;
}, null);
}
str.Close();
}
else
{
// if ((Environment.TickCount - req.RequestTime) > m_timeout)
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{
DoHTTPGruntWork(m_server, req,

View File

@ -0,0 +1,671 @@
// Proprietary code of Avination Virtual Limited
// (c) 2012 Melanie Thielker, Leal Duarte
//
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Capabilities;
using ComponentAce.Compression.Libs.zlib;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.ClientStack.Linden
{
public struct ModelPrimLimits
{
}
public class ModelCost
{
// upload fee defaults
// fees are normalized to 1.0
// this parameters scale them to basic cost ( so 1.0 translates to 10 )
public float ModelMeshCostFactor = 0.0f; // scale total cost relative to basic (excluding textures)
public float ModelTextureCostFactor = 1.0f; // scale textures fee to basic.
public float ModelMinCostFactor = 0.0f; // 0.5f; // minimum total model free excluding textures
// itens costs in normalized values
// ie will be multiplied by basicCost and factors above
public float primCreationCost = 0.002f; // extra cost for each prim creation overhead
// weigthed size to normalized cost
public float bytecost = 1e-5f;
// mesh upload fees based on compressed data sizes
// several data sections are counted more that once
// to promote user optimization
// following parameters control how many extra times they are added
// to global size.
// LOD meshs
const float medSizeWth = 1f; // 2x
const float lowSizeWth = 1.5f; // 2.5x
const float lowestSizeWth = 2f; // 3x
// favor potencially physical optimized meshs versus automatic decomposition
const float physMeshSizeWth = 6f; // counts 7x
const float physHullSizeWth = 8f; // counts 9x
// stream cost area factors
// more or less like SL
const float highLodFactor = 17.36f;
const float midLodFactor = 277.78f;
const float lowLodFactor = 1111.11f;
// physics cost is below, identical to SL, assuming shape type convex
// server cost is below identical to SL assuming non scripted non physical object
// internal
const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
// control prims dimensions
public float PrimScaleMin = 0.001f;
public float NonPhysicalPrimScaleMax = 256f;
public float PhysicalPrimScaleMax = 10f;
public int ObjectLinkedPartsMax = 512;
// storage for a single mesh asset cost parameters
private class ameshCostParam
{
// LOD sizes for size dependent streaming cost
public int highLODSize;
public int medLODSize;
public int lowLODSize;
public int lowestLODSize;
// normalized fee based on compressed data sizes
public float costFee;
// physics cost
public float physicsCost;
}
// calculates a mesh model costs
// returns false on error, with a reason on parameter error
// resources input LLSD request
// basicCost input region assets upload cost
// totalcost returns model total upload fee
// meshcostdata returns detailed costs for viewer
public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost,
LLSDAssetUploadResponseData meshcostdata, out string error, ref string warning)
{
totalcost = 0;
error = string.Empty;
if (resources == null ||
resources.instance_list == null ||
resources.instance_list.Array.Count == 0)
{
error = "missing model information.";
return false;
}
int numberInstances = resources.instance_list.Array.Count;
if( numberInstances > ObjectLinkedPartsMax )
{
error = "Model whould have more than " + ObjectLinkedPartsMax.ToString() + " linked prims";
return false;
}
meshcostdata.model_streaming_cost = 0.0;
meshcostdata.simulation_cost = 0.0;
meshcostdata.physics_cost = 0.0;
meshcostdata.resource_cost = 0.0;
meshcostdata.upload_price_breakdown.mesh_instance = 0;
meshcostdata.upload_price_breakdown.mesh_physics = 0;
meshcostdata.upload_price_breakdown.mesh_streaming = 0;
meshcostdata.upload_price_breakdown.model = 0;
int itmp;
// textures cost
if (resources.texture_list != null && resources.texture_list.Array.Count > 0)
{
float textures_cost = (float)(resources.texture_list.Array.Count * basicCost);
textures_cost *= ModelTextureCostFactor;
itmp = (int)(textures_cost + 0.5f); // round
meshcostdata.upload_price_breakdown.texture = itmp;
totalcost += itmp;
}
// meshs assets cost
float meshsfee = 0;
int numberMeshs = 0;
bool haveMeshs = false;
List<ameshCostParam> meshsCosts = new List<ameshCostParam>();
if (resources.mesh_list != null && resources.mesh_list.Array.Count > 0)
{
numberMeshs = resources.mesh_list.Array.Count;
for (int i = 0; i < numberMeshs; i++)
{
ameshCostParam curCost = new ameshCostParam();
byte[] data = (byte[])resources.mesh_list.Array[i];
if (!MeshCost(data, curCost, out error))
{
return false;
}
meshsCosts.Add(curCost);
meshsfee += curCost.costFee;
}
haveMeshs = true;
}
// instances (prims) cost
int mesh;
int skipedSmall = 0;
for (int i = 0; i < numberInstances; i++)
{
Hashtable inst = (Hashtable)resources.instance_list.Array[i];
ArrayList ascale = (ArrayList)inst["scale"];
Vector3 scale;
double tmp;
tmp = (double)ascale[0];
scale.X = (float)tmp;
tmp = (double)ascale[1];
scale.Y = (float)tmp;
tmp = (double)ascale[2];
scale.Z = (float)tmp;
if (scale.X < PrimScaleMin || scale.Y < PrimScaleMin || scale.Z < PrimScaleMin)
{
skipedSmall++;
continue;
}
if (scale.X > NonPhysicalPrimScaleMax || scale.Y > NonPhysicalPrimScaleMax || scale.Z > NonPhysicalPrimScaleMax)
{
error = "Model contains parts with sides larger than " + NonPhysicalPrimScaleMax.ToString() + "m. Please ajust scale";
return false;
}
if (haveMeshs && inst.ContainsKey("mesh"))
{
mesh = (int)inst["mesh"];
if (mesh >= numberMeshs)
{
error = "Incoerent model information.";
return false;
}
// streamming cost
float sqdiam = scale.LengthSquared();
ameshCostParam curCost = meshsCosts[mesh];
float mesh_streaming = streamingCost(curCost, sqdiam);
meshcostdata.model_streaming_cost += mesh_streaming;
meshcostdata.physics_cost += curCost.physicsCost;
}
else // instance as no mesh ??
{
// to do later if needed
meshcostdata.model_streaming_cost += 0.5f;
meshcostdata.physics_cost += 1.0f;
}
// assume unscripted and static prim server cost
meshcostdata.simulation_cost += 0.5f;
// charge for prims creation
meshsfee += primCreationCost;
}
if (skipedSmall > 0)
{
if (skipedSmall > numberInstances / 2)
{
error = "Model contains too many prims smaller than " + PrimScaleMin.ToString() +
"m minimum allowed size. Please check scalling";
return false;
}
else
warning += skipedSmall.ToString() + " of the requested " +numberInstances.ToString() +
" model prims will not upload because they are smaller than " + PrimScaleMin.ToString() +
"m minimum allowed size. Please check scalling ";
}
if (meshcostdata.physics_cost <= meshcostdata.model_streaming_cost)
meshcostdata.resource_cost = meshcostdata.model_streaming_cost;
else
meshcostdata.resource_cost = meshcostdata.physics_cost;
if (meshcostdata.resource_cost < meshcostdata.simulation_cost)
meshcostdata.resource_cost = meshcostdata.simulation_cost;
// scale cost
// at this point a cost of 1.0 whould mean basic cost
meshsfee *= ModelMeshCostFactor;
if (meshsfee < ModelMinCostFactor)
meshsfee = ModelMinCostFactor;
// actually scale it to basic cost
meshsfee *= (float)basicCost;
meshsfee += 0.5f; // rounding
totalcost += (int)meshsfee;
// breakdown prices
// don't seem to be in use so removed code for now
return true;
}
// single mesh asset cost
private bool MeshCost(byte[] data, ameshCostParam cost, out string error)
{
cost.highLODSize = 0;
cost.medLODSize = 0;
cost.lowLODSize = 0;
cost.lowestLODSize = 0;
cost.physicsCost = 0.0f;
cost.costFee = 0.0f;
error = string.Empty;
if (data == null || data.Length == 0)
{
error = "Missing model information.";
return false;
}
OSD meshOsd = null;
int start = 0;
error = "Invalid model data";
using (MemoryStream ms = new MemoryStream(data))
{
try
{
OSD osd = OSDParser.DeserializeLLSDBinary(ms);
if (osd is OSDMap)
meshOsd = (OSDMap)osd;
else
return false;
}
catch (Exception e)
{
return false;
}
start = (int)ms.Position;
}
OSDMap map = (OSDMap)meshOsd;
OSDMap tmpmap;
int highlod_size = 0;
int medlod_size = 0;
int lowlod_size = 0;
int lowestlod_size = 0;
int skin_size = 0;
int hulls_size = 0;
int phys_nhulls;
int phys_hullsvertices = 0;
int physmesh_size = 0;
int phys_ntriangles = 0;
int submesh_offset = -1;
if (map.ContainsKey("physics_convex"))
{
tmpmap = (OSDMap)map["physics_convex"];
if (tmpmap.ContainsKey("offset"))
submesh_offset = tmpmap["offset"].AsInteger() + start;
if (tmpmap.ContainsKey("size"))
hulls_size = tmpmap["size"].AsInteger();
}
if (submesh_offset < 0 || hulls_size == 0)
{
error = "Missing physics_convex block";
return false;
}
if (!hulls(data, submesh_offset, hulls_size, out phys_hullsvertices, out phys_nhulls))
{
error = "Bad physics_convex block";
return false;
}
submesh_offset = -1;
// only look for LOD meshs sizes
if (map.ContainsKey("high_lod"))
{
tmpmap = (OSDMap)map["high_lod"];
// see at least if there is a offset for this one
if (tmpmap.ContainsKey("offset"))
submesh_offset = tmpmap["offset"].AsInteger() + start;
if (tmpmap.ContainsKey("size"))
highlod_size = tmpmap["size"].AsInteger();
}
if (submesh_offset < 0 || highlod_size <= 0)
{
error = "Missing high_lod block";
return false;
}
bool haveprev = true;
if (map.ContainsKey("medium_lod"))
{
tmpmap = (OSDMap)map["medium_lod"];
if (tmpmap.ContainsKey("size"))
medlod_size = tmpmap["size"].AsInteger();
else
haveprev = false;
}
if (haveprev && map.ContainsKey("low_lod"))
{
tmpmap = (OSDMap)map["low_lod"];
if (tmpmap.ContainsKey("size"))
lowlod_size = tmpmap["size"].AsInteger();
else
haveprev = false;
}
if (haveprev && map.ContainsKey("lowest_lod"))
{
tmpmap = (OSDMap)map["lowest_lod"];
if (tmpmap.ContainsKey("size"))
lowestlod_size = tmpmap["size"].AsInteger();
}
if (map.ContainsKey("skin"))
{
tmpmap = (OSDMap)map["skin"];
if (tmpmap.ContainsKey("size"))
skin_size = tmpmap["size"].AsInteger();
}
cost.highLODSize = highlod_size;
cost.medLODSize = medlod_size;
cost.lowLODSize = lowlod_size;
cost.lowestLODSize = lowestlod_size;
submesh_offset = -1;
tmpmap = null;
if(map.ContainsKey("physics_mesh"))
tmpmap = (OSDMap)map["physics_mesh"];
else if (map.ContainsKey("physics_shape")) // old naming
tmpmap = (OSDMap)map["physics_shape"];
if(tmpmap != null)
{
if (tmpmap.ContainsKey("offset"))
submesh_offset = tmpmap["offset"].AsInteger() + start;
if (tmpmap.ContainsKey("size"))
physmesh_size = tmpmap["size"].AsInteger();
if (submesh_offset >= 0 || physmesh_size > 0)
{
if (!submesh(data, submesh_offset, physmesh_size, out phys_ntriangles))
{
error = "Model data parsing error";
return false;
}
}
}
// upload is done in convex shape type so only one hull
phys_hullsvertices++;
cost.physicsCost = 0.04f * phys_hullsvertices;
float sfee;
sfee = data.Length; // start with total compressed data size
// penalize lod meshs that should be more builder optimized
sfee += medSizeWth * medlod_size;
sfee += lowSizeWth * lowlod_size;
sfee += lowestSizeWth * lowlod_size;
// physics
// favor potencial optimized meshs versus automatic decomposition
if (physmesh_size != 0)
sfee += physMeshSizeWth * (physmesh_size + hulls_size / 4); // reduce cost of mandatory convex hull
else
sfee += physHullSizeWth * hulls_size;
// bytes to money
sfee *= bytecost;
cost.costFee = sfee;
return true;
}
// parses a LOD or physics mesh component
private bool submesh(byte[] data, int offset, int size, out int ntriangles)
{
ntriangles = 0;
OSD decodedMeshOsd = new OSD();
byte[] meshBytes = new byte[size];
System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
try
{
using (MemoryStream inMs = new MemoryStream(meshBytes))
{
using (MemoryStream outMs = new MemoryStream())
{
using (ZOutputStream zOut = new ZOutputStream(outMs))
{
byte[] readBuffer = new byte[4096];
int readLen = 0;
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
zOut.Write(readBuffer, 0, readLen);
}
zOut.Flush();
outMs.Seek(0, SeekOrigin.Begin);
byte[] decompressedBuf = outMs.GetBuffer();
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
}
}
}
}
catch (Exception e)
{
return false;
}
OSDArray decodedMeshOsdArray = null;
if ((!decodedMeshOsd is OSDArray))
return false;
byte[] dummy;
decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
foreach (OSD subMeshOsd in decodedMeshOsdArray)
{
if (subMeshOsd is OSDMap)
{
OSDMap subtmpmap = (OSDMap)subMeshOsd;
if (subtmpmap.ContainsKey("NoGeometry") && ((OSDBoolean)subtmpmap["NoGeometry"]))
continue;
if (!subtmpmap.ContainsKey("Position"))
return false;
if (subtmpmap.ContainsKey("TriangleList"))
{
dummy = subtmpmap["TriangleList"].AsBinary();
ntriangles += dummy.Length / bytesPerCoord;
}
else
return false;
}
}
return true;
}
// parses convex hulls component
private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
{
nvertices = 0;
nhulls = 1;
OSD decodedMeshOsd = new OSD();
byte[] meshBytes = new byte[size];
System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
try
{
using (MemoryStream inMs = new MemoryStream(meshBytes))
{
using (MemoryStream outMs = new MemoryStream())
{
using (ZOutputStream zOut = new ZOutputStream(outMs))
{
byte[] readBuffer = new byte[4096];
int readLen = 0;
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
zOut.Write(readBuffer, 0, readLen);
}
zOut.Flush();
outMs.Seek(0, SeekOrigin.Begin);
byte[] decompressedBuf = outMs.GetBuffer();
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
}
}
}
}
catch (Exception e)
{
return false;
}
OSDMap cmap = (OSDMap)decodedMeshOsd;
if (cmap == null)
return false;
byte[] dummy;
// must have one of this
if (cmap.ContainsKey("BoundingVerts"))
{
dummy = cmap["BoundingVerts"].AsBinary();
nvertices = dummy.Length / bytesPerCoord;
}
else
return false;
/* upload is done with convex shape type
if (cmap.ContainsKey("HullList"))
{
dummy = cmap["HullList"].AsBinary();
nhulls += dummy.Length;
}
if (cmap.ContainsKey("Positions"))
{
dummy = cmap["Positions"].AsBinary();
nvertices = dummy.Length / bytesPerCoord;
}
*/
return true;
}
// returns streaming cost from on mesh LODs sizes in curCost and square of prim size length
private float streamingCost(ameshCostParam curCost, float sqdiam)
{
// compute efective areas
float ma = 262144f;
float mh = sqdiam * highLodFactor;
if (mh > ma)
mh = ma;
float mm = sqdiam * midLodFactor;
if (mm > ma)
mm = ma;
float ml = sqdiam * lowLodFactor;
if (ml > ma)
ml = ma;
float mlst = ma;
mlst -= ml;
ml -= mm;
mm -= mh;
if (mlst < 1.0f)
mlst = 1.0f;
if (ml < 1.0f)
ml = 1.0f;
if (mm < 1.0f)
mm = 1.0f;
if (mh < 1.0f)
mh = 1.0f;
ma = mlst + ml + mm + mh;
// get LODs compressed sizes
// giving 384 bytes bonus
int lst = curCost.lowestLODSize - 384;
int l = curCost.lowLODSize - 384;
int m = curCost.medLODSize - 384;
int h = curCost.highLODSize - 384;
// use previus higher LOD size on missing ones
if (m <= 0)
m = h;
if (l <= 0)
l = m;
if (lst <= 0)
lst = l;
// force minumum sizes
if (lst < 16)
lst = 16;
if (l < 16)
l = 16;
if (m < 16)
m = 16;
if (h < 16)
h = 16;
// compute cost weighted by relative effective areas
float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh;
cost /= ma;
cost *= 0.004f; // overall tunning parameter
return cost;
}
}
}

View File

@ -419,7 +419,7 @@ namespace OpenSim.Region.ClientStack.Linden
}
}
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
public Hashtable GetEvents(UUID requestID, UUID pAgentId)
{
if (DebugLevel >= 2)
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);

View File

@ -53,6 +53,14 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
public class GetTextureModule : INonSharedRegionModule
{
struct aPollRequest
{
public PollServiceTextureEventArgs thepoll;
public UUID reqID;
public Hashtable request;
}
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
@ -64,8 +72,8 @@ namespace OpenSim.Region.ClientStack.Linden
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
private static Thread[] m_workerThreads = null;
private static OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs> m_queue =
new OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs>();
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
new OpenMetaverse.BlockingQueue<aPollRequest>();
#region ISharedRegionModule Members
@ -104,7 +112,7 @@ namespace OpenSim.Region.ClientStack.Linden
String.Format("TextureWorkerThread{0}", i),
ThreadPriority.Normal,
false,
true,
false,
null,
int.MaxValue);
}
@ -129,7 +137,8 @@ namespace OpenSim.Region.ClientStack.Linden
~GetTextureModule()
{
foreach (Thread t in m_workerThreads)
t.Abort();
Watchdog.AbortThread(t.ManagedThreadId);
}
private class PollServiceTextureEventArgs : PollServiceEventArgs
@ -142,40 +151,50 @@ namespace OpenSim.Region.ClientStack.Linden
private Scene m_scene;
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
base(null, null, null, null, pId, 30000)
base(null, null, null, null, pId, int.MaxValue)
{
m_scene = scene;
HasEvents = (x, y) => { return this.responses.ContainsKey(x); };
GetEvents = (x, y, s) =>
HasEvents = (x, y) =>
{
try
lock (responses)
return responses.ContainsKey(x);
};
GetEvents = (x, y) =>
{
lock (responses)
{
return this.responses[x];
}
finally
{
responses.Remove(x);
try
{
return responses[x];
}
finally
{
responses.Remove(x);
}
}
};
Request = (x, y) =>
{
y["RequestID"] = x.ToString();
lock (this.requests)
this.requests.Add(y);
aPollRequest reqinfo = new aPollRequest();
reqinfo.thepoll = this;
reqinfo.reqID = x;
reqinfo.request = y;
m_queue.Enqueue(this);
m_queue.Enqueue(reqinfo);
};
// this should never happen except possible on shutdown
NoEvents = (x, y) =>
{
lock (this.requests)
/*
lock (requests)
{
Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
requests.Remove(request);
}
*/
Hashtable response = new Hashtable();
response["int_response_code"] = 500;
@ -188,25 +207,11 @@ namespace OpenSim.Region.ClientStack.Linden
};
}
public void Process()
public void Process(aPollRequest requestinfo)
{
Hashtable response;
Hashtable request = null;
try
{
lock (this.requests)
{
request = requests[0];
requests.RemoveAt(0);
}
}
catch
{
return;
}
UUID requestID = new UUID(request["RequestID"].ToString());
UUID requestID = requestinfo.reqID;
// If the avatar is gone, don't bother to get the texture
if (m_scene.GetScenePresence(Id) == null)
@ -219,13 +224,15 @@ namespace OpenSim.Region.ClientStack.Linden
response["keepalive"] = false;
response["reusecontext"] = false;
responses[requestID] = response;
lock (responses)
responses[requestID] = response;
return;
}
response = m_getTextureHandler.Handle(request);
responses[requestID] = response;
response = m_getTextureHandler.Handle(requestinfo.request);
lock (responses)
responses[requestID] = response;
}
}
@ -233,8 +240,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
string capUrl = "/CAPS/" + UUID.Random() + "/";
// Register this as a poll service
// absurd large timeout to tune later to make a bit less than viewer
// Register this as a poll service
PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
args.Type = PollServiceEventArgs.EventType.Texture;
@ -270,11 +276,10 @@ namespace OpenSim.Region.ClientStack.Linden
{
while (true)
{
PollServiceTextureEventArgs args = m_queue.Dequeue();
aPollRequest poolreq = m_queue.Dequeue();
args.Process();
poolreq.thepoll.Process(poolreq);
}
}
}
}

View File

@ -129,15 +129,15 @@ namespace OpenSim.Region.ClientStack.Linden
// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
OSDMap data = new OSDMap();
ScenePresence sp = m_scene.GetScenePresence(m_agentID);
data["username"] = sp.Firstname + "." + sp.Lastname;
data["display_name_next_update"] = new OSDDate(DateTime.Now);
data["legacy_first_name"] = sp.Firstname;
// ScenePresence sp = m_scene.GetScenePresence(m_agentID);
// data["username"] = sp.Firstname + "." + sp.Lastname;
// data["display_name_next_update"] = new OSDDate(DateTime.Now);
// data["legacy_first_name"] = sp.Firstname;
data["mesh_upload_status"] = "valid";
data["display_name"] = sp.Firstname + " " + sp.Lastname;
data["legacy_last_name"] = sp.Lastname;
data["id"] = m_agentID;
data["is_display_name_default"] = true;
// data["display_name"] = sp.Firstname + " " + sp.Lastname;
// data["legacy_last_name"] = sp.Lastname;
// data["id"] = m_agentID;
// data["is_display_name_default"] = true;
//Send back data
Hashtable responsedata = new Hashtable();

View File

@ -52,6 +52,13 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class WebFetchInvDescModule : INonSharedRegionModule
{
struct aPollRequest
{
public PollServiceInventoryEventArgs thepoll;
public UUID reqID;
public Hashtable request;
}
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
@ -64,8 +71,8 @@ namespace OpenSim.Region.ClientStack.Linden
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
private static Thread[] m_workerThreads = null;
private static OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs> m_queue =
new OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs>();
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
new OpenMetaverse.BlockingQueue<aPollRequest>();
#region ISharedRegionModule Members
@ -131,49 +138,52 @@ namespace OpenSim.Region.ClientStack.Linden
~WebFetchInvDescModule()
{
foreach (Thread t in m_workerThreads)
t.Abort();
Watchdog.AbortThread(t.ManagedThreadId);
}
private class PollServiceInventoryEventArgs : PollServiceEventArgs
{
private List<Hashtable> requests =
new List<Hashtable>();
private Dictionary<UUID, Hashtable> responses =
new Dictionary<UUID, Hashtable>();
public PollServiceInventoryEventArgs(UUID pId) :
base(null, null, null, null, pId, 30000)
base(null, null, null, null, pId, int.MaxValue)
{
HasEvents = (x, y) => { return this.responses.ContainsKey(x); };
GetEvents = (x, y, s) =>
HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); };
GetEvents = (x, y) =>
{
try
lock (responses)
{
return this.responses[x];
}
finally
{
responses.Remove(x);
try
{
return responses[x];
}
finally
{
responses.Remove(x);
}
}
};
Request = (x, y) =>
{
y["RequestID"] = x.ToString();
lock (this.requests)
this.requests.Add(y);
aPollRequest reqinfo = new aPollRequest();
reqinfo.thepoll = this;
reqinfo.reqID = x;
reqinfo.request = y;
m_queue.Enqueue(this);
m_queue.Enqueue(reqinfo);
};
NoEvents = (x, y) =>
{
lock (this.requests)
/*
lock (requests)
{
Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
requests.Remove(request);
}
*/
Hashtable response = new Hashtable();
response["int_response_code"] = 500;
@ -186,24 +196,9 @@ namespace OpenSim.Region.ClientStack.Linden
};
}
public void Process()
public void Process(aPollRequest requestinfo)
{
Hashtable request = null;
try
{
lock (this.requests)
{
request = requests[0];
requests.RemoveAt(0);
}
}
catch
{
return;
}
UUID requestID = new UUID(request["RequestID"].ToString());
UUID requestID = requestinfo.reqID;
Hashtable response = new Hashtable();
@ -212,9 +207,11 @@ namespace OpenSim.Region.ClientStack.Linden
response["keepalive"] = false;
response["reusecontext"] = false;
response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(request["body"].ToString(), String.Empty, String.Empty, null, null);
response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(
requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null);
responses[requestID] = response;
lock (responses)
responses[requestID] = response;
}
}
@ -222,8 +219,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
string capUrl = "/CAPS/" + UUID.Random() + "/";
// Register this as a poll service
// absurd large timeout to tune later to make a bit less than viewer
// Register this as a poll service
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID);
args.Type = PollServiceEventArgs.EventType.Inventory;
@ -259,9 +255,9 @@ namespace OpenSim.Region.ClientStack.Linden
{
while (true)
{
PollServiceInventoryEventArgs args = m_queue.Dequeue();
aPollRequest poolreq = m_queue.Dequeue();
args.Process();
poolreq.thepoll.Process(poolreq);
}
}
}

View File

@ -2066,8 +2066,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
}
/// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
{
SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
}
/// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
{
const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
@ -2078,6 +2083,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// TODO: don't create new blocks if recycling an old packet
InventoryReply.AgentData.AgentID = AgentId;
InventoryReply.AgentData.SimApproved = true;
InventoryReply.AgentData.TransactionID = transactionID;
InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
InventoryReply.InventoryData[0].ItemID = Item.ID;

View File

@ -143,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
}
}
public void RequestCreateInventoryItem(IClientAPI remoteClient,
public bool RequestCreateInventoryItem(IClientAPI remoteClient,
UUID transactionID, UUID folderID, uint callbackID,
string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
@ -153,6 +153,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
uploader.RequestCreateInventoryItem(
remoteClient, folderID, callbackID,
description, name, invType, type, wearableType, nextOwnerMask);
return true;
}
public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
@ -172,4 +174,4 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
uploader.RequestUpdateInventoryItem(remoteClient, item);
}
}
}
}

View File

@ -158,7 +158,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// <param name="type"></param>
/// <param name="wearableType"></param>
/// <param name="nextOwnerMask"></param>
public void HandleItemCreationFromTransaction(IClientAPI remoteClient,
public bool HandleItemCreationFromTransaction(IClientAPI remoteClient,
UUID transactionID, UUID folderID, uint callbackID,
string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
AgentAssetTransactions transactions =
GetUserTransactions(remoteClient.AgentId);
transactions.RequestCreateInventoryItem(remoteClient, transactionID,
return transactions.RequestCreateInventoryItem(remoteClient, transactionID,
folderID, callbackID, description, name, invType, type,
wearableType, nextOwnerMask);
}

View File

@ -256,7 +256,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
if (sp.IsChildAgent)
return;
sp.ControllingClient.Kick(reason);
sp.Scene.IncomingCloseAgent(sp.UUID);
sp.MakeChildAgent();
sp.ControllingClient.Close();
}
private void OnIncomingInstantMessage(GridInstantMessage msg)

View File

@ -663,7 +663,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
//
// This sleep can be increased if necessary. However, whilst it's active,
// an agent cannot teleport back to this region if it has teleported away.
Thread.Sleep(2000);
Thread.Sleep(3000);
sp.Scene.IncomingCloseAgent(sp.UUID, false);
}

View File

@ -186,45 +186,44 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (folder == null || folder.Owner != remoteClient.AgentId)
return;
if (transactionID == UUID.Zero)
{
ScenePresence presence;
if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
byte[] data = null;
if (invType == (sbyte)InventoryType.Landmark && presence != null)
{
string suffix = string.Empty, prefix = string.Empty;
string strdata = GenerateLandmark(presence, out prefix, out suffix);
data = Encoding.ASCII.GetBytes(strdata);
name = prefix + name;
description += suffix;
}
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
m_Scene.AssetService.Store(asset);
m_Scene.CreateNewInventoryItem(
remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
}
else
{
m_log.ErrorFormat(
"[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
remoteClient.AgentId);
}
}
else
if (transactionID != UUID.Zero)
{
IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
if (agentTransactions != null)
{
agentTransactions.HandleItemCreationFromTransaction(
if (agentTransactions.HandleItemCreationFromTransaction(
remoteClient, transactionID, folderID, callbackID, description,
name, invType, assetType, wearableType, nextOwnerMask);
name, invType, assetType, wearableType, nextOwnerMask))
return;
}
}
ScenePresence presence;
if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
byte[] data = null;
if (invType == (sbyte)InventoryType.Landmark && presence != null)
{
string suffix = string.Empty, prefix = string.Empty;
string strdata = GenerateLandmark(presence, out prefix, out suffix);
data = Encoding.ASCII.GetBytes(strdata);
name = prefix + name;
description += suffix;
}
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
m_Scene.AssetService.Store(asset);
m_Scene.CreateNewInventoryItem(
remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID);
}
else
{
m_log.ErrorFormat(
"[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
remoteClient.AgentId);
}
}
protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)

View File

@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
}
}
}
private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
private Hashtable GetEvents(UUID requestID, UUID sessionID)
{
UrlData url = null;
RequestData requestData = null;

View File

@ -36,7 +36,7 @@ namespace OpenSim.Region.Framework.Interfaces
void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID,
InventoryItemBase item);
void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID,
bool HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask);

View File

@ -904,11 +904,22 @@ namespace OpenSim.Region.Framework.Scenes
public void CreateNewInventoryItem(
IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
string name, string description, uint flags, uint callbackID,
AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate, UUID transationID)
{
CreateNewInventoryItem(
remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, asset, invType,
(uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
(uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate, transationID);
}
private void CreateNewInventoryItem(
IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
string name, string description, uint flags, uint callbackID, AssetBase asset, sbyte invType,
uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
{
CreateNewInventoryItem(remoteClient, creatorID, creatorData, folderID,
name, description, flags, callbackID, asset, invType,
baseMask, currentMask, everyoneMask, nextOwnerMask, groupMask, creationDate, UUID.Zero);
}
/// <summary>
@ -933,7 +944,7 @@ namespace OpenSim.Region.Framework.Scenes
private void CreateNewInventoryItem(
IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
string name, string description, uint flags, uint callbackID, AssetBase asset, sbyte invType,
uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate,UUID transationID)
{
InventoryItemBase item = new InventoryItemBase();
item.Owner = remoteClient.AgentId;
@ -956,7 +967,7 @@ namespace OpenSim.Region.Framework.Scenes
if (AddInventoryItem(item))
{
remoteClient.SendInventoryItemCreateUpdate(item, callbackID);
remoteClient.SendInventoryItemCreateUpdate(item, transationID, callbackID);
}
else
{

View File

@ -4372,7 +4372,7 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
if (presence != null)
{
presence.ControllingClient.Close(true, force);
presence.ControllingClient.Close(force, force);
return true;
}

View File

@ -2146,10 +2146,10 @@ namespace OpenSim.Region.Framework.Scenes
{
if (asset != null)
SculptTextureCallback(asset);
else
m_log.WarnFormat(
"[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
Name, UUID, id);
// else
// m_log.WarnFormat(
// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
// Name, UUID, id);
}
/// <summary>

View File

@ -1100,7 +1100,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
{
}
public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
{
}
public void SendRemoveInventoryItem(UUID itemID)

View File

@ -739,6 +739,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
}
public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
{
}
public virtual void SendRemoveInventoryItem(UUID itemID)
{
}

View File

@ -902,7 +902,7 @@ namespace OpenSim.Region.Physics.OdePlugin
axis.X = (axis.X > 0) ? 1f : 0f;
axis.Y = (axis.Y > 0) ? 1f : 0f;
axis.Z = (axis.Z > 0) ? 1f : 0f;
m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
// m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
AddChange(changes.AngLock, axis);
}
else

View File

@ -10149,31 +10149,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
UUID key = new UUID();
if (UUID.TryParse(id, out key))
{
try
{
/*
SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
if (obj != null)
return (double)obj.GetMass();
*/
// return total object mass
SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
if (obj != null)
return obj.GetMass();
// return total object mass
SceneObjectPart part = World.GetSceneObjectPart(key);
if (part != null)
return part.ParentGroup.GetMass();
// the object is null so the key is for an avatar
ScenePresence avatar = World.GetScenePresence(key);
if (avatar != null)
if (avatar.IsChildAgent)
// reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
// child agents have a mass of 1.0
return 1;
else
return (double)avatar.GetMass();
}
catch (KeyNotFoundException)
// the object is null so the key is for an avatar
ScenePresence avatar = World.GetScenePresence(key);
if (avatar != null)
{
return 0; // The Object/Agent not in the region so just return zero
if (avatar.IsChildAgent)
{
// reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
// child agents have a mass of 1.0
return 1;
}
else
{
return (double)avatar.GetMass();
}
}
}
return 0;

View File

@ -443,7 +443,15 @@ namespace OpenSim.Server.Handlers.Simulation
// subclasses can override this
protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason)
{
return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason);
reason = String.Empty;
Util.FireAndForget(x =>
{
string r;
m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out r);
});
return true;
}
}

View File

@ -27,6 +27,7 @@
using log4net;
using System;
using System.Threading;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
@ -50,7 +51,7 @@ namespace OpenSim.Services.Connectors
private IImprovedAssetCache m_Cache = null;
private int m_retryCounter;
private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>();
private Timer m_retryTimer;
private System.Timers.Timer m_retryTimer;
private delegate void AssetRetrievedEx(AssetBase asset);
// Keeps track of concurrent requests for the same asset, so that it's only loaded once.
@ -61,6 +62,8 @@ namespace OpenSim.Services.Connectors
private Dictionary<string, string> m_UriMap = new Dictionary<string, string>();
private Thread[] m_fetchThreads;
public AssetServicesConnector()
{
}
@ -96,7 +99,7 @@ namespace OpenSim.Services.Connectors
}
m_retryTimer = new Timer();
m_retryTimer = new System.Timers.Timer();
m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck);
m_retryTimer.Interval = 60000;
@ -112,6 +115,14 @@ namespace OpenSim.Services.Connectors
m_UriMap[prefix] = groupHost;
//m_log.DebugFormat("[ASSET]: Using {0} for prefix {1}", groupHost, prefix);
}
m_fetchThreads = new Thread[2];
for (int i = 0 ; i < 2 ; i++)
{
m_fetchThreads[i] = new Thread(AssetRequestProcessor);
m_fetchThreads[i].Start();
}
}
private string MapServer(string id)
@ -261,6 +272,66 @@ namespace OpenSim.Services.Connectors
return null;
}
private class QueuedAssetRequest
{
public string uri;
public string id;
}
private OpenMetaverse.BlockingQueue<QueuedAssetRequest> m_requestQueue =
new OpenMetaverse.BlockingQueue<QueuedAssetRequest>();
private void AssetRequestProcessor()
{
QueuedAssetRequest r;
while (true)
{
r = m_requestQueue.Dequeue();
string uri = r.uri;
string id = r.id;
bool success = false;
try
{
AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0,
delegate(AssetBase a)
{
if (m_Cache != null)
m_Cache.Cache(a);
List<AssetRetrievedEx> handlers;
lock (m_AssetHandlers)
{
handlers = m_AssetHandlers[id];
m_AssetHandlers.Remove(id);
}
foreach (AssetRetrievedEx h in handlers)
h.Invoke(a);
if (handlers != null)
handlers.Clear();
}, 30);
success = true;
}
finally
{
if (!success)
{
List<AssetRetrievedEx> handlers;
lock (m_AssetHandlers)
{
handlers = m_AssetHandlers[id];
m_AssetHandlers.Remove(id);
}
if (handlers != null)
handlers.Clear();
}
}
}
}
public bool Get(string id, Object sender, AssetRetrieved handler)
{
string uri = MapServer(id) + "/assets/" + id;
@ -293,52 +364,11 @@ namespace OpenSim.Services.Connectors
m_AssetHandlers.Add(id, handlers);
}
bool success = false;
try
{
AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0,
delegate(AssetBase a)
{
if (m_Cache != null)
m_Cache.Cache(a);
/*
AssetRetrievedEx handlers;
lock (m_AssetHandlers)
{
handlers = m_AssetHandlers[id];
m_AssetHandlers.Remove(id);
}
QueuedAssetRequest request = new QueuedAssetRequest();
request.id = id;
request.uri = uri;
handlers.Invoke(a);
*/
List<AssetRetrievedEx> handlers;
lock (m_AssetHandlers)
{
handlers = m_AssetHandlers[id];
m_AssetHandlers.Remove(id);
}
foreach (AssetRetrievedEx h in handlers)
h.Invoke(a);
if (handlers != null)
handlers.Clear();
}, 30);
success = true;
}
finally
{
if (!success)
{
List<AssetRetrievedEx> handlers;
lock (m_AssetHandlers)
{
handlers = m_AssetHandlers[id];
m_AssetHandlers.Remove(id);
}
if (handlers != null)
handlers.Clear();
}
}
m_requestQueue.Enqueue(request);
}
else
{

View File

@ -716,6 +716,10 @@ namespace OpenSim.Tests.Common.Mock
{
}
public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
{
}
public virtual void SendRemoveInventoryItem(UUID itemID)
{
}

View File

@ -162,6 +162,7 @@
<Reference name="XMLRPC" path="../../../../bin/"/>
<Reference name="log4net" path="../../../../bin/"/>
<Reference name="HttpServer_OpenSim" path="../../../../bin/"/>
<Reference name="SmartThreadPool"/>
<Files>
<Match pattern="*.cs" recurse="true">
@ -1703,7 +1704,7 @@
<Reference name="OpenSim.Capabilities"/>
<Reference name="OpenSim.Capabilities.Handlers"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Console"/>
@ -1713,6 +1714,7 @@
<Reference name="Nini" path="../../../../../bin/"/>
<Reference name="log4net" path="../../../../../bin/"/>
<Reference name="Nini" path="../../../../../bin/"/>
<Reference name="zlib.net" path="../../../../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true">