Another attempt to fix the image sending bug (next week, I intend to rewrite the assetcache and asset server).

Attempt to fix bug # 326. (crashing when using save-xml and hollow prims)
Attempt to fix bug # 328 (limit of 50 items in a folder)
afrisby
MW 2007-08-26 17:57:25 +00:00
parent 87711c5869
commit 291eb48fb0
13 changed files with 172 additions and 79 deletions

View File

@ -58,7 +58,9 @@ namespace OpenSim.Framework.Communications.Caches
public Dictionary<LLUUID, TextureSender> SendingTextures = new Dictionary<LLUUID, TextureSender>();
private BlockingQueue<TextureSender> QueueTextures = new BlockingQueue<TextureSender>();
private Dictionary<LLUUID, List<LLUUID>> AvatarRecievedTextures = new Dictionary<LLUUID,List<LLUUID>>();
private Dictionary<LLUUID, List<LLUUID>> AvatarRecievedTextures = new Dictionary<LLUUID, List<LLUUID>>();
private Dictionary<LLUUID, Dictionary<LLUUID, int>> TimesTextureSent = new Dictionary<LLUUID, Dictionary<LLUUID, int>>();
private IAssetServer _assetServer;
private Thread _assetCacheThread;
@ -139,12 +141,12 @@ namespace OpenSim.Framework.Communications.Caches
public AssetBase GetAsset(LLUUID assetID, bool isTexture)
{
AssetBase asset = GetAsset(assetID);
if (asset == null)
{
this._assetServer.RequestAsset(assetID, isTexture);
}
return asset;
AssetBase asset = GetAsset(assetID);
if (asset == null)
{
this._assetServer.RequestAsset(assetID, isTexture);
}
return asset;
}
public void AddAsset(AssetBase asset)
@ -190,7 +192,7 @@ namespace OpenSim.Framework.Communications.Caches
req = (AssetRequest)this.TextureRequests[i];
if (!this.SendingTextures.ContainsKey(req.ImageInfo.FullID))
{
//Console.WriteLine("new texture to send");
//Console.WriteLine("new texture to send");
TextureSender sender = new TextureSender(req);
//sender.OnComplete += this.TextureSent;
lock (this.SendingTextures)
@ -210,15 +212,40 @@ namespace OpenSim.Framework.Communications.Caches
while (true)
{
TextureSender sender = this.QueueTextures.Dequeue();
bool finished = sender.SendTexture();
if (finished)
if (TimesTextureSent.ContainsKey(sender.request.RequestUser.AgentId))
{
this.TextureSent(sender);
if (TimesTextureSent[sender.request.RequestUser.AgentId].ContainsKey(sender.request.ImageInfo.FullID))
{
TimesTextureSent[sender.request.RequestUser.AgentId][sender.request.ImageInfo.FullID]++;
}
else
{
TimesTextureSent[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID, 1);
}
}
else
{
// Console.WriteLine("readding texture");
this.QueueTextures.Enqueue(sender);
Dictionary<LLUUID, int> UsersSent = new Dictionary<LLUUID,int>();
TimesTextureSent.Add(sender.request.RequestUser.AgentId, UsersSent );
UsersSent.Add(sender.request.ImageInfo.FullID, 1);
}
if (TimesTextureSent[sender.request.RequestUser.AgentId][sender.request.ImageInfo.FullID] < 600)
{
bool finished = sender.SendTexture();
if (finished)
{
this.TextureSent(sender);
}
else
{
// Console.WriteLine("readding texture");
this.QueueTextures.Enqueue(sender);
}
}
else
{
this.TextureSent(sender);
}
}
}
@ -234,7 +261,7 @@ namespace OpenSim.Framework.Communications.Caches
lock (this.SendingTextures)
{
this.SendingTextures.Remove(sender.request.ImageInfo.FullID);
// this.AvatarRecievedTextures[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID);
// this.AvatarRecievedTextures[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID);
}
}
}
@ -247,11 +274,11 @@ namespace OpenSim.Framework.Communications.Caches
//then add to the correct cache list
//then check for waiting requests for this asset/texture (in the Requested lists)
//and move those requests into the Requests list.
if (IsTexture)
{
// Console.WriteLine("asset recieved from asset server");
//Console.WriteLine("asset recieved from asset server");
TextureImage image = new TextureImage(asset);
if (!this.Textures.ContainsKey(image.FullID))
{
@ -301,10 +328,17 @@ namespace OpenSim.Framework.Communications.Caches
}
}
public void AssetNotFound(AssetBase asset)
public void AssetNotFound(LLUUID assetID)
{
//the asset server had no knowledge of requested asset
if (this.RequestedTextures.ContainsKey(assetID))
{
AssetRequest req = this.RequestedTextures[assetID];
ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
notFound.ImageID.ID = assetID;
req.RequestUser.OutPacket(notFound);
this.RequestedTextures.Remove(assetID);
}
}
#region Assets
@ -499,17 +533,17 @@ namespace OpenSim.Framework.Communications.Caches
/// <param name="imageID"></param>
public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID, uint packetNumber)
{
// Console.WriteLine("texture request for " + imageID.ToStringHyphenated());
//Console.WriteLine("texture request for " + imageID.ToStringHyphenated());
//check to see if texture is in local cache, if not request from asset server
if(!this.AvatarRecievedTextures.ContainsKey(userInfo.AgentId))
if (!this.AvatarRecievedTextures.ContainsKey(userInfo.AgentId))
{
this.AvatarRecievedTextures.Add(userInfo.AgentId, new List<LLUUID>());
}
/* if(this.AvatarRecievedTextures[userInfo.AgentId].Contains(imageID))
{
//Console.WriteLine(userInfo.AgentId +" is requesting a image( "+ imageID+" that has already been sent to them");
return;
}*/
/* if(this.AvatarRecievedTextures[userInfo.AgentId].Contains(imageID))
{
//Console.WriteLine(userInfo.AgentId +" is requesting a image( "+ imageID+" that has already been sent to them");
return;
}*/
if (!this.Textures.ContainsKey(imageID))
{
if (!this.RequestedTextures.ContainsKey(imageID))
@ -536,7 +570,7 @@ namespace OpenSim.Framework.Communications.Caches
if (imag.Data.LongLength > 600)
{
//over 600 bytes so split up file
req.NumPackets = 1 + (int)(imag.Data.Length - 600 ) / 1000;
req.NumPackets = 1 + (int)(imag.Data.Length - 600) / 1000;
//Console.WriteLine("texture is " + imag.Data.Length + " which we will send in " +req.NumPackets +" packets");
}
else
@ -656,15 +690,15 @@ namespace OpenSim.Framework.Communications.Caches
public TextureSender(AssetRequest req)
{
request = req;
}
public bool SendTexture()
{
SendPacket();
counter++;
if ((request.PacketCounter > request.NumPackets) | (counter > 50) |(request.NumPackets ==1))
if ((request.PacketCounter > request.NumPackets) | (counter > 90) | (request.NumPackets == 1))
{
return true;
}
@ -682,6 +716,7 @@ namespace OpenSim.Framework.Communications.Caches
{
//only one packet so send whole file
ImageDataPacket im = new ImageDataPacket();
im.Header.Reliable = false;
im.ImageID.Packets = 1;
im.ImageID.ID = req.ImageInfo.FullID;
im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
@ -697,6 +732,7 @@ namespace OpenSim.Framework.Communications.Caches
{
//more than one packet so split file up
ImageDataPacket im = new ImageDataPacket();
im.Header.Reliable = false;
im.ImageID.Packets = (ushort)(req.NumPackets);
im.ImageID.ID = req.ImageInfo.FullID;
im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
@ -704,7 +740,7 @@ namespace OpenSim.Framework.Communications.Caches
Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600);
im.ImageID.Codec = 2;
req.RequestUser.OutPacket(im);
req.PacketCounter++;
//req.ImageInfo.last_used = time;
//System.Console.WriteLine("sent first packet of texture:
@ -713,10 +749,11 @@ namespace OpenSim.Framework.Communications.Caches
}
else
{
//Console.WriteLine("sending packet" + req.PacketCounter + "for " + req.ImageInfo.FullID.ToStringHyphenated());
//Console.WriteLine("sending packet" + req.PacketCounter + "for " + req.ImageInfo.FullID.ToStringHyphenated());
//send imagepacket
//more than one packet so split file up
ImagePacketPacket im = new ImagePacketPacket();
im.Header.Reliable = false;
im.ImageID.Packet = (ushort)(req.PacketCounter);
im.ImageID.ID = req.ImageInfo.FullID;
int size = req.ImageInfo.Data.Length - 600 - (1000 * (req.PacketCounter - 1));

View File

@ -80,15 +80,16 @@ namespace OpenSim.Framework.Communications.Caches
}
public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data)
public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, bool storeLocal)
{
// Console.WriteLine("asset upload of " + assetID);
AgentAssetTransactions transactions = this.GetUserTransActions(remoteClient.AgentId);
if (transactions != null)
{
AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
if (uploader != null)
{
uploader.Initialise(remoteClient, assetID, transaction, type, data);
uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal);
}
}
}

