From e978d00914a25c12cc03efd597125e2948526681 Mon Sep 17 00:00:00 2001
From: MW
Date: Wed, 27 Feb 2008 21:11:01 +0000
Subject: After seeing sdague do his happy dance over trunk working "the best
he has ever seen". I'm not sure I should be doing this commit, but oh well.
So anyway, it moves the Asset downloading (packet sending) to a module
(AssetDownloadModule). So now at last, AssetCache should be just dealing with
fetching assets from the asset server and caching them.
---
OpenSim/Region/ClientStack/ClientView.cs | 147 +++++------
.../Environment/Modules/AssetDownloadModule.cs | 270 ++++++++++++++++++++-
.../Region/Examples/SimpleApp/MyNpcCharacter.cs | 1 +
3 files changed, 346 insertions(+), 72 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
index de3e29d..55c5726 100644
--- a/OpenSim/Region/ClientStack/ClientView.cs
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -51,10 +51,10 @@ namespace OpenSim.Region.ClientStack
///
public class ClientView : IClientAPI
{
-// ~ClientView()
-// {
-// System.Console.WriteLine("[CLIENTVIEW]: Destructor called");
-// }
+ // ~ClientView()
+ // {
+ // System.Console.WriteLine("[CLIENTVIEW]: Destructor called");
+ // }
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@@ -119,7 +119,7 @@ namespace OpenSim.Region.ClientStack
protected LLVector3 m_startpos;
protected EndPoint m_userEndPoint;
- /* Instantiated Designated Event Delegates */
+ /* Instantiated Designated Event Delegates */
//- used so we don't create new objects for each incoming packet and then toss it out later */
private RequestAvatarProperties handler001 = null; //OnRequestAvatarProperties;
@@ -214,7 +214,8 @@ namespace OpenSim.Region.ClientStack
private UpdateVector handler089 = null; //OnUpdatePrimGroupPosition;
private UpdatePrimRotation handler090 = null; //OnUpdatePrimGroupRotation;
private UpdatePrimGroupRotation handler091 = null; //OnUpdatePrimGroupMouseRotation;
- private PacketStats handler093 = null; // OnPacketStats;
+ private PacketStats handler093 = null; // OnPacketStats;#
+ private RequestAsset handler094 = null; // OnRequestAsset;
/* Properties */
@@ -363,7 +364,7 @@ namespace OpenSim.Region.ClientStack
// We can't reach into other scenes and close the connection
// We need to do this over grid communications
//m_scene.CloseAllAgents(CircuitCode);
-
+
// If we're not shutting down the circuit, then this is the last time we'll go here.
// If we are shutting down the circuit, the UDP Server will come back here with
// ShutDownCircuit = false
@@ -502,7 +503,7 @@ namespace OpenSim.Region.ClientStack
protected virtual void ClientLoop()
{
m_log.Info("[CLIENT]: Entered loop");
- while( true )
+ while (true)
{
QueItem nextPacket = m_packetQueue.Dequeue();
if (nextPacket.Incoming)
@@ -690,6 +691,7 @@ namespace OpenSim.Region.ClientStack
public event RezScript OnRezScript;
public event UpdateTaskInventory OnUpdateTaskInventory;
public event RemoveTaskInventory OnRemoveTaskItem;
+ public event RequestAsset OnRequestAsset;
public event UUIDNameRequest OnNameFromUUIDRequest;
@@ -1410,7 +1412,7 @@ namespace OpenSim.Region.ClientStack
OutPacket(replyPacket, ThrottleOutPacketType.Task);
}
- public void SendAgentDataUpdate(LLUUID agentid, LLUUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname,string grouptitle)
+ public void SendAgentDataUpdate(LLUUID agentid, LLUUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
{
AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate);
sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid;
@@ -1420,7 +1422,7 @@ namespace OpenSim.Region.ClientStack
sendAgentDataUpdate.AgentData.GroupPowers = grouppowers;
sendAgentDataUpdate.AgentData.GroupTitle = Helpers.StringToField(grouptitle);
sendAgentDataUpdate.AgentData.LastName = Helpers.StringToField(lastname);
- OutPacket(sendAgentDataUpdate,ThrottleOutPacketType.Task);
+ OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task);
}
///
@@ -2329,10 +2331,10 @@ namespace OpenSim.Region.ClientStack
{
LLUUID partId = part.UUID;
-
-
-
-
+
+
+
+
UpdatePrimRotation handler090 = OnUpdatePrimGroupRotation;
UpdatePrimGroupRotation handler091 = OnUpdatePrimGroupMouseRotation;
@@ -2344,7 +2346,7 @@ namespace OpenSim.Region.ClientStack
handler086 = OnUpdatePrimSinglePosition;
if (handler086 != null)
{
-
+
// System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
handler086(localId, pos1, this);
}
@@ -2355,18 +2357,18 @@ namespace OpenSim.Region.ClientStack
handler087 = OnUpdatePrimSingleRotation;
if (handler087 != null)
{
-
+
//System.Console.WriteLine("new tab rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
handler087(localId, rot1, this);
}
break;
case 3:
-
+
LLQuaternion rot2 = new LLQuaternion(block.Data, 12, true);
handler087 = OnUpdatePrimSingleRotation;
if (handler087 != null)
{
-
+
//System.Console.WriteLine("new mouse rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
handler087(localId, rot2, this);
}
@@ -2378,7 +2380,7 @@ namespace OpenSim.Region.ClientStack
handler088 = OnUpdatePrimScale;
if (handler088 != null)
{
-
+
// Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
handler088(localId, scale1, this);
}
@@ -2390,18 +2392,18 @@ namespace OpenSim.Region.ClientStack
if (handler089 != null)
{
-
+
handler089(localId, pos2, this);
}
break;
case 10:
-
+
LLQuaternion rot3 = new LLQuaternion(block.Data, 0, true);
handler090 = OnUpdatePrimGroupRotation;
if (handler090 != null)
{
-
+
// Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W);
handler090(localId, rot3, this);
}
@@ -2429,7 +2431,7 @@ namespace OpenSim.Region.ClientStack
handler088 = OnUpdatePrimScale;
if (handler088 != null)
{
-
+
//Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
handler088(localId, scale2, this);
@@ -2449,10 +2451,10 @@ namespace OpenSim.Region.ClientStack
handler088 = OnUpdatePrimScale;
if (handler088 != null)
{
-
+
// Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z );
handler088(localId, scale5, this);
-
+
handler086 = OnUpdatePrimSinglePosition;
if (handler086 != null)
{
@@ -2762,7 +2764,7 @@ namespace OpenSim.Region.ClientStack
if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent))
{
//m_log.Debug("[NETWORK]: Resending " + packet.Type.ToString() + " packet, " +
- //(now - packet.TickCount) + "ms have passed");
+ //(now - packet.TickCount) + "ms have passed");
packet.Header.Resent = true;
OutPacket(packet, ThrottleOutPacketType.Resend);
@@ -2863,13 +2865,13 @@ namespace OpenSim.Region.ClientStack
case PacketType.AvatarPropertiesRequest:
AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
-
+
handler001 = OnRequestAvatarProperties;
if (handler001 != null)
{
handler001(this, avatarProperties.AgentData.AvatarID);
}
-
+
break;
case PacketType.ChatFromViewer:
@@ -2900,7 +2902,7 @@ namespace OpenSim.Region.ClientStack
handler002(this, args);
}
-
+
break;
case PacketType.ScriptDialogReply:
@@ -2921,7 +2923,7 @@ namespace OpenSim.Region.ClientStack
if (handler003 != null)
handler003(this, args);
}
-
+
break;
case PacketType.ImprovedInstantMessage:
ImprovedInstantMessagePacket msgpack = (ImprovedInstantMessagePacket)Pack;
@@ -2940,7 +2942,7 @@ namespace OpenSim.Region.ClientStack
msgpack.MessageBlock.BinaryBucket);
}
-
+
break;
case PacketType.AcceptFriendship:
@@ -2963,7 +2965,7 @@ namespace OpenSim.Region.ClientStack
handler005(this, agentID, transactionID, callingCardFolders);
}
-
+
break;
@@ -2977,7 +2979,7 @@ namespace OpenSim.Region.ClientStack
{
handler006(this, listOwnerAgentID, exFriendID);
}
-
+
break;
case PacketType.RezObject:
@@ -2995,7 +2997,7 @@ namespace OpenSim.Region.ClientStack
//rezPacket.RezData.RezSelected;
//rezPacket.RezData.FromTaskID;
//m_log.Info("[REZData]: " + rezPacket.ToString());
-
+
handler007(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd,
rezPacket.RezData.RayStart, rezPacket.RezData.RayTargetID,
rezPacket.RezData.BypassRaycast, rezPacket.RezData.RayEndIsIntersection,
@@ -3004,7 +3006,7 @@ namespace OpenSim.Region.ClientStack
rezPacket.RezData.RezSelected, rezPacket.RezData.RemoveItem,
rezPacket.RezData.FromTaskID);
}
-
+
break;
case PacketType.DeRezObject:
handler008 = OnDeRezObject;
@@ -3012,7 +3014,7 @@ namespace OpenSim.Region.ClientStack
{
handler008(Pack, this);
}
-
+
break;
case PacketType.ModifyLand:
ModifyLandPacket modify = (ModifyLandPacket)Pack;
@@ -3021,7 +3023,7 @@ namespace OpenSim.Region.ClientStack
{
if (OnModifyTerrain != null)
{
-
+
for (int i = 0; i < modify.ParcelData.Length; i++)
{
handler009 = OnModifyTerrain;
@@ -3036,7 +3038,7 @@ namespace OpenSim.Region.ClientStack
}
}
}
-
+
break;
case PacketType.RegionHandshakeReply:
@@ -3045,7 +3047,7 @@ namespace OpenSim.Region.ClientStack
{
handler010(this);
}
-
+
break;
case PacketType.AgentWearablesRequest:
handler011 = OnRequestWearables;
@@ -3054,7 +3056,7 @@ namespace OpenSim.Region.ClientStack
{
handler011();
}
-
+
handler012 = OnRequestAvatarsData;
@@ -3063,7 +3065,7 @@ namespace OpenSim.Region.ClientStack
handler012(this);
}
-
+
break;
case PacketType.AgentSetAppearance:
AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack;
@@ -3073,7 +3075,7 @@ namespace OpenSim.Region.ClientStack
{
handler013(appear.ObjectData.TextureEntry, appear.VisualParam);
}
-
+
break;
case PacketType.AgentIsNowWearing:
if (OnAvatarNowWearing != null)
@@ -3094,7 +3096,7 @@ namespace OpenSim.Region.ClientStack
handler014(this, wearingArgs);
}
-
+
}
break;
case PacketType.RezSingleAttachmentFromInv:
@@ -3102,28 +3104,28 @@ namespace OpenSim.Region.ClientStack
handler015 = OnRezSingleAttachmentFromInv;
if (handler015 != null)
{
- RezSingleAttachmentFromInvPacket rez = (RezSingleAttachmentFromInvPacket) Pack;
- handler015(this, rez.ObjectData.ItemID,
+ RezSingleAttachmentFromInvPacket rez = (RezSingleAttachmentFromInvPacket)Pack;
+ handler015(this, rez.ObjectData.ItemID,
rez.ObjectData.AttachmentPt, rez.ObjectData.ItemFlags, rez.ObjectData.NextOwnerMask);
}
-
- break;
+
+ break;
case PacketType.ObjectAttach:
-
+
if (OnObjectAttach != null)
{
ObjectAttachPacket att = (ObjectAttachPacket)Pack;
-
+
handler016 = OnObjectAttach;
-
+
if (handler016 != null)
- {
+ {
handler016(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation);
}
}
-
- break;
+
+ break;
case PacketType.SetAlwaysRun:
SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack;
@@ -3131,7 +3133,7 @@ namespace OpenSim.Region.ClientStack
if (handler017 != null)
handler017(this, run.AgentData.AlwaysRun);
-
+
break;
case PacketType.CompleteAgentMovement:
@@ -3243,7 +3245,7 @@ namespace OpenSim.Region.ClientStack
case PacketType.SetStartLocationRequest:
SetStartLocationRequestPacket avSetStartLocationRequestPacket = (SetStartLocationRequestPacket)Pack;
-
+
if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId)
{
handler027 = OnSetStartLocationRequest;
@@ -3494,7 +3496,7 @@ namespace OpenSim.Region.ClientStack
byte set = permChanges.Set;
handler043 = OnObjectPermissions;
-
+
if (handler043 != null)
OnObjectPermissions(this, AgentID, SessionID, field, localID, mask, set);
}
@@ -3539,7 +3541,7 @@ namespace OpenSim.Region.ClientStack
case PacketType.RequestImage:
RequestImagePacket imageRequest = (RequestImagePacket)Pack;
//Console.WriteLine("image request: " + Pack.ToString());
-
+
handler045 = null;
for (int i = 0; i < imageRequest.RequestImage.Length; i++)
@@ -3551,9 +3553,9 @@ namespace OpenSim.Region.ClientStack
args.DiscardLevel = imageRequest.RequestImage[i].DiscardLevel;
args.PacketNumber = imageRequest.RequestImage[i].Packet;
args.Priority = imageRequest.RequestImage[i].DownloadPriority;
-
+
handler045 = OnRequestTexture;
-
+
if (handler045 != null)
OnRequestTexture(this, args);
}
@@ -3562,7 +3564,12 @@ namespace OpenSim.Region.ClientStack
case PacketType.TransferRequest:
//Console.WriteLine("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
TransferRequestPacket transfer = (TransferRequestPacket)Pack;
- m_assetCache.AddAssetRequest(this, transfer);
+ // m_assetCache.AddAssetRequest(this, transfer);
+ handler094 = OnRequestAsset;
+ if (handler094 != null)
+ {
+ handler094(this, transfer);
+ }
break;
case PacketType.AssetUploadRequest:
AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
@@ -3606,7 +3613,7 @@ namespace OpenSim.Region.ClientStack
handler049 = OnConfirmXfer;
if (handler049 != null)
{
- handler049(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet);
+ handler049(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet);
}
break;
case PacketType.CreateInventoryFolder:
@@ -3615,7 +3622,7 @@ namespace OpenSim.Region.ClientStack
handler050 = OnCreateNewInventoryFolder;
if (handler050 != null)
{
-
+
handler050(this, invFolder.FolderData.FolderID,
(ushort)invFolder.FolderData.Type,
Util.FieldToString(invFolder.FolderData.Name),
@@ -3709,7 +3716,7 @@ namespace OpenSim.Region.ClientStack
}
break;
case PacketType.PurgeInventoryDescendents:
-
+
PurgeInventoryDescendentsPacket Purge = (PurgeInventoryDescendentsPacket)Pack;
handler056 = OnPurgeInventoryDescendents;
@@ -4130,7 +4137,7 @@ namespace OpenSim.Region.ClientStack
}
break;
case PacketType.EstateCovenantRequest:
-
+
EstateCovenantRequestPacket.AgentDataBlock epack =
((EstateCovenantRequestPacket)Pack).AgentData;
@@ -4246,9 +4253,9 @@ namespace OpenSim.Region.ClientStack
m_log.Warn("[CLIENT]: unhandled MuteListRequest packet");
break;
//case PacketType.AgentDataUpdateRequest:
- // TODO: handle this packet
- //m_log.Warn("[CLIENT]: unhandled AgentDataUpdateRequest packet");
- //break;
+ // TODO: handle this packet
+ //m_log.Warn("[CLIENT]: unhandled AgentDataUpdateRequest packet");
+ //break;
case PacketType.ParcelDwellRequest:
// TODO: handle this packet
@@ -4275,9 +4282,9 @@ namespace OpenSim.Region.ClientStack
m_log.Warn("[CLIENT]: unhandled SoundTrigger packet");
break;
//case PacketType.UserInfoRequest:
- // TODO: handle this packet
- //m_log.Warn("[CLIENT]: unhandled UserInfoRequest packet");
- //break;
+ // TODO: handle this packet
+ //m_log.Warn("[CLIENT]: unhandled UserInfoRequest packet");
+ //break;
case PacketType.InventoryDescendents:
// TODO: handle this packet
m_log.Warn("[CLIENT]: unhandled InventoryDescent packet");
diff --git a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs b/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs
index 012f920..ca01cae 100644
--- a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs
@@ -26,25 +26,57 @@
*
*/
+using System;
+using System.Collections.Generic;
+using System.Threading;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes;
+using libsecondlife;
+using libsecondlife.Packets;
namespace OpenSim.Region.Environment.Modules
{
public class AssetDownloadModule : IRegionModule
{
private Scene m_scene;
+ private Dictionary RegisteredScenes = new Dictionary();
+ ///
+ /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests
+ ///
+ private Dictionary> RequestedAssets;
+
+ ///
+ /// Asset requests with data which are ready to be sent back to requesters. This includes textures.
+ ///
+ private List AssetRequests;
+
+ private Thread m_thread;
public AssetDownloadModule()
{
+ RequestedAssets = new Dictionary>();
+ AssetRequests = new List();
}
public void Initialise(Scene scene, IConfigSource config)
{
- m_scene = scene;
- m_scene.EventManager.OnNewClient += NewClient;
+ if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
+ {
+ RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
+ scene.EventManager.OnNewClient += NewClient;
+ }
+
+ if (m_scene == null)
+ {
+ m_scene = scene;
+ m_thread = new Thread(new ThreadStart(RunAssetQueue));
+ m_thread.Name = "AssetDownloadQueueThread";
+ m_thread.IsBackground = true;
+ m_thread.Start();
+ OpenSim.Framework.ThreadTracker.Add(m_thread);
+ }
}
public void PostInitialise()
@@ -67,6 +99,240 @@ namespace OpenSim.Region.Environment.Modules
public void NewClient(IClientAPI client)
{
+ client.OnRequestAsset += AddAssetRequest;
+ }
+
+ ///
+ /// Make an asset request the result of which will be packeted up and sent directly back to the client.
+ ///
+ ///
+ ///
+ public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
+ {
+ LLUUID requestID = null;
+ byte source = 2;
+ if (transferRequest.TransferInfo.SourceType == 2)
+ {
+ //direct asset request
+ requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
+ }
+ else if (transferRequest.TransferInfo.SourceType == 3)
+ {
+ //inventory asset request
+ requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
+ source = 3;
+ //Console.WriteLine("asset request " + requestID);
+ }
+
+ //not found asset
+ // so request from asset server
+ Dictionary userRequests = null;
+ if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests))
+ {
+ if (!userRequests.ContainsKey(requestID))
+ {
+
+ AssetRequest request = new AssetRequest();
+ request.RequestUser = userInfo;
+ request.RequestAssetID = requestID;
+ request.TransferRequestID = transferRequest.TransferInfo.TransferID;
+ request.AssetRequestSource = source;
+ request.Params = transferRequest.TransferInfo.Params;
+ userRequests[requestID] = request;
+ m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
+ }
+ }
+ else
+ {
+ userRequests = new Dictionary();
+ AssetRequest request = new AssetRequest();
+ request.RequestUser = userInfo;
+ request.RequestAssetID = requestID;
+ request.TransferRequestID = transferRequest.TransferInfo.TransferID;
+ request.AssetRequestSource = source;
+ request.Params = transferRequest.TransferInfo.Params;
+ userRequests.Add(requestID, request);
+ RequestedAssets[userInfo.AgentId] = userRequests;
+ m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
+
+ }
+ return;
+ }
+
+ public void AssetCallback(LLUUID assetID, AssetBase asset)
+ {
+ if (asset != null)
+ {
+ foreach (Dictionary userRequests in RequestedAssets.Values)
+ {
+ if (userRequests.ContainsKey(assetID))
+ {
+ AssetRequest req = userRequests[assetID];
+ if (req != null)
+ {
+ req.AssetInf = asset;
+ req.NumPackets = CalculateNumPackets(asset.Data);
+
+ userRequests.Remove(assetID);
+ AssetRequests.Add(req);
+ }
+ }
+ }
+ }
+ }
+
+ private void RunAssetQueue()
+ {
+ while (true)
+ {
+ try
+ {
+ ProcessAssetQueue();
+ Thread.Sleep(500);
+ }
+ catch (Exception e)
+ {
+ // m_log.Error("[ASSET CACHE]: " + e.ToString());
+ }
+ }
+ }
+
+ ///
+ /// Process the asset queue which sends packets directly back to the client.
+ ///
+ private void ProcessAssetQueue()
+ {
+ //should move the asset downloading to a module, like has been done with texture downloading
+ if (AssetRequests.Count == 0)
+ {
+ //no requests waiting
+ return;
+ }
+ // if less than 5, do all of them
+ int num = Math.Min(5, AssetRequests.Count);
+
+ AssetRequest req;
+ for (int i = 0; i < num; i++)
+ {
+ req = (AssetRequest)AssetRequests[i];
+ //Console.WriteLine("sending asset " + req.RequestAssetID);
+ TransferInfoPacket Transfer = new TransferInfoPacket();
+ Transfer.TransferInfo.ChannelType = 2;
+ Transfer.TransferInfo.Status = 0;
+ Transfer.TransferInfo.TargetType = 0;
+ if (req.AssetRequestSource == 2)
+ {
+ Transfer.TransferInfo.Params = new byte[20];
+ Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
+ int assType = (int)req.AssetInf.Type;
+ Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
+ }
+ else if (req.AssetRequestSource == 3)
+ {
+ Transfer.TransferInfo.Params = req.Params;
+ // Transfer.TransferInfo.Params = new byte[100];
+ //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
+ //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
+ }
+ Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
+ Transfer.TransferInfo.TransferID = req.TransferRequestID;
+ req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
+
+ if (req.NumPackets == 1)
+ {
+ TransferPacketPacket TransferPacket = new TransferPacketPacket();
+ TransferPacket.TransferData.Packet = 0;
+ TransferPacket.TransferData.ChannelType = 2;
+ TransferPacket.TransferData.TransferID = req.TransferRequestID;
+ TransferPacket.TransferData.Data = req.AssetInf.Data;
+ TransferPacket.TransferData.Status = 1;
+ req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
+ }
+ else
+ {
+ int processedLength = 0;
+ // libsecondlife hardcodes 1500 as the maximum data chunk size
+ int maxChunkSize = 1250;
+ int packetNumber = 0;
+
+ while (processedLength < req.AssetInf.Data.Length)
+ {
+ TransferPacketPacket TransferPacket = new TransferPacketPacket();
+ TransferPacket.TransferData.Packet = packetNumber;
+ TransferPacket.TransferData.ChannelType = 2;
+ TransferPacket.TransferData.TransferID = req.TransferRequestID;
+
+ int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
+ byte[] chunk = new byte[chunkSize];
+ Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
+
+ TransferPacket.TransferData.Data = chunk;
+
+ // 0 indicates more packets to come, 1 indicates last packet
+ if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
+ {
+ TransferPacket.TransferData.Status = 0;
+ }
+ else
+ {
+ TransferPacket.TransferData.Status = 1;
+ }
+
+ req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
+
+ processedLength += chunkSize;
+ packetNumber++;
+ }
+ }
+ }
+
+ //remove requests that have been completed
+ for (int i = 0; i < num; i++)
+ {
+ AssetRequests.RemoveAt(0);
+ }
+ }
+ ///
+ /// Calculate the number of packets required to send the asset to the client.
+ ///
+ ///
+ ///
+ private int CalculateNumPackets(byte[] data)
+ {
+ const uint m_maxPacketSize = 600;
+ int numPackets = 1;
+
+ if (data.LongLength > m_maxPacketSize)
+ {
+ // over max number of bytes so split up file
+ long restData = data.LongLength - m_maxPacketSize;
+ int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
+ numPackets += restPackets;
+ }
+
+ return numPackets;
+ }
+
+ public class AssetRequest
+ {
+ public IClientAPI RequestUser;
+ public LLUUID RequestAssetID;
+ public AssetBase AssetInf;
+ public AssetBase ImageInfo;
+ public LLUUID TransferRequestID;
+ public long DataPointer = 0;
+ public int NumPackets = 0;
+ public int PacketCounter = 0;
+ public bool IsTextureRequest;
+ public byte AssetRequestSource = 2;
+ public byte[] Params = null;
+ //public bool AssetInCache;
+ //public int TimeRequested;
+ public int DiscardLevel = -1;
+
+ public AssetRequest()
+ {
+ }
}
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
index e821800..30a41b7 100644
--- a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
@@ -131,6 +131,7 @@ namespace SimpleApp
public event RezScript OnRezScript;
public event UpdateTaskInventory OnUpdateTaskInventory;
public event RemoveTaskInventory OnRemoveTaskItem;
+ public event RequestAsset OnRequestAsset;
public event UUIDNameRequest OnNameFromUUIDRequest;
--
cgit v1.1