Ejemplo n.º 1
0
        private Asset CreateAsset(AssetType type, UUID assetID, DateTime creationDate, UUID creatorID, bool local, bool temporary, byte[] data)
        {
            Asset asset = new Asset();

            asset.ID           = assetID;
            asset.ContentType  = LLUtil.LLAssetTypeToContentType((int)type);
            asset.CreationDate = creationDate;
            asset.CreatorID    = creatorID;
            asset.Data         = data;
            asset.Local        = local;
            asset.Temporary    = temporary;
            //asset.SHA1 is filled in later

            return(asset);
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        private void TransferRequestHandler(Packet packet, LLAgent agent)
        {
            TransferRequestPacket request = (TransferRequestPacket)packet;

            ChannelType channel = (ChannelType)request.TransferInfo.ChannelType;
            SourceType  source  = (SourceType)request.TransferInfo.SourceType;

            if (channel == ChannelType.Asset)
            {
                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);
                    string    contentType = LLUtil.LLAssetTypeToContentType((int)type);

                    // Permission check
                    if (!CanDownloadInventory(agent, type, assetID))
                    {
                        TransferNotFound(agent, request.TransferInfo.TransferID, assetID, type);
                        return;
                    }

                    // Check if we have this asset
                    Asset asset;
                    if (m_assets.TryGetAsset(assetID, contentType, out asset))
                    {
                        TransferDownload(agent, request.TransferInfo.TransferID, assetID, type, asset);
                    }
                    else
                    {
                        TransferNotFound(agent, request.TransferInfo.TransferID, assetID, type);
                    }
                }
                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);
                    string    contentType = LLUtil.LLAssetTypeToContentType((int)type);

                    if (taskID != UUID.Zero)
                    {
                        // Task (prim) inventory request permission check
                        if (!CanDownloadTaskInventory(agent, type, taskID, itemID))
                        {
                            TransferNotFound(agent, request.TransferInfo.TransferID, assetID, type);
                            return;
                        }
                    }
                    else
                    {
                        // Agent inventory request permission check
                        if (!CanDownloadInventory(agent, type, assetID))
                        {
                            TransferNotFound(agent, request.TransferInfo.TransferID, assetID, type);
                            return;
                        }
                    }

                    // Check if we have this asset
                    Asset asset;
                    if (m_assets.TryGetAsset(assetID, contentType, out asset))
                    {
                        TransferDownload(agent, request.TransferInfo.TransferID, assetID, type, asset);
                    }
                    else
                    {
                        TransferNotFound(agent, request.TransferInfo.TransferID, assetID, type);
                    }
                }
                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);

                    m_log.Warn("Don't know what to do with an estate asset transfer request");
                }
                else
                {
                    m_log.WarnFormat(
                        "Received a TransferRequest that we don't know how to handle. Channel: {0}, Source: {1}",
                        channel, source);
                }
            }
            else
            {
                m_log.WarnFormat(
                    "Received a TransferRequest that we don't know how to handle. Channel: {0}, Source: {1}",
                    channel, source);
            }
        }
Ejemplo n.º 4
0
        private void RezObject(IScriptInstance script, string inventory, Vector3 position, Vector3 vel, Quaternion rot, int param, bool atRoot)
        {
            // TODO: Test to make sure this actually rezzes from the root, and get the atRoot param working

            // Can't do this without an IAssetClient
            if (m_assetClient == null)
            {
                return;
            }

            // Sanity check the input rotation
            if (Single.IsNaN(rot.X) || Single.IsNaN(rot.Y) || Single.IsNaN(rot.Z) || Single.IsNaN(rot.W))
            {
                return;
            }

            // Sanity check the distance, silently fail at > 10m
            float dist = Vector3.Distance(script.Host.ScenePosition, position);

            if (dist > 10.0f)
            {
                return;
            }

            if (script.Host is LLPrimitive)
            {
                LLPrimitive         obj  = (LLPrimitive)script.Host;
                LLInventoryTaskItem item = obj.Inventory.FindItem(delegate(LLInventoryTaskItem match) { return(match.Name == inventory); });

                if (item != null)
                {
                    // Make sure this is an object
                    if (item.InventoryType != InventoryType.Object)
                    {
                        llSay(script, 0, "Unable to create requested object. Object is missing from database.");
                        return;
                    }

                    // Fetch the serialized linkset asset
                    Asset linksetAsset;
                    if (!m_assetClient.TryGetAsset(item.AssetID, LLUtil.LLAssetTypeToContentType((int)AssetType.Object), out linksetAsset))
                    {
                        llSay(script, 0, "Unable to create requested object. Object is missing from database.");
                        return;
                    }

                    // Deserialize the asset to LLSD
                    OSDMap linksetMap = null;
                    try { linksetMap = OSDParser.Deserialize(linksetAsset.Data) as OSDMap; }
                    catch (Exception ex) { m_log.Error("Failed to deserialize linkset from asset " + linksetAsset.ID + ": " + ex.Message); }

                    if (linksetMap == null)
                    {
                        llSay(script, 0, "Unable to create requested object. Object is corrupted in database.");
                        return;
                    }

                    // Deserialize the linkset
                    IList <LLPrimitive> linkset = LLPrimitive.DeserializeLinkset(linksetMap, obj.Scene, m_primMesher, true);

                    Vector3    velocity = vel;
                    Quaternion rotation = rot;
                    float      velMag   = velocity.Length();
                    float      mass     = (float)llGetMass(script);

                    // Rez the parent(s) first
                    for (int i = 0; i < linkset.Count; i++)
                    {
                        LLPrimitive prim = linkset[i];
                        if (prim.Parent == null)
                        {
                            // Objects rezzed with this method are DieAtEdge by default
                            prim.Prim.Flags |= PrimFlags.DieAtEdge;

                            // Set the position, rotation and velocity of the root prim in the scene
                            prim.RelativePosition = position;
                            prim.RelativeRotation = rotation;
                            if (prim.Prim.Flags.HasFlag(PrimFlags.Physics))
                            {
                                prim.FallStart = Util.TickCount();
                                prim.Velocity  = velocity;
                            }

                            obj.Scene.EntityAddOrUpdate(this, prim, UpdateFlags.FullUpdate, 0);
                            m_log.Debug("Deserialized root prim " + prim.ID + " (" + prim.LocalID + ") from task inventory");
                        }
                    }

                    // Rez the children
                    for (int i = 0; i < linkset.Count; i++)
                    {
                        LLPrimitive prim = linkset[i];
                        if (prim.Parent != null)
                        {
                            obj.Scene.EntityAddOrUpdate(this, prim, UpdateFlags.FullUpdate, 0);
                        }
                    }

                    // FIXME: Post an object_rez event

                    if (obj.Prim.Flags.HasFlag(PrimFlags.Physics))
                    {
                        obj.FallStart = Util.TickCount();
                        // FIXME: Recoil
                        //llApplyImpulse(script, new lsl_vector(velocity.X * mass, velocity.Y * mass, velocity.Z * mass), 0);
                    }

                    // Variable script delay (http://wiki.secondlife.com/wiki/LSL_Delay)
                    script.AddSleepMS((int)((mass * velMag) * 0.1f));
                    script.AddSleepMS(200);
                }
                else
                {
                    llSay(script, 0, "Could not find object " + inventory);
                }
            }
        }