View File

@ -189,6 +189,7 @@ namespace OpenSim.Framework.Communications.Caches
private bool m_finished = false;
private bool m_createItem = false;
private AgentAssetTransactions m_userTransactions;
private bool m_storeLocal;
public AssetXferUploader(AgentAssetTransactions transactions)
{
@ -224,7 +225,7 @@ namespace OpenSim.Framework.Communications.Caches
}
}
public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data)
public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, bool storeLocal)
{
this.ourClient = remoteClient;
this.Asset = new AssetBase();
@ -235,6 +236,7 @@ namespace OpenSim.Framework.Communications.Caches
this.Asset.Name = "blank";
this.Asset.Description = "empty";
this.TransactionID = transaction;
this.m_storeLocal = storeLocal;
if (this.Asset.Data.Length > 2)
{
this.SendCompleteMessage();
@ -271,6 +273,11 @@ namespace OpenSim.Framework.Communications.Caches
{
DoCreateItem();
}
else if (m_storeLocal)
{
this.m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(this.Asset);
}
// Console.WriteLine("upload complete "+ this.TransactionID);
//SaveAssetToFile("testudpupload" + Util.RandomClass.Next(1, 1000) + ".dat", this.Asset.Data);
}

View File

@ -48,7 +48,7 @@ namespace OpenSim.Framework.Interfaces
public interface IAssetReceiver
{
void AssetReceived(AssetBase asset, bool IsTexture);
void AssetNotFound(AssetBase asset);
void AssetNotFound(LLUUID assetID);
}
public interface IAssetPlugin

View File

@ -92,7 +92,7 @@ namespace OpenSim.Framework.Interfaces
public delegate void UpdateTaskInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID folderID, uint localID);
public delegate void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID);
public delegate void UDPAssetUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data);
public delegate void UDPAssetUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, bool storeLocal);
public delegate void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data);
public delegate void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName);
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);

