Files
opensim/OpenSim/Region/Environment/Modules/TextureSender.cs
2008-01-03 13:44:52 +00:00

136 lines
4.9 KiB
C#

using System;
using libsecondlife;
using libsecondlife.Packets;
using OpenSim.Framework;
using OpenSim.Framework.Console;
namespace OpenSim.Region.Environment.Modules
{
public class TextureSender
{
public int counter = 0;
private AssetBase m_asset;
public long DataPointer = 0;
public int NumPackets = 0;
public int PacketCounter = 0;
public bool Cancel = false;
public bool ImageLoaded = false;
public bool Sending = false;
public IClientAPI RequestUser;
public LLUUID RequestedAssetID;
public int RequestedDiscardLevel = -1;
public uint StartPacketNumber = 0;
// private int m_sentDiscardLevel = -1;
public TextureSender(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber)
{
RequestUser = client;
RequestedAssetID = textureID;
RequestedDiscardLevel = discardLevel;
StartPacketNumber = packetNumber;
}
public void TextureReceived(AssetBase asset)
{
m_asset = asset;
NumPackets = CalculateNumPackets(asset.Data.Length);
PacketCounter = (int) StartPacketNumber;
ImageLoaded = true;
}
public void UpdateRequest(int discardLevel, uint packetNumber)
{
RequestedDiscardLevel = discardLevel;
StartPacketNumber = packetNumber;
PacketCounter = (int) StartPacketNumber;
}
public bool SendTexturePacket()
{
SendPacket();
counter++;
if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets/(RequestedDiscardLevel + 1)))))
{
return true;
}
return false;
}
private void SendPacket()
{
if (PacketCounter <= NumPackets)
{
if (PacketCounter == 0)
{
if (NumPackets == 0)
{
ImageDataPacket im = new ImageDataPacket();
im.Header.Reliable = false;
im.ImageID.Packets = 1;
im.ImageID.ID = m_asset.FullID;
im.ImageID.Size = (uint) m_asset.Data.Length;
im.ImageData.Data = m_asset.Data;
im.ImageID.Codec = 2;
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
PacketCounter++;
}
else
{
ImageDataPacket im = new ImageDataPacket();
im.Header.Reliable = false;
im.ImageID.Packets = (ushort) (NumPackets);
im.ImageID.ID = m_asset.FullID;
im.ImageID.Size = (uint) m_asset.Data.Length;
im.ImageData.Data = new byte[600];
Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
im.ImageID.Codec = 2;
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
PacketCounter++;
}
}
else
{
ImagePacketPacket im = new ImagePacketPacket();
im.Header.Reliable = false;
im.ImageID.Packet = (ushort) (PacketCounter);
im.ImageID.ID = m_asset.FullID;
int size = m_asset.Data.Length - 600 - (1000*(PacketCounter - 1));
if (size > 1000) size = 1000;
im.ImageData.Data = new byte[size];
try
{
Array.Copy(m_asset.Data, 600 + (1000*(PacketCounter - 1)), im.ImageData.Data, 0, size);
}
catch (ArgumentOutOfRangeException)
{
MainLog.Instance.Error("TEXTURE",
"Unable to separate texture into multiple packets: Array bounds failure on asset:" +
m_asset.FullID.ToString() );
return;
}
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
PacketCounter++;
}
}
}
private int CalculateNumPackets(int length)
{
int numPackets = 0;
if (length > 600)
{
//over 600 bytes so split up file
int restData = (length - 600);
int restPackets = ((restData + 999)/1000);
numPackets = restPackets;
}
return numPackets;
}
}
}