From 1110ee877ff0cdd17098b5035f147542ccd5ca87 Mon Sep 17 00:00:00 2001
From: MW
Date: Mon, 15 Dec 2008 21:46:57 +0000
Subject: More work on moving Xfer file transfer handling code to the Client
stack from the various region modules that it is currently in. Still not
enabled yet.
---
OpenSim/Framework/IClientFileTransfer.cs | 2 +-
.../Region/ClientStack/LindenUDP/LLFileTransfer.cs | 167 ++++++++++++++++-----
2 files changed, 134 insertions(+), 35 deletions(-)
diff --git a/OpenSim/Framework/IClientFileTransfer.cs b/OpenSim/Framework/IClientFileTransfer.cs
index 832164e..ac5fc2b 100644
--- a/OpenSim/Framework/IClientFileTransfer.cs
+++ b/OpenSim/Framework/IClientFileTransfer.cs
@@ -32,7 +32,7 @@ using OpenMetaverse;
namespace OpenSim.Framework
{
- public delegate void UploadComplete(string filename, UUID fileID, byte[] fileData, IClientAPI remoteClient);
+ public delegate void UploadComplete(string filename, UUID fileID, ulong transferID, byte[] fileData, IClientAPI remoteClient);
public delegate void UploadAborted(string filename, UUID fileID, ulong transferID, IClientAPI remoteClient);
public interface IClientFileTransfer
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
index 9d7b39e..e5783de 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
@@ -40,18 +40,34 @@ using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.ClientStack.LindenUDP
{
+ ///
+ /// A work in progress, to contain the SL specific file transfer code that is currently in various region modules
+ /// This file currently contains multiple classes that need to be split out into their own files.
+ ///
public class LLFileTransfer : IClientFileTransfer
{
protected IClientAPI m_clientAPI;
/// Dictionary of handlers for uploading files from client
/// TODO: Need to add cleanup code to remove handlers that have completed their upload
- protected Dictionary m_handlers;
- protected object m_handlerLock = new object();
+ protected Dictionary m_uploadHandlers;
+ protected object m_uploadHandlersLock = new object();
+
+
+ ///
+ /// Dictionary of files to be sent to clients
+ ///
+ protected static Dictionary m_files;
+
+ ///
+ /// Dictionary of Download Transfers in progess
+ ///
+ protected Dictionary m_downloadHandlers = new Dictionary();
+
public LLFileTransfer(IClientAPI clientAPI)
{
- m_handlers = new Dictionary();
+ m_uploadHandlers = new Dictionary();
m_clientAPI = clientAPI;
m_clientAPI.OnXferReceive += XferReceive;
@@ -72,10 +88,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if ((String.IsNullOrEmpty(clientFileName)) || (uploadCompleteCallback == null))
{
- return false;
+ return false;
}
- XferHandler uploader = new XferHandler(m_clientAPI, clientFileName);
+ XferUploadHandler uploader = new XferUploadHandler(m_clientAPI, clientFileName);
return StartUpload(uploader, uploadCompleteCallback, abortCallback);
}
@@ -87,12 +103,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return false;
}
- XferHandler uploader = new XferHandler(m_clientAPI, fileID);
+ XferUploadHandler uploader = new XferUploadHandler(m_clientAPI, fileID);
return StartUpload(uploader, uploadCompleteCallback, abortCallback);
}
- private bool StartUpload(XferHandler uploader, UploadComplete uploadCompleteCallback, UploadAborted abortCallback)
+ private bool StartUpload(XferUploadHandler uploader, UploadComplete uploadCompleteCallback, UploadAborted abortCallback)
{
uploader.UploadDone += uploadCompleteCallback;
uploader.UploadDone += RemoveXferHandler;
@@ -102,11 +118,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uploader.UploadAborted += abortCallback;
}
- lock (m_handlerLock)
+ lock (m_uploadHandlersLock)
{
- if (!m_handlers.ContainsKey(uploader.XferID))
+ if (!m_uploadHandlers.ContainsKey(uploader.XferID))
{
- m_handlers.Add(uploader.XferID, uploader);
+ m_uploadHandlers.Add(uploader.XferID, uploader);
uploader.RequestStartXfer(m_clientAPI);
return true;
}
@@ -126,37 +142,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected void AbortXferHandler(IClientAPI remoteClient, ulong xferID)
{
- lock (m_handlerLock)
+ lock (m_uploadHandlersLock)
{
- if (m_handlers.ContainsKey(xferID))
+ if (m_uploadHandlers.ContainsKey(xferID))
{
- m_handlers[xferID].AbortUpload(remoteClient);
- m_handlers.Remove(xferID);
+ m_uploadHandlers[xferID].AbortUpload(remoteClient);
+ m_uploadHandlers.Remove(xferID);
}
}
}
protected void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
{
- lock (m_handlerLock)
+ lock (m_uploadHandlersLock)
{
- if (m_handlers.ContainsKey(xferID))
+ if (m_uploadHandlers.ContainsKey(xferID))
{
- m_handlers[xferID].XferReceive(remoteClient, xferID, packetID, data);
+ m_uploadHandlers[xferID].XferReceive(remoteClient, xferID, packetID, data);
}
}
}
- protected void RemoveXferHandler(string filename, UUID fileID, byte[] fileData, IClientAPI remoteClient)
+ protected void RemoveXferHandler(string filename, UUID fileID, ulong transferID, byte[] fileData, IClientAPI remoteClient)
{
}
}
- public class XferHandler
+ public class XferUploadHandler
{
private AssetBase m_asset;
-
+
public event UploadComplete UploadDone;
public event UploadAborted UploadAborted;
@@ -173,27 +189,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
get { return m_complete; }
}
- public XferHandler(IClientAPI pRemoteClient, string pClientFilename)
+ public XferUploadHandler(IClientAPI pRemoteClient, string pClientFilename)
{
+ Initialise(UUID.Zero, pClientFilename);
+ }
- m_asset = new AssetBase();
- m_asset.FullID = UUID.Zero;
- m_asset.Type = type;
- m_asset.Data = new byte[0];
- m_asset.Name = pClientFilename;
- m_asset.Description = "empty";
- m_asset.Local = true;
- m_asset.Temporary = true;
- mXferID = Util.GetNextXferID();
+ public XferUploadHandler(IClientAPI pRemoteClient, UUID fileID)
+ {
+ Initialise(fileID, String.Empty);
}
- public XferHandler(IClientAPI pRemoteClient, UUID fileID)
+ private void Initialise(UUID fileID, string fileName)
{
m_asset = new AssetBase();
m_asset.FullID = fileID;
m_asset.Type = type;
m_asset.Data = new byte[0];
- m_asset.Name = String.Empty;
+ m_asset.Name = fileName;
m_asset.Description = "empty";
m_asset.Local = true;
m_asset.Temporary = true;
@@ -207,7 +219,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void RequestStartXfer(IClientAPI pRemoteClient)
{
- if (!String.IsNullOrEmpty(m_asset.Name) )
+ if (!String.IsNullOrEmpty(m_asset.Name))
{
pRemoteClient.SendXferRequest(mXferID, m_asset.Type, m_asset.FullID, 0, Utils.StringToBytes(m_asset.Name));
}
@@ -257,7 +269,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
handlerUploadDone = UploadDone;
if (handlerUploadDone != null)
{
- handlerUploadDone(m_asset.Name, m_asset.FullID, m_asset.Data, remoteClient);
+ handlerUploadDone(m_asset.Name, m_asset.FullID, mXferID, m_asset.Data, remoteClient);
}
}
@@ -270,4 +282,91 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
}
+
+ public class XferDownloadHandler
+ {
+ public IClientAPI Client;
+ private bool complete;
+ public byte[] Data = new byte[0];
+ public int DataPointer = 0;
+ public string FileName = String.Empty;
+ public uint Packet = 0;
+ public uint Serial = 1;
+ public ulong XferID = 0;
+
+ public XferDownloadHandler(string fileName, byte[] data, ulong xferID, IClientAPI client)
+ {
+ FileName = fileName;
+ Data = data;
+ XferID = xferID;
+ Client = client;
+ }
+
+ public XferDownloadHandler()
+ {
+ }
+
+ ///
+ /// Start a transfer
+ ///
+ /// True if the transfer is complete, false if not
+ public bool StartSend()
+ {
+ if (Data.Length < 1000)
+ {
+ // for now (testing) we only support files under 1000 bytes
+ byte[] transferData = new byte[Data.Length + 4];
+ Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
+ Array.Copy(Data, 0, transferData, 4, Data.Length);
+ Client.SendXferPacket(XferID, 0 + 0x80000000, transferData);
+
+ complete = true;
+ }
+ else
+ {
+ byte[] transferData = new byte[1000 + 4];
+ Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
+ Array.Copy(Data, 0, transferData, 4, 1000);
+ Client.SendXferPacket(XferID, 0, transferData);
+ Packet++;
+ DataPointer = 1000;
+ }
+
+ return complete;
+ }
+
+ ///
+ /// Respond to an ack packet from the client
+ ///
+ ///
+ /// True if the transfer is complete, false otherwise
+ public bool AckPacket(uint packet)
+ {
+ if (!complete)
+ {
+ if ((Data.Length - DataPointer) > 1000)
+ {
+ byte[] transferData = new byte[1000];
+ Array.Copy(Data, DataPointer, transferData, 0, 1000);
+ Client.SendXferPacket(XferID, Packet, transferData);
+ Packet++;
+ DataPointer += 1000;
+ }
+ else
+ {
+ byte[] transferData = new byte[Data.Length - DataPointer];
+ Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
+ uint endPacket = Packet |= (uint)0x80000000;
+ Client.SendXferPacket(XferID, endPacket, transferData);
+ Packet++;
+ DataPointer += (Data.Length - DataPointer);
+
+ complete = true;
+ }
+ }
+
+ return complete;
+ }
+ }
+
}
\ No newline at end of file
--
cgit v1.1