private void TransferPacketCallbackHandler(Packet packet, Simulator simulator) { #if DEBUG_PACKETS Console.WriteLine(packet); #endif TransferPacketPacket reply = (TransferPacketPacket)packet; LLUUID TransferID = reply.TransferData.TransferID; byte[] Data = reply.TransferData.Data; // Append data to data received. AssetRequestDownload request = htDownloadRequests[TransferID]; if (request == null) { return; } lock (request) { Array.Copy(Data, 0, request.AssetData, request.Received, Data.Length); request.Received += Data.Length; // If we've gotten all the data, mark it completed. if (request.Received >= request.Size) { Console.WriteLine("Download Complete"); request.Completed.Set(); } } }
private Packet TransferPacketHandler(Packet packet, IPEndPoint simulator) { TransferPacketPacket asset = (TransferPacketPacket)packet; UUID cid = asset.TransferData.TransferID; if (dls.ContainsKey(cid)) { if (gdebug) { Console.WriteLine("Got an transpher packet"); } try { Buffer.BlockCopy(asset.TransferData.Data, 0, dls[cid].bytes, dls[cid].sizedone, asset.TransferData.Data.Length); } catch (Exception) { return(packet); } dls[cid].sizedone += asset.TransferData.Data.Length; // Check if we downloaded the full asset if (dls[cid].sizedone >= dls[cid].size) { //done return(done(packet, cid)); } //Intercept packet } return(packet); }
//handle packets that contain info about the notecard data transfer // private Packet TransferInfoHandler(Packet packet, IPEndPoint simulator) // { // TransferInfoPacket info = (TransferInfoPacket)packet; // // if (info.TransferInfo.TransferID == assetdownloadID) // { // //this is our requested tranfer, handle it // downloadsize = info.TransferInfo.Size; // // if ((StatusCode)info.TransferInfo.Status != StatusCode.OK) // { // SayToUser("Failed to read notecard"); // } // if (downloadedbytes >= downloadsize) // { // //Download already completed! // downloadCompleted(); // } // //intercept packet // return null; // } // return packet; // } //handle packets which contain the notecard data private Packet TransferPacketHandler(Packet packet, IPEndPoint simulator) { TransferPacketPacket asset = (TransferPacketPacket)packet; if (asset.TransferData.TransferID == assetdownloadID) { Buffer.BlockCopy(asset.TransferData.Data, 0, buffer, 1000 * asset.TransferData.Packet, asset.TransferData.Data.Length); downloadedbytes += asset.TransferData.Data.Length; // Check if we downloaded the full asset if (downloadedbytes >= downloadsize) { downloadCompleted(); } //Intercept packet return(null); } return(packet); }
private void TransferPacketCallbackHandler(Packet packet, Simulator simulator) { #if DEBUG_PACKETS slClient.DebugLog(packet); #endif TransferPacketPacket reply = (TransferPacketPacket)packet; LLUUID TransferID = reply.TransferData.TransferID; byte[] Data = reply.TransferData.Data; // Append data to data received. AssetRequestDownload request = htDownloadRequests[TransferID]; if (request == null) { return; } // Add data to data dictionary. request.AssetDataReceived[reply.TransferData.Packet] = Data; request.Received += Data.Length; // If we've gotten all the data, mark it completed. if (request.Received >= request.Size) { int curPos = 0; foreach (KeyValuePair <int, byte[]> kvp in request.AssetDataReceived) { Array.Copy(kvp.Value, 0, request.AssetData, curPos, kvp.Value.Length); curPos += kvp.Value.Length; } request.Completed.Set(); } }
private void TransferPacketCallbackHandler(Packet packet, Simulator simulator) { #if DEBUG_PACKETS slClient.Log(packet.ToString(), Helpers.LogLevel.Info); #endif TransferPacketPacket reply = (TransferPacketPacket)packet; LLUUID TransferID = reply.TransferData.TransferID; byte[] Data = reply.TransferData.Data; // Lookup the request for this packet if (!htDownloadRequests.ContainsKey(TransferID)) { //slClient.Log("Received unexpected TransferPacket packet." + Environment.NewLine + packet.ToString(), // Helpers.LogLevel.Warning); return; } AssetRequestDownload request = htDownloadRequests[TransferID]; // Append data to data received. request.AddDownloadedData(reply.TransferData.Packet, Data); }
void TransferToClient(Asset asset, Agent agent, UUID transferID) { Logger.Log(String.Format("Transferring asset {0} ({1})", asset.AssetID, asset.AssetType), Helpers.LogLevel.Info); TransferInfoPacket response = new TransferInfoPacket(); response.TransferInfo = new TransferInfoPacket.TransferInfoBlock(); response.TransferInfo.TransferID = transferID; response.TransferInfo.Params = new byte[20]; Buffer.BlockCopy(asset.AssetID.GetBytes(), 0, response.TransferInfo.Params, 0, 16); Buffer.BlockCopy(Utils.IntToBytes((int)asset.AssetType), 0, response.TransferInfo.Params, 16, 4); response.TransferInfo.ChannelType = (int)ChannelType.Asset; response.TransferInfo.Size = asset.AssetData.Length; response.TransferInfo.Status = (int)StatusCode.OK; response.TransferInfo.TargetType = (int)TargetType.Unknown; // Doesn't seem to be used by the client scene.UDP.SendPacket(agent.ID, response, PacketCategory.Asset); // Transfer system does not wait for ACKs, just sends all of the // packets for this transfer out const int MAX_CHUNK_SIZE = Settings.MAX_PACKET_SIZE - 100; int processedLength = 0; int packetNum = 0; while (processedLength < asset.AssetData.Length) { TransferPacketPacket transfer = new TransferPacketPacket(); transfer.TransferData.ChannelType = (int)ChannelType.Asset; transfer.TransferData.TransferID = transferID; transfer.TransferData.Packet = packetNum++; int chunkSize = Math.Min(asset.AssetData.Length - processedLength, MAX_CHUNK_SIZE); transfer.TransferData.Data = new byte[chunkSize]; Buffer.BlockCopy(asset.AssetData, processedLength, transfer.TransferData.Data, 0, chunkSize); processedLength += chunkSize; if (processedLength >= asset.AssetData.Length) transfer.TransferData.Status = (int)StatusCode.Done; else transfer.TransferData.Status = (int)StatusCode.OK; scene.UDP.SendPacket(agent.ID, transfer, PacketCategory.Asset); } }
private void TransferDownload(LLAgent agent, UUID transferID, UUID assetID, AssetType type, Asset asset) { const int MAX_CHUNK_SIZE = 1000; string contentType = LLUtil.LLAssetTypeToContentType((int)type); if (contentType == asset.ContentType) { m_log.Debug(String.Format("Transferring asset {0} ({1})", asset.ID, asset.ContentType)); TransferInfoPacket response = new TransferInfoPacket(); response.TransferInfo = new TransferInfoPacket.TransferInfoBlock(); response.TransferInfo.TransferID = transferID; // Set the response channel type response.TransferInfo.ChannelType = (int)ChannelType.Asset; // Params response.TransferInfo.Params = new byte[20]; assetID.ToBytes(response.TransferInfo.Params, 0); Utils.IntToBytes((int)type, response.TransferInfo.Params, 16); response.TransferInfo.Size = asset.Data.Length; response.TransferInfo.Status = (int)StatusCode.OK; response.TransferInfo.TargetType = (int)TargetType.Unknown; // Doesn't seem to be used by the client m_udp.SendPacket(agent, response, ThrottleCategory.Asset, false); // Transfer system does not wait for ACKs, just sends all of the // packets for this transfer out int processedLength = 0; int packetNum = 0; while (processedLength < asset.Data.Length) { TransferPacketPacket transfer = new TransferPacketPacket(); transfer.TransferData.ChannelType = (int)ChannelType.Asset; transfer.TransferData.TransferID = transferID; transfer.TransferData.Packet = packetNum++; int chunkSize = Math.Min(asset.Data.Length - processedLength, MAX_CHUNK_SIZE); transfer.TransferData.Data = new byte[chunkSize]; Buffer.BlockCopy(asset.Data, processedLength, transfer.TransferData.Data, 0, chunkSize); processedLength += chunkSize; if (processedLength >= asset.Data.Length) { transfer.TransferData.Status = (int)StatusCode.Done; } else { transfer.TransferData.Status = (int)StatusCode.OK; } m_udp.SendPacket(agent, transfer, ThrottleCategory.Asset, false); } } else { m_log.WarnFormat("Request for asset {0} with type {1} does not match actual asset type {2}", assetID, type, asset.ContentType); TransferNotFound(agent, transferID, assetID, type); } }
private void TransferDownload(LLAgent agent, UUID transferID, UUID assetID, AssetType type, Asset asset) { const int MAX_CHUNK_SIZE = 1000; string contentType = LLUtil.LLAssetTypeToContentType((int)type); if (contentType == asset.ContentType) { m_log.Debug(String.Format("Transferring asset {0} ({1})", asset.ID, asset.ContentType)); TransferInfoPacket response = new TransferInfoPacket(); response.TransferInfo = new TransferInfoPacket.TransferInfoBlock(); response.TransferInfo.TransferID = transferID; // Set the response channel type response.TransferInfo.ChannelType = (int)ChannelType.Asset; // Params response.TransferInfo.Params = new byte[20]; assetID.ToBytes(response.TransferInfo.Params, 0); Utils.IntToBytes((int)type, response.TransferInfo.Params, 16); response.TransferInfo.Size = asset.Data.Length; response.TransferInfo.Status = (int)StatusCode.OK; response.TransferInfo.TargetType = (int)TargetType.Unknown; // Doesn't seem to be used by the client m_udp.SendPacket(agent, response, ThrottleCategory.Asset, false); // Transfer system does not wait for ACKs, just sends all of the // packets for this transfer out int processedLength = 0; int packetNum = 0; while (processedLength < asset.Data.Length) { TransferPacketPacket transfer = new TransferPacketPacket(); transfer.TransferData.ChannelType = (int)ChannelType.Asset; transfer.TransferData.TransferID = transferID; transfer.TransferData.Packet = packetNum++; int chunkSize = Math.Min(asset.Data.Length - processedLength, MAX_CHUNK_SIZE); transfer.TransferData.Data = new byte[chunkSize]; Buffer.BlockCopy(asset.Data, processedLength, transfer.TransferData.Data, 0, chunkSize); processedLength += chunkSize; if (processedLength >= asset.Data.Length) transfer.TransferData.Status = (int)StatusCode.Done; else transfer.TransferData.Status = (int)StatusCode.OK; m_udp.SendPacket(agent, transfer, ThrottleCategory.Asset, false); } } else { m_log.WarnFormat("Request for asset {0} with type {1} does not match actual asset type {2}", assetID, type, asset.ContentType); TransferNotFound(agent, transferID, assetID, type); } }
private void TransferPacketHandler(Packet packet, Simulator simulator) { TransferPacketPacket asset = (TransferPacketPacket)packet; Transfer transfer; AssetDownload download; if (Transfers.TryGetValue(asset.TransferData.TransferID, out transfer)) { download = (AssetDownload)transfer; if (download.Size == 0) { Client.DebugLog("TransferPacket received ahead of the transfer header, blocking..."); // We haven't received the header yet, block until it's received or times out download.HeaderReceivedEvent.WaitOne(1000 * 20, false); if (download.Size == 0) { Client.Log("Timed out while waiting for the asset header to download for " + download.ID.ToString(), Helpers.LogLevel.Warning); // Abort the transfer TransferAbortPacket abort = new TransferAbortPacket(); abort.TransferInfo.ChannelType = (int)download.Channel; abort.TransferInfo.TransferID = download.ID; Client.Network.SendPacket(abort, download.Simulator); download.Success = false; lock (Transfers) Transfers.Remove(download.ID); // Fire the event with our transfer that contains Success = false if (OnAssetReceived != null) { try { OnAssetReceived(download, null); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } return; } } // This assumes that every transfer packet except the last one is exactly 1000 bytes, // hopefully that is a safe assumption to make Buffer.BlockCopy(asset.TransferData.Data, 0, download.AssetData, 1000 * asset.TransferData.Packet, asset.TransferData.Data.Length); download.Transferred += asset.TransferData.Data.Length; //Client.DebugLog(String.Format("Transfer packet {0}, received {1}/{2}/{3} bytes for asset {4}", // asset.TransferData.Packet, asset.TransferData.Data.Length, transfer.Transferred, transfer.Size, // transfer.AssetID.ToString())); // Check if we downloaded the full asset if (download.Transferred >= download.Size) { Client.DebugLog("Transfer for asset " + download.AssetID.ToString() + " completed"); download.Success = true; lock (Transfers) Transfers.Remove(download.ID); if (OnAssetReceived != null) { try { OnAssetReceived(download, WrapAsset(download)); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } } } }
/// <summary> /// /// </summary> private void ProcessAssetQueue() { if (this.AssetRequests.Count == 0) { //no requests waiting return; } int num; if (this.AssetRequests.Count < 5) { //lower than 5 so do all of them num = this.AssetRequests.Count; } else { num = 5; } AssetRequest req; for (int i = 0; i < num; i++) { req = (AssetRequest)this.AssetRequests[i]; TransferInfoPacket Transfer = new TransferInfoPacket(); Transfer.TransferInfo.ChannelType = 2; Transfer.TransferInfo.Status = 0; Transfer.TransferInfo.TargetType = 0; Transfer.TransferInfo.Params = req.RequestAssetID.GetBytes(); Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; Transfer.TransferInfo.TransferID = req.TransferRequestID; req.RequestUser.OutPacket(Transfer); 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); } else { //more than one packet so split file up , for now it can't be bigger than 2000 bytes TransferPacketPacket TransferPacket = new TransferPacketPacket(); TransferPacket.TransferData.Packet = 0; TransferPacket.TransferData.ChannelType = 2; TransferPacket.TransferData.TransferID = req.TransferRequestID; byte[] chunk = new byte[1000]; Array.Copy(req.AssetInf.Data, chunk, 1000); TransferPacket.TransferData.Data = chunk; TransferPacket.TransferData.Status = 0; req.RequestUser.OutPacket(TransferPacket); TransferPacket = new TransferPacketPacket(); TransferPacket.TransferData.Packet = 1; TransferPacket.TransferData.ChannelType = 2; TransferPacket.TransferData.TransferID = req.TransferRequestID; byte[] chunk1 = new byte[(req.AssetInf.Data.Length - 1000)]; Array.Copy(req.AssetInf.Data, 1000, chunk1, 0, chunk1.Length); TransferPacket.TransferData.Data = chunk1; TransferPacket.TransferData.Status = 1; req.RequestUser.OutPacket(TransferPacket); } } //remove requests that have been completed for (int i = 0; i < num; i++) { this.AssetRequests.RemoveAt(0); } }
private Packet LoadingUpNewScript(Packet packet, IPEndPoint sim) { if (packet.Header.Resent) { return(packet); } TransferPacketPacket tpp = (TransferPacketPacket)packet; if (tpp.TransferData.ChannelType == 2 && tpp.TransferData.Packet == 0 && scriptInfos.ContainsKey(tpp.TransferData.TransferID)) { string data = Utils.BytesToString(tpp.TransferData.Data); if (data.Contains("//-->(LGG_PROTECTED)")) { string incache = "Scripts Cache\\" + data.Substring(20, 36) + ".lsl"; form.log("Detected a localy saved script, looking.." + incache, System.Drawing.Color.DarkBlue, System.Drawing.Color.Cyan); if (File.Exists(incache)) { form.log("Found !localy saved script, loading..", System.Drawing.Color.Blue, System.Drawing.Color.Cyan); using (StreamReader r = new StreamReader(incache)) { byte[] newdata = Utils.StringToBytes(r.ReadToEnd()); r.Close(); TransferInfoPacket tosend = scriptInfos[tpp.TransferData.TransferID]; scriptInfos.Remove(tpp.TransferData.TransferID); tosend.TransferInfo.Size = newdata.Length + (1000 - (newdata.Length % 1000)); proxy.InjectPacket(tosend, Direction.Incoming); form.log("Injecting info with size " + tosend.TransferInfo.Size.ToString(), System.Drawing.Color.Blue, System.Drawing.Color.Cyan); int start = 0; int pnum = 0; byte[] temp = new byte[1000]; while (newdata.Length - start > 1000) { Buffer.BlockCopy(newdata, start, temp, 0, 1000); TransferPacketPacket send = tpp; send.TransferData.Packet = pnum++; send.TransferData.Data = temp; send.TransferData.Status = (int)StatusCode.OK; proxy.InjectPacket(send, Direction.Incoming); start += 1000; form.log("Injecting Packet number " + pnum.ToString(), System.Drawing.Color.Blue, System.Drawing.Color.Cyan); } temp = new byte[1000]; Buffer.BlockCopy(newdata, start, temp, 0, newdata.Length - start); tpp.TransferData.Data = temp; tpp.TransferData.Status = (int)StatusCode.Done; tpp.TransferData.Packet = pnum++; form.log("Injecting Packet number " + pnum.ToString(), System.Drawing.Color.Blue, System.Drawing.Color.Cyan); } } else { form.log("oh shit.. cant find the script... f*" + incache, System.Drawing.Color.DarkBlue, System.Drawing.Color.Cyan); } } else { TransferInfoPacket tosend = scriptInfos[tpp.TransferData.TransferID]; scriptInfos.Remove(tpp.TransferData.TransferID); proxy.InjectPacket(tosend, Direction.Incoming); } } return(tpp); }
public void AssetReceived(AssetBase asset) { //m_log.Debug("sending asset " + req.RequestAssetID); TransferInfoPacket Transfer = new TransferInfoPacket(); Transfer.TransferInfo.ChannelType = 2; Transfer.TransferInfo.Status = 0; Transfer.TransferInfo.TargetType = 0; if (source == 2) { Transfer.TransferInfo.Params = new byte[20]; Array.Copy(assetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); int assType = asset.Type; Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); } else if (source == 3) { Transfer.TransferInfo.Params = Params; } Transfer.TransferInfo.Size = asset.Data.Length; //req.AssetInf.Data.Length; Transfer.TransferInfo.TransferID = transferID; Transfer.Header.Zerocoded = true; //OutPacket(Transfer, ThrottleOutPacketType.Asset); proxy.InjectPacket(Transfer, Direction.Incoming); int npackets = CalculateNumPackets(asset.Data); if (npackets == 1) { TransferPacketPacket TransferPacket = new TransferPacketPacket(); TransferPacket.TransferData.Packet = 0; TransferPacket.TransferData.ChannelType = 2; TransferPacket.TransferData.TransferID = transferID; TransferPacket.TransferData.Data = asset.Data; TransferPacket.TransferData.Status = 1; TransferPacket.Header.Zerocoded = true; //OutPacket(TransferPacket, ThrottleOutPacketType.Asset); proxy.InjectPacket(TransferPacket, Direction.Incoming); } else { int processedLength = 0; int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; int packetNumber = 0; while (processedLength < asset.Data.Length) { TransferPacketPacket TransferPacket = new TransferPacketPacket(); TransferPacket.TransferData.Packet = packetNumber; TransferPacket.TransferData.ChannelType = 2; TransferPacket.TransferData.TransferID = transferID; int chunkSize = Math.Min(asset.Data.Length - processedLength, maxChunkSize); byte[] chunk = new byte[chunkSize]; Array.Copy(asset.Data, processedLength, chunk, 0, chunk.Length); TransferPacket.TransferData.Data = chunk; // 0 indicates more packets to come, 1 indicates last packet if (asset.Data.Length - processedLength > maxChunkSize) { TransferPacket.TransferData.Status = 0; } else { TransferPacket.TransferData.Status = 1; } TransferPacket.Header.Zerocoded = true; //OutPacket(TransferPacket, ThrottleOutPacketType.Asset); proxy.InjectPacket(TransferPacket, Direction.Incoming); processedLength += chunkSize; packetNumber++; } } }
void TransferRequestHandler(Packet packet, Agent agent) { TransferRequestPacket request = (TransferRequestPacket)packet; ChannelType channel = (ChannelType)request.TransferInfo.ChannelType; SourceType source = (SourceType)request.TransferInfo.SourceType; if (channel == ChannelType.Asset) { // Construct the response packet TransferInfoPacket response = new TransferInfoPacket(); response.TransferInfo = new TransferInfoPacket.TransferInfoBlock(); response.TransferInfo.TransferID = request.TransferInfo.TransferID; if (source == SourceType.Asset) { // Parse the request UUID assetID = new UUID(request.TransferInfo.Params, 0); AssetType type = (AssetType)(sbyte)Utils.BytesToInt(request.TransferInfo.Params, 16); // Set the response channel type response.TransferInfo.ChannelType = (int)ChannelType.Asset; // Params response.TransferInfo.Params = new byte[20]; Buffer.BlockCopy(assetID.GetBytes(), 0, response.TransferInfo.Params, 0, 16); Buffer.BlockCopy(Utils.IntToBytes((int)type), 0, response.TransferInfo.Params, 16, 4); // Check if we have this asset Asset asset; if (AssetStore.TryGetValue(assetID, out asset)) { if (asset.AssetType == type) { Logger.DebugLog(String.Format("Transferring asset {0} ({1})", asset.AssetID, asset.AssetType)); // Asset found response.TransferInfo.Size = asset.AssetData.Length; response.TransferInfo.Status = (int)StatusCode.OK; response.TransferInfo.TargetType = (int)TargetType.Unknown; // Doesn't seem to be used by the client server.UDP.SendPacket(agent.AgentID, response, PacketCategory.Asset); // Transfer system does not wait for ACKs, just sends all of the // packets for this transfer out const int MAX_CHUNK_SIZE = Settings.MAX_PACKET_SIZE - 100; int processedLength = 0; int packetNum = 0; while (processedLength < asset.AssetData.Length) { TransferPacketPacket transfer = new TransferPacketPacket(); transfer.TransferData.ChannelType = (int)ChannelType.Asset; transfer.TransferData.TransferID = request.TransferInfo.TransferID; transfer.TransferData.Packet = packetNum++; int chunkSize = Math.Min(asset.AssetData.Length - processedLength, MAX_CHUNK_SIZE); transfer.TransferData.Data = new byte[chunkSize]; Buffer.BlockCopy(asset.AssetData, processedLength, transfer.TransferData.Data, 0, chunkSize); processedLength += chunkSize; if (processedLength >= asset.AssetData.Length) { transfer.TransferData.Status = (int)StatusCode.Done; } else { transfer.TransferData.Status = (int)StatusCode.OK; } server.UDP.SendPacket(agent.AgentID, transfer, PacketCategory.Asset); } } else { Logger.Log(String.Format( "Request for asset {0} with type {1} does not match actual asset type {2}", assetID, type, asset.AssetType), Helpers.LogLevel.Warning); } } else { Logger.Log(String.Format("Request for missing asset {0} with type {1}", assetID, type), Helpers.LogLevel.Warning); // Asset not found response.TransferInfo.Size = 0; response.TransferInfo.Status = (int)StatusCode.UnknownSource; response.TransferInfo.TargetType = (int)TargetType.Unknown; server.UDP.SendPacket(agent.AgentID, response, PacketCategory.Asset); } } else if (source == SourceType.SimEstate) { UUID agentID = new UUID(request.TransferInfo.Params, 0); UUID sessionID = new UUID(request.TransferInfo.Params, 16); EstateAssetType type = (EstateAssetType)Utils.BytesToInt(request.TransferInfo.Params, 32); Logger.Log("Please implement estate asset transfers", Helpers.LogLevel.Warning); } else if (source == SourceType.SimInventoryItem) { UUID agentID = new UUID(request.TransferInfo.Params, 0); UUID sessionID = new UUID(request.TransferInfo.Params, 16); UUID ownerID = new UUID(request.TransferInfo.Params, 32); UUID taskID = new UUID(request.TransferInfo.Params, 48); UUID itemID = new UUID(request.TransferInfo.Params, 64); UUID assetID = new UUID(request.TransferInfo.Params, 80); AssetType type = (AssetType)(sbyte)Utils.BytesToInt(request.TransferInfo.Params, 96); if (taskID != UUID.Zero) { // Task (prim) inventory request Logger.Log("Please implement task inventory transfers", Helpers.LogLevel.Warning); } else { // Agent inventory request Logger.Log("Please implement agent inventory transfer", Helpers.LogLevel.Warning); } } else { Logger.Log(String.Format( "Received a TransferRequest that we don't know how to handle. Channel: {0}, Source: {1}", channel, source), Helpers.LogLevel.Warning); } } else { Logger.Log(String.Format( "Received a TransferRequest that we don't know how to handle. Channel: {0}, Source: {1}", channel, source), Helpers.LogLevel.Warning); } }