View File

@ -1,3 +1,4 @@
using System.Xml.Serialization;
using libsecondlife;
using libsecondlife.Packets;
@ -75,6 +76,7 @@ namespace OpenSim.Framework.Types
}
}
[XmlIgnore]
public HollowShape HollowShape
{
get

View File

@ -531,13 +531,19 @@ namespace OpenSim.Region.ClientStack
{
Encoding enc = Encoding.ASCII;
uint FULL_MASK_PERMISSIONS = 2147483647;
InventoryDescendentsPacket descend = new InventoryDescendentsPacket();
descend.AgentData.AgentID = this.AgentId;
descend.AgentData.OwnerID = ownerID;
descend.AgentData.FolderID = folderID;
descend.AgentData.Descendents = items.Count;
descend.AgentData.Version = 0;
descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count];
InventoryDescendentsPacket descend = this.CreateInventoryDescendentsPacket(ownerID, folderID);
int count = 0;
if (items.Count < 40)
{
descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count];
descend.AgentData.Descendents = items.Count;
}
else
{
descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[40];
descend.AgentData.Descendents = 40;
}
int i = 0;
foreach (InventoryItemBase item in items)
{
@ -564,12 +570,47 @@ namespace OpenSim.Region.ClientStack
descend.ItemData[i].CRC = Helpers.InventoryCRC(1000, 0, descend.ItemData[i].InvType, descend.ItemData[i].Type, descend.ItemData[i].AssetID, descend.ItemData[i].GroupID, 100, descend.ItemData[i].OwnerID, descend.ItemData[i].CreatorID, descend.ItemData[i].ItemID, descend.ItemData[i].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS);
i++;
count++;
if (i == 40)
{
this.OutPacket(descend);
if ((items.Count - count) > 0)
{
descend = this.CreateInventoryDescendentsPacket(ownerID, folderID);
if ((items.Count - count) < 40)
{
descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count - count];
descend.AgentData.Descendents = items.Count - count;
}
else
{
descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[40];
descend.AgentData.Descendents = 40;
}
i = 0;
}
}
}
this.OutPacket(descend);
if (i < 40)
{
this.OutPacket(descend);
}
}
private InventoryDescendentsPacket CreateInventoryDescendentsPacket(LLUUID ownerID, LLUUID folderID)
{
InventoryDescendentsPacket descend = new InventoryDescendentsPacket();
descend.AgentData.AgentID = this.AgentId;
descend.AgentData.OwnerID = ownerID;
descend.AgentData.FolderID = folderID;
descend.AgentData.Version = 0;
return descend;
}
public void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item)
{
Encoding enc = Encoding.ASCII;

View File

@ -351,7 +351,7 @@ namespace OpenSim.Region.ClientStack
#region Inventory/Asset/Other related packets
case PacketType.RequestImage:
RequestImagePacket imageRequest = (RequestImagePacket)Pack;
//Console.WriteLine("image request: " + Pack.ToString());
for (int i = 0; i < imageRequest.RequestImage.Length; i++)
{
m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image, imageRequest.RequestImage[i].Packet);
@ -363,10 +363,11 @@ namespace OpenSim.Region.ClientStack
m_assetCache.AddAssetRequest(this, transfer);
break;
case PacketType.AssetUploadRequest:
//Console.WriteLine("upload request " + Pack.ToString());
AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
if (OnAssetUploadRequest != null)
{
OnAssetUploadRequest(this, request.AssetBlock.TransactionID.Combine(this.SecureSessionID), request.AssetBlock.TransactionID, request.AssetBlock.Type, request.AssetBlock.AssetData);
OnAssetUploadRequest(this, request.AssetBlock.TransactionID.Combine(this.SecureSessionID), request.AssetBlock.TransactionID, request.AssetBlock.Type, request.AssetBlock.AssetData, request.AssetBlock.StoreLocal);
}
break;
case PacketType.RequestXfer:

View File

@ -86,7 +86,7 @@ namespace OpenSim.Region.Environment
if (!permission)
SendPermissionError(user, reason);
return true;
return permission;
}
#region Object Permissions

View File

@ -262,7 +262,7 @@ namespace OpenSim.Region.Environment.Scenes
if (rezAsset != null)
{
string script = Util.FieldToString(rezAsset.Data);
// Console.WriteLine("rez script " + script);
// Console.WriteLine("rez script " + script);
this.EventManager.TriggerRezScript(localID, copyID, script);
rezzed = true;
}
@ -270,22 +270,22 @@ namespace OpenSim.Region.Environment.Scenes
if (rezzed)
{
bool hasPrim = false;
foreach (EntityBase ent in Entities.Values)
{
if (ent is SceneObjectGroup)
{
hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID);
if (hasPrim != false)
{
bool hasPrim = false;
foreach (EntityBase ent in Entities.Values)
{
if (ent is SceneObjectGroup)
{
hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID);
if (hasPrim != false)
{
bool added = ((SceneObjectGroup)ent).AddInventoryItem(remoteClient, localID, item, copyID);
((SceneObjectGroup)ent).GetProperites(remoteClient);
}
}
}
bool added = ((SceneObjectGroup)ent).AddInventoryItem(remoteClient, localID, item, copyID);
((SceneObjectGroup)ent).GetProperites(remoteClient);
}
}
}
}
}
}
@ -361,7 +361,7 @@ namespace OpenSim.Region.Environment.Scenes
this.phyScene.RemovePrim(rootPart.PhysActor);
rootPart.PhysActor = null;
}
storageManager.DataStore.RemoveObject(((SceneObjectGroup)selectedEnt).UUID, m_regInfo.SimUUID);
((SceneObjectGroup)selectedEnt).DeleteGroup();
@ -415,11 +415,11 @@ namespace OpenSim.Region.Environment.Scenes
this.AddEntity(group);
group.AbsolutePosition = pos;
SceneObjectPart rootPart = group.GetChildPart(group.UUID);
rootPart.PhysActor = phyScene.AddPrim(
new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y, rootPart.AbsolutePosition.Z),
new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z),
new Axiom.Math.Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X,
rootPart.RotationOffset.Y, rootPart.RotationOffset.Z));
rootPart.PhysActor = phyScene.AddPrim(
new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y, rootPart.AbsolutePosition.Z),
new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z),
new Axiom.Math.Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X,
rootPart.RotationOffset.Y, rootPart.RotationOffset.Z));
}

View File

@ -544,11 +544,14 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="ownerID"></param>
public void AddNewPrim(LLUUID ownerID, LLVector3 pos, PrimitiveBaseShape shape)
{
SceneObjectGroup sceneOb = new SceneObjectGroup(this, this.m_regionHandle, ownerID, PrimIDAllocate(), pos, shape);
AddEntity(sceneOb);
SceneObjectPart rootPart = sceneOb.GetChildPart(sceneOb.UUID);
rootPart.PhysActor =phyScene.AddPrim(new PhysicsVector(pos.X, pos.Y, pos.Z), new PhysicsVector(shape.Scale.X, shape.Scale.Y, shape.Scale.Z),
new Axiom.Math.Quaternion());
if (this.PermissionsMngr.CanRezObject(ownerID, pos))
{
SceneObjectGroup sceneOb = new SceneObjectGroup(this, this.m_regionHandle, ownerID, PrimIDAllocate(), pos, shape);
AddEntity(sceneOb);
SceneObjectPart rootPart = sceneOb.GetChildPart(sceneOb.UUID);
rootPart.PhysActor = phyScene.AddPrim(new PhysicsVector(pos.X, pos.Y, pos.Z), new PhysicsVector(shape.Scale.X, shape.Scale.Y, shape.Scale.Z),
new Axiom.Math.Quaternion());
}
}
public void RemovePrim(uint localID, LLUUID avatar_deleter)

View File

@ -144,13 +144,15 @@ namespace OpenSim.Region.GridInterfaces.Local
asset.InvType = foundAsset.Type;
asset.Name = foundAsset.Name;
idata = foundAsset.Data;
asset.Data = idata;
_receiver.AssetReceived(asset, req.IsTexture);
}
else
{
asset.FullID = LLUUID.Zero;
//asset.FullID = ;
_receiver.AssetNotFound(req.AssetID);
}
asset.Data = idata;
_receiver.AssetReceived(asset, req.IsTexture);
}
}

View File

@ -260,7 +260,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
Return += Script;
Return += "} }\r\n";
return Return;
}