Пример #1
0
        // Methods

        private bool VerifySignature(User user, string querystring)
        {
            // Check that we have enough characters to avoid an ArgumentOutOfRangeException.
            // If we don't have at least this many, there's certainly no hash anyway.
            if (querystring.Length < 38)
            {
                return(false);
            }

            // All this does the same job as the following on the client side:
            // var tohash = (++AjaxLife.SignedCallCount).toString() + querystring + AjaxLife.Signature;
            // var hash = md5(tohash);

            // First we have to remove the hash from the incoming string. We may assume the has is always at the end.
            // This makes the job easy - we just chop the end off. No parsing required.
            // MD5s are 128 bits, or 32 hex characters, so we chop off "&hash=00000000000000000000000000000000", which is
            // 38 characters.
            string receivedhash = querystring.Substring(querystring.Length - 32);                                                        // Grab the last 32 characters.

            querystring = querystring.Remove(querystring.Length - 38);                                                                   // Strip the hash off.
            ++user.SignedCallCount;                                                                                                      // Increment the call count to ensure the same hash can't be used multiple times.
            string tohash       = user.SignedCallCount.ToString() + querystring + user.Signature;                                        // Build the to hash string.
            string expectedhash = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(tohash))).Replace("-", "").ToLower(); // Actually hash it.

            AjaxLife.Debug("SendMessage", "VerifySignature: Received hash " + receivedhash + ", expected " + expectedhash + " (based on '" + tohash + "')");
            // Check if they're equal.
            return(receivedhash == expectedhash);
        }
Пример #2
0
        // Someone wants logout.kat?
        public void OnFileRequested(HttpRequest request, IDirectory directory)
        {
            request.Response.ResponseContent = new MemoryStream();
            StreamWriter writer = new StreamWriter(request.Response.ResponseContent);

            try
            {
                StreamReader reader = new StreamReader(request.PostData);
                string       post   = reader.ReadToEnd();
                reader.Dispose();
                // Get the user session and GridClient object.
                Dictionary <string, string> POST = AjaxLife.PostDecode(post);
                Guid       session = new Guid(POST["sid"]);
                GridClient client;
                User       user;
                lock (users)
                {
                    user             = users[session];
                    client           = user.Client;
                    user.LastRequest = DateTime.Now;
                }
                // If we're connected, request a logout.
                if (client.Network.Connected)
                {
                    client.Network.Logout();
                    client.Network.Shutdown(NetworkManager.DisconnectType.ClientInitiated);
                    System.Threading.Thread.Sleep(2000);
                }
                // Deactivate the event queue.
                if (user.Events != null)
                {
                    user.Events.deactivate();
                }
                // Unset everything for garbage collection purposes.
                user.Events  = null;
                user.Client  = null;
                client       = null;
                user.Avatars = null;
                // Remove the user
                lock (users)
                {
                    users.Remove(session);
                }
                // Announce our success.
                writer.WriteLine("{success: true}");
            }
            catch (Exception e)
            {
                request.Response.ContentType = "text/plain";
                writer.WriteLine(e.Message);
            }
            writer.Flush();
        }
Пример #3
0
        public void OnFileRequested(HttpRequest request, IDirectory directory)
        {
            request.Response.ResponseContent = new MemoryStream();
            StreamWriter writer = new StreamWriter(request.Response.ResponseContent);

            StreamReader reader = new StreamReader(request.PostData);
            string       post   = reader.ReadToEnd();

            reader.Dispose();
            Dictionary <string, string> POST = AjaxLife.PostDecode(post);

            Hashtable hash = new Hashtable();

            hash.Add("SESSION_ID", POST["sid"]);
            hash.Add("STATIC_ROOT", AjaxLife.STATIC_ROOT);

            Html.Template.Parser parser = new Html.Template.Parser(hash);
            writer.Write(parser.Parse(File.ReadAllText("client/Templates/iPhone.html")));;
            writer.Flush();
        }
Пример #4
0
        public void OnFileRequested(HttpRequest request, IDirectory directory)
        {
            request.Response.ResponseContent = new MemoryStream();
            StreamWriter writer = new StreamWriter(request.Response.ResponseContent);

            try
            {
                SecondLife client;
                User       user;
                // Get the session.
                Dictionary <string, string> POST = AjaxLife.PostDecode((new StreamReader(request.PostData)).ReadToEnd());
                Guid sessionid = new Guid(POST["sid"]);
                // Standard user stuff.
                lock (users)
                {
                    user             = users[sessionid];
                    client           = user.Client;
                    user.LastRequest = DateTime.Now;
                    // Clear the inventory cache to avoid confusion.
                    user.Events.ClearInventory();
                }
                Hashtable data = new Hashtable();
                Dictionary <string, int> pos = new Dictionary <string, int>();
                pos.Add("x", (int)Math.Floor(client.Self.GlobalPosition.X / 256));
                pos.Add("y", (int)Math.Floor(client.Self.GlobalPosition.Y / 256));
                data.Add("RegionCoords", pos);
                data.Add("Region", client.Network.CurrentSim.Name);
                data.Add("Position", client.Self.SimPosition);
                data.Add("MOTD", client.Network.LoginMessage);
                data.Add("UserName", client.Self.FirstName + " " + client.Self.LastName);
                data.Add("AgentID", client.Self.AgentID);
                data.Add("InventoryRoot", client.Inventory.Store.RootFolder.UUID);
                writer.Write(MakeJson.FromHashtable(data));
                writer.Flush();
            }
            catch (Exception e)
            {
                writer.WriteLine("Error: " + e.Message);
            }
            writer.Flush();
        }
Пример #5
0
        public void OnFileRequested(HttpRequest request, IDirectory directory)
        {
            request.Response.ResponseContent = new MemoryStream();
            StreamWriter writer = new StreamWriter(request.Response.ResponseContent);

            try
            {
                StreamReader reader = new StreamReader(request.PostData);
                string       post   = reader.ReadToEnd();
                reader.Dispose();
                // Decode the POST data.
                Dictionary <string, string> POST = AjaxLife.PostDecode(post);
                Guid       session = new Guid(POST["sid"]);
                Events     eventqueue;
                User       user;
                SecondLife client;
                // Load in the session data.
                lock (users)
                {
                    user             = users[session];
                    eventqueue       = user.Events;
                    client           = user.Client;
                    user.LastRequest = DateTime.Now;
                }
                bool   sent    = false;
                double heading = user.Rotation;
                // Check once per second, timing out after 15 seconds.
                for (int i = 0; i < 15; ++i)
                {
                    // Ugly hack - we're riding on the back of the event poll to rotate our camera.
                    if (user.Rotation != -4)
                    {
                        // If we've reached π, having started at -π, we're done. Quit rotating, because it
                        // appears to annoy people and/or make them dizzy.
                        heading += 0.5d;
                        if (heading > Math.PI)
                        {
                            // We use -4 because -4 < -π, so will never occur during normal operation.
                            user.Rotation = -4;
                            heading       = Math.PI;
                        }
                        else
                        {
                            user.Rotation = heading;
                        }
                        client.Self.Movement.UpdateFromHeading(heading, false);
                    }

                    if (eventqueue.GetEventCount() > 0)
                    {
                        writer.WriteLine(eventqueue.GetPendingJson(client));
                        sent = true;
                        break;
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                }
                // If nothing of interest ever came up, we just send the standard footer.
                if (!sent)
                {
                    JsonWriter w = new JsonWriter(writer);
                    w.WriteStartArray();
                    (new JsonSerializer()).Serialize(w, eventqueue.GetFooter(client));
                    w.WriteEndArray();
                    w.Flush();
                }
            }
            catch (Exception e)
            {
                request.Response.ContentType = "text/plain";
                writer.WriteLine(e.Message);
            }
            writer.Flush();
        }
Пример #6
0
        public void OnFileRequested(HttpRequest request, IDirectory directory)
        {
            //request.Response.SetHeader("Content-Type", "text/plain; charset=utf-8");
            request.Response.ResponseContent = new MemoryStream();
            StreamWriter  textwriter = new StreamWriter(request.Response.ResponseContent);
            SecondLife    client;
            AvatarTracker avatars;
            Events        events;
            StreamReader  reader  = new StreamReader(request.PostData);
            string        qstring = reader.ReadToEnd();

            reader.Dispose();
            Dictionary <string, string> POST = AjaxLife.PostDecode(qstring);

            // Pull out the session.
            if (!POST.ContainsKey("sid"))
            {
                textwriter.WriteLine("Need an SID.");
                textwriter.Flush();
                return;
            }
            Guid guid = new Guid(POST["sid"]);
            User user = new User();

            lock (this.users)
            {
                if (!this.users.ContainsKey(guid))
                {
                    textwriter.WriteLine("Error: invalid SID");
                    textwriter.Flush();
                    return;
                }
                user             = this.users[guid];
                client           = user.Client;
                avatars          = user.Avatars;
                events           = user.Events;
                user.LastRequest = DateTime.Now;
            }
            // Get the message type.
            string messagetype = POST["MessageType"];

            // Check that the message is signed if it should be.
            if (Array.IndexOf(REQUIRED_SIGNATURES, messagetype) > -1)
            {
                if (!VerifySignature(user, qstring))
                {
                    textwriter.WriteLine("Error: Received hash and expected hash do not match.");
                    textwriter.Flush();
                    return;
                }
            }

            // Right. This file is fun. It takes information in POST paramaters and sends them to
            // the server in the appropriate format. Some will return data immediately, some will return
            // keys to data that will arrive in the message queue, some return nothing but you get
            // something in the message queue later, and some return nother ever.
            //
            // The joys of dealing with multiple bizarre message types.

            switch (messagetype)
            {
            case "SpatialChat":
                client.Self.Chat(POST["Message"], int.Parse(POST["Channel"]), (ChatType)((byte)int.Parse(POST["Type"])));
                break;

            case "SimpleInstantMessage":
                if (POST.ContainsKey("IMSessionID"))
                {
                    client.Self.InstantMessage(new LLUUID(POST["Target"]), POST["Message"], new LLUUID(POST["IMSessionID"]));
                }
                else
                {
                    client.Self.InstantMessage(new LLUUID(POST["Target"]), POST["Message"]);
                }
                break;

            case "GenericInstantMessage":
                client.Self.InstantMessage(
                    client.Self.FirstName + " " + client.Self.LastName,
                    new LLUUID(POST["Target"]),
                    POST["Message"],
                    new LLUUID(POST["IMSessionID"]),
                    (InstantMessageDialog)((byte)int.Parse(POST["Dialog"])),
                    (InstantMessageOnline)int.Parse(POST["Online"]),
                    client.Self.SimPosition,
                    client.Network.CurrentSim.ID,
                    new byte[0]);
                break;

            case "NameLookup":
                client.Avatars.RequestAvatarName(new LLUUID(POST["ID"]));
                break;

            case "Teleport":
            {
                Hashtable hash = new Hashtable();
                bool      status;
                if (POST.ContainsKey("Landmark"))
                {
                    status = client.Self.Teleport(new LLUUID(POST["Landmark"]));
                }
                else
                {
                    status = client.Self.Teleport(POST["Sim"], new LLVector3(float.Parse(POST["X"]), float.Parse(POST["Y"]), float.Parse(POST["Z"])));
                }
                if (status)
                {
                    hash.Add("Success", true);
                    hash.Add("Sim", client.Network.CurrentSim.Name);
                    hash.Add("Position", client.Self.SimPosition);
                }
                else
                {
                    hash.Add("Success", false);
                    hash.Add("Reason", client.Self.TeleportMessage);
                }
                textwriter.WriteLine(MakeJson.FromHashtable(hash));
            }
            break;

            case "GoHome":
                client.Self.GoHome();
                break;

            case "GetPosition":
            {
                Hashtable hash = new Hashtable();
                hash.Add("Sim", client.Network.CurrentSim.Name);
                hash.Add("Position", client.Self.SimPosition);
                textwriter.WriteLine(JavaScriptConvert.SerializeObject(hash));
            }
            break;

            case "RequestBalance":
                client.Self.RequestBalance();
                break;

            case "GetStats":
            {
                Hashtable hash = new Hashtable();
                hash.Add("FPS", client.Network.CurrentSim.Stats.FPS);
                hash.Add("TimeDilation", client.Network.CurrentSim.Stats.Dilation);
                hash.Add("LSLIPS", client.Network.CurrentSim.Stats.LSLIPS);
                hash.Add("Objects", client.Network.CurrentSim.Stats.Objects);
                hash.Add("ActiveScripts", client.Network.CurrentSim.Stats.ActiveScripts);
                hash.Add("Agents", client.Network.CurrentSim.Stats.Agents);
                hash.Add("ChildAgents", client.Network.CurrentSim.Stats.ChildAgents);
                hash.Add("AjaxLifeSessions", users.Count);
                hash.Add("TextureCacheCount", AjaxLife.TextureCacheCount);
                hash.Add("TextureCacheSize", AjaxLife.TextureCacheSize);
                textwriter.WriteLine(MakeJson.FromHashtable(hash));
            }
            break;

            case "TeleportLureRespond":
                client.Self.TeleportLureRespond(new LLUUID(POST["RequesterID"]), bool.Parse(POST["Accept"]));
                break;

            case "GodlikeTeleportLureRespond":
            {
                LLUUID lurer   = new LLUUID(POST["RequesterID"]);
                LLUUID session = new LLUUID(POST["SessionID"]);
                client.Self.InstantMessage(client.Self.Name, lurer, "", LLUUID.Random(), InstantMessageDialog.AcceptTeleport, InstantMessageOnline.Offline, client.Self.SimPosition, LLUUID.Zero, new byte[0]);
                TeleportLureRequestPacket lure = new TeleportLureRequestPacket();
                lure.Info.AgentID       = client.Self.AgentID;
                lure.Info.SessionID     = client.Self.SessionID;
                lure.Info.LureID        = session;
                lure.Info.TeleportFlags = (uint)AgentManager.TeleportFlags.ViaGodlikeLure;
                client.Network.SendPacket(lure);
            }
            break;

            case "FindPeople":
            {
                Hashtable hash = new Hashtable();
                hash.Add("QueryID", client.Directory.StartPeopleSearch(DirectoryManager.DirFindFlags.People, POST["Search"], int.Parse(POST["Start"])));
                textwriter.WriteLine(MakeJson.FromHashtable(hash));
            }
            break;

            case "FindGroups":
            {
                Hashtable hash = new Hashtable();
                hash.Add("QueryID", client.Directory.StartGroupSearch(DirectoryManager.DirFindFlags.Groups, POST["Search"], int.Parse(POST["Start"])));
                textwriter.WriteLine(MakeJson.FromHashtable(hash));
            }
            break;

            case "GetAgentData":
                client.Avatars.RequestAvatarProperties(new LLUUID(POST["AgentID"]));
                break;

            case "StartAnimation":
                client.Self.AnimationStart(new LLUUID(POST["Animation"]), false);
                break;

            case "StopAnimation":
                client.Self.AnimationStop(new LLUUID(POST["Animation"]), true);
                break;

            case "SendAppearance":
                client.Appearance.SetPreviousAppearance(false);
                break;

            case "GetMapItems":
            {
                MapItemRequestPacket req = new MapItemRequestPacket();
                req.AgentData.AgentID   = client.Self.AgentID;
                req.AgentData.SessionID = client.Self.SessionID;
                GridRegion region;
                client.Grid.GetGridRegion(POST["Region"], GridLayerType.Objects, out region);
                req.RequestData.RegionHandle = region.RegionHandle;
                req.RequestData.ItemType     = uint.Parse(POST["ItemType"]);
                client.Network.SendPacket((Packet)req);
            }
            break;

            case "GetMapBlocks":
            {
                MapBlockRequestPacket req = new MapBlockRequestPacket();
                req.AgentData.AgentID   = client.Self.AgentID;
                req.AgentData.SessionID = client.Self.SessionID;
                req.PositionData.MinX   = 0;
                req.PositionData.MinY   = 0;
                req.PositionData.MaxX   = ushort.MaxValue;
                req.PositionData.MaxY   = ushort.MaxValue;
                client.Network.SendPacket((Packet)req);
            }
            break;

            case "GetMapBlock":
            {
                ushort x = ushort.Parse(POST["X"]);
                ushort y = ushort.Parse(POST["Y"]);
                MapBlockRequestPacket req = new MapBlockRequestPacket();
                req.AgentData.AgentID   = client.Self.AgentID;
                req.AgentData.SessionID = client.Self.SessionID;
                req.PositionData.MinX   = x;
                req.PositionData.MinY   = y;
                req.PositionData.MaxX   = x;
                req.PositionData.MaxY   = y;
                client.Network.SendPacket((Packet)req);
            }
            break;

            case "GetOfflineMessages":
            {
                RetrieveInstantMessagesPacket req = new RetrieveInstantMessagesPacket();
                req.AgentData.AgentID   = client.Self.AgentID;
                req.AgentData.SessionID = client.Self.SessionID;
                client.Network.SendPacket((Packet)req);
            }
            break;

            case "GetFriendList":
            {
                InternalDictionary <LLUUID, FriendInfo> friends = client.Friends.FriendList;
                List <Hashtable> friendlist = new List <Hashtable>();
                friends.ForEach(delegate(FriendInfo friend)
                    {
                        Hashtable friendhash = new Hashtable();
                        friendhash.Add("ID", friend.UUID.ToString());
                        friendhash.Add("Name", friend.Name);
                        friendhash.Add("Online", friend.IsOnline);
                        friendhash.Add("MyRights", friend.MyFriendRights);
                        friendhash.Add("TheirRights", friend.TheirFriendRights);
                        friendlist.Add(friendhash);
                    });
                textwriter.Write(MakeJson.FromObject(friendlist));
            }
            break;

            case "ChangeRights":
            {
                LLUUID uuid = new LLUUID(POST["Friend"]);
                client.Friends.GrantRights(uuid, (FriendRights)int.Parse(POST["Rights"]));
            }
            break;

            case "RequestLocation":
                client.Friends.MapFriend(new LLUUID(POST["Friend"]));
                break;

            case "RequestTexture":
            {
                // This one's confusing, so it gets some comments.
                // First, we get the image's UUID.
                LLUUID image = new LLUUID(POST["ID"]);
                // We prepare a query to ask if S3 has it. HEAD only to avoid wasting
                // GET requests and bandwidth.
                bool exists = false;
                // If we already know we have it, note this.
                if (AjaxLife.CachedTextures.Contains(image))
                {
                    exists = true;
                }
                else
                {
                    // If we're using S3, check the S3 bucket
                    if (AjaxLife.USE_S3)
                    {
                        // Otherwise, make that HEAD request and find out.
                        try
                        {
                            IThreeSharp query = new ThreeSharpQuery(AjaxLife.S3Config);
                            Affirma.ThreeSharp.Model.ObjectGetRequest s3request = new Affirma.ThreeSharp.Model.ObjectGetRequest(AjaxLife.TEXTURE_BUCKET, image.ToString() + ".png");
                            s3request.Method = "HEAD";
                            Affirma.ThreeSharp.Model.ObjectGetResponse s3response = query.ObjectGet(s3request);
                            if (s3response.StatusCode == System.Net.HttpStatusCode.OK)
                            {
                                exists = true;
                            }
                            s3response.DataStream.Close();
                        }
                        catch { }
                    }
                    // If we aren't using S3, just check the texture cache.
                    else
                    {
                        exists = File.Exists(AjaxLife.TEXTURE_CACHE + image.ToString() + ".png");
                    }
                }
                // If it exists, reply with Ready = true and the URL to find it at.
                if (exists)
                {
                    textwriter.Write("{Ready: true, URL: \"" + AjaxLife.TEXTURE_ROOT + image + ".png\"}");
                }
                // If it doesn't, request the image from SL and note its lack of readiness.
                // Notification will arrive later in the message queue.
                else
                {
                    client.Assets.RequestImage(image, ImageType.Normal, 125000.0f, 0);
                    textwriter.Write("{Ready: false}");
                }
            }
            break;

            case "AcceptFriendship":
                client.Friends.AcceptFriendship(client.Self.AgentID, POST["IMSessionID"]);
                break;

            case "DeclineFriendship":
                client.Friends.DeclineFriendship(client.Self.AgentID, POST["IMSessionID"]);
                break;

            case "OfferFriendship":
                client.Friends.OfferFriendship(new LLUUID(POST["Target"]));
                break;

            case "TerminateFriendship":
                client.Friends.TerminateFriendship(new LLUUID(POST["Target"]));
                break;

            case "SendAgentMoney":
                client.Self.GiveAvatarMoney(new LLUUID(POST["Target"]), int.Parse(POST["Amount"]));
                break;

            case "RequestAvatarList":
            {
                List <Hashtable> list = new List <Hashtable>();
                foreach (KeyValuePair <uint, Avatar> pair in avatars.Avatars)
                {
                    Avatar    avatar = pair.Value;
                    Hashtable hash   = new Hashtable();
                    hash.Add("Name", avatar.Name);
                    hash.Add("ID", avatar.ID);
                    hash.Add("LocalID", avatar.LocalID);
                    hash.Add("Position", avatar.Position);
                    //hash.Add("Rotation", avatar.Rotation);
                    hash.Add("Scale", avatar.Scale);
                    hash.Add("GroupName", avatar.GroupName);
                    list.Add(hash);
                }
                textwriter.Write(MakeJson.FromObject(list));
            }
            break;

            case "LoadInventoryFolder":
                client.Inventory.RequestFolderContents(new LLUUID(POST["UUID"]), client.Self.AgentID, true, true, InventorySortOrder.ByDate | InventorySortOrder.SystemFoldersToTop);
                break;

            case "RequestAsset":
            {
                try
                {
                    LLUUID transferid = client.Assets.RequestInventoryAsset(new LLUUID(POST["AssetID"]), new LLUUID(POST["InventoryID"]),
                                                                            LLUUID.Zero, new LLUUID(POST["OwnerID"]), (AssetType)int.Parse(POST["AssetType"]), false);
                    textwriter.Write("{TransferID: \"" + transferid + "\"}");
                }
                catch         // Try catching the error that sometimes gets thrown... but sometimes doesn't.
                {
                }
            }
            break;

            case "SendTeleportLure":
                client.Self.SendTeleportLure(new LLUUID(POST["Target"]), POST["Message"]);
                break;

            case "ScriptPermissionResponse":
                client.Self.ScriptQuestionReply(client.Network.CurrentSim, new LLUUID(POST["ItemID"]), new LLUUID(POST["TaskID"]), (ScriptPermission)int.Parse(POST["Permissions"]));
                break;

            case "ScriptDialogReply":
            {
                ScriptDialogReplyPacket packet = new ScriptDialogReplyPacket();
                packet.AgentData.AgentID   = client.Self.AgentID;
                packet.AgentData.SessionID = client.Self.SessionID;
                packet.Data.ButtonIndex    = int.Parse(POST["ButtonIndex"]);
                packet.Data.ButtonLabel    = Helpers.StringToField(POST["ButtonLabel"]);
                packet.Data.ChatChannel    = int.Parse(POST["ChatChannel"]);
                packet.Data.ObjectID       = new LLUUID(POST["ObjectID"]);
                client.Network.SendPacket((Packet)packet);
            }
            break;

            case "SaveNotecard":
                client.Inventory.RequestUploadNotecardAsset(Helpers.StringToField(POST["AssetData"]), new LLUUID(POST["ItemID"]), new InventoryManager.NotecardUploadedAssetCallback(events.Inventory_OnNoteUploaded));
                break;

            case "CreateInventory":
                client.Inventory.RequestCreateItem(new LLUUID(POST["Folder"]), POST["Name"], POST["Description"], (AssetType)int.Parse(POST["AssetType"]), LLUUID.Random(), (InventoryType)int.Parse(POST["InventoryType"]), PermissionMask.All, new InventoryManager.ItemCreatedCallback(events.Inventory_OnItemCreated));
                break;

            case "CreateFolder":
            {
                LLUUID folder = client.Inventory.CreateFolder(new LLUUID(POST["Parent"]), POST["Name"]);
                textwriter.Write("{FolderID: \"" + folder + "\"}");
            }
            break;

            case "EmptyTrash":
                client.Inventory.EmptyTrash();
                break;

            case "MoveItem":
                client.Inventory.MoveItem(new LLUUID(POST["Item"]), new LLUUID(POST["TargetFolder"]), POST["NewName"]);
                break;

            case "MoveFolder":
                client.Inventory.MoveFolder(new LLUUID(POST["Folder"]), new LLUUID(POST["NewParent"]));
                break;

            case "MoveItems":
            case "MoveFolders":
            {
                Dictionary <LLUUID, LLUUID> dict = new Dictionary <LLUUID, LLUUID>();
                string[] moves = POST["ToMove"].Split(',');
                for (int i = 0; i < moves.Length; ++i)
                {
                    string[] move = moves[i].Split(' ');
                    dict.Add(new LLUUID(move[0]), new LLUUID(move[1]));
                }
                if (messagetype == "MoveItems")
                {
                    client.Inventory.MoveItems(dict);
                }
                else if (messagetype == "MoveFolders")
                {
                    client.Inventory.MoveFolders(dict);
                }
            }
            break;

            case "DeleteItem":
                client.Inventory.RemoveItem(new LLUUID(POST["Item"]));
                break;

            case "DeleteFolder":
                client.Inventory.RemoveFolder(new LLUUID(POST["Folder"]));
                break;

            case "DeleteMultiple":
            {
                string[]      items    = POST["Items"].Split(',');
                List <LLUUID> itemlist = new List <LLUUID>();
                for (int i = 0; i < items.Length; ++i)
                {
                    itemlist.Add(new LLUUID(items[i]));
                }
                string[]      folders    = POST["Folders"].Split(',');
                List <LLUUID> folderlist = new List <LLUUID>();
                for (int i = 0; i < items.Length; ++i)
                {
                    folderlist.Add(new LLUUID(folders[i]));
                }
                client.Inventory.Remove(itemlist, folderlist);
            }
            break;

            case "GiveInventory":
            {
                client.Inventory.GiveItem(new LLUUID(POST["ItemID"]), POST["ItemName"], (AssetType)int.Parse(POST["AssetType"]), new LLUUID(POST["Recipient"]), true);
            }
            break;

            case "UpdateItem":
            {
                InventoryItem item = client.Inventory.FetchItem(new LLUUID(POST["ItemID"]), new LLUUID(POST["OwnerID"]), 1000);
                if (POST.ContainsKey("Name"))
                {
                    item.Name = POST["Name"];
                }
                if (POST.ContainsKey("Description"))
                {
                    item.Description = POST["Description"];
                }
                if (POST.ContainsKey("NextOwnerMask"))
                {
                    item.Permissions.NextOwnerMask = (PermissionMask)uint.Parse(POST["NextOwnerMask"]);
                }
                if (POST.ContainsKey("SalePrice"))
                {
                    item.SalePrice = int.Parse(POST["SalePrice"]);
                }
                if (POST.ContainsKey("SaleType"))
                {
                    item.SaleType = (SaleType)int.Parse(POST["SaleType"]);                                       // This should be byte.Parse, but this upsets mono's compiler (CS1002)
                }
                client.Inventory.RequestUpdateItem(item);
            }
            break;

            case "UpdateFolder":
            {
                UpdateInventoryFolderPacket packet = new UpdateInventoryFolderPacket();
                packet.AgentData.AgentID      = client.Self.AgentID;
                packet.AgentData.SessionID    = client.Self.SessionID;
                packet.FolderData             = new UpdateInventoryFolderPacket.FolderDataBlock[1];
                packet.FolderData[0]          = new UpdateInventoryFolderPacket.FolderDataBlock();
                packet.FolderData[0].FolderID = new LLUUID(POST["FolderID"]);
                packet.FolderData[0].ParentID = new LLUUID(POST["ParentID"]);
                packet.FolderData[0].Type     = sbyte.Parse(POST["Type"]);
                packet.FolderData[0].Name     = Helpers.StringToField(POST["Name"]);
                client.Network.SendPacket((Packet)packet);
            }
            break;

            case "FetchItem":
                client.Inventory.FetchItem(new LLUUID(POST["Item"]), new LLUUID(POST["Owner"]), 5000);
                break;

            case "ReRotate":
                user.Rotation = -Math.PI;
                break;

            case "StartGroupIM":
                AjaxLife.Debug("SendMessage", "RequestJoinGroupChat(" + POST["Group"] + ")");
                client.Self.RequestJoinGroupChat(new LLUUID(POST["Group"]));
                break;

            case "GroupInstantMessage":
                client.Self.InstantMessageGroup(new LLUUID(POST["Group"]), POST["Message"]);
                break;

            case "RequestGroupProfile":
                client.Groups.RequestGroupProfile(new LLUUID(POST["Group"]));
                break;

            case "RequestGroupMembers":
                client.Groups.RequestGroupMembers(new LLUUID(POST["Group"]));
                break;

            case "RequestGroupName":
                client.Groups.RequestGroupName(new LLUUID(POST["ID"]));
                break;

            case "JoinGroup":
                client.Groups.RequestJoinGroup(new LLUUID(POST["Group"]));
                break;

            case "LeaveGroup":
                client.Groups.LeaveGroup(new LLUUID(POST["Group"]));
                break;

            case "RequestCurrentGroups":
                client.Groups.RequestCurrentGroups();
                break;

            case "GetParcelID":
                textwriter.Write("{LocalID: " + client.Parcels.GetParcelLocalID(client.Network.CurrentSim, new LLVector3(float.Parse(POST["X"]), float.Parse(POST["Y"]), float.Parse(POST["Z"]))) + "}");
                break;

            case "RequestParcelProperties":
                client.Parcels.PropertiesRequest(client.Network.CurrentSim, int.Parse(POST["LocalID"]), int.Parse(POST["SequenceID"]));
                break;
            }
            textwriter.Flush();
        }
Пример #7
0
        // Someone wants connect.kat.
        public void OnFileRequested(HttpRequest request, IDirectory directory)
        {
            request.Response.ResponseContent = new MemoryStream();
            StreamWriter textWriter = new StreamWriter(request.Response.ResponseContent);

            try
            {
                // Grab various bits of data from the User object.
                // If we can't do that, complain.
                // While we're at it, decode the post data.
                User         user;
                SecondLife   client;
                StreamReader reader  = new StreamReader(request.PostData);
                string       qstring = reader.ReadToEnd();
                reader.Dispose();
                Dictionary <string, string> POST = AjaxLife.PostDecode(qstring);
                Guid key = new Guid(POST["session"]);
                // The session doesn't exist. Get upset.
                if (!this.users.ContainsKey(key))
                {
                    this.invalidSessionID(key, textWriter);
                    return;
                }
                lock (this.users)
                {
                    user = users[key];
                }
                user.LastRequest = DateTime.Now;
                client           = user.GetClient();

                string first = "";
                string last  = "";
                string pass  = "";
                // Decrypt the incoming login data
                string decrypted = StringHelper.ASCIIBytesToString(AjaxLife.RSA.Decrypt(StringHelper.HexStringToBytes(POST["logindata"])));
                // Split it into its component parts.
                string[] data = decrypted.Split('\\');
                // Get upset if the challenge was incorrect.
                if (data[0] == null || data[0] != user.Challenge)
                {
                    throw new Exception("Invalid request.");
                }
                // Decode the login data.
                first          = StringHelper.ASCIIBytesToString(StringHelper.FromBase64(data[1]));
                last           = StringHelper.ASCIIBytesToString(StringHelper.FromBase64(data[2]));
                pass           = data[3];
                user.Signature = data[4];
                // Check if they're banned first.
                if (AjaxLife.BannedUsers.IsBanned(first, last))
                {
                    textWriter.WriteLine("{success: false, message: \"You have been banned from AjaxLife by the administrator.\"}");
                    textWriter.Flush();
                    return;
                }
                LoginParams login = client.Network.DefaultLoginParams(first, last, pass, "AjaxLife", "Katharine Berry <*****@*****.**>");
                login.Platform = "web";
                login.Channel  = "AjaxLife";
                login.MAC      = AjaxLife.MAC_ADDRESS;
                login.id0      = AjaxLife.ID0;
                login.Start    = (POST["location"] != "arbitrary") ? POST["location"] : NetworkManager.StartLocation(POST["sim"], 128, 128, 20);
                // Pick the correct loginuri.
                lock (AjaxLife.LOGIN_SERVERS) login.URI = AjaxLife.LOGIN_SERVERS[POST["grid"]];
                client.Settings.LOGIN_SERVER = login.URI;
                user.LindenGrid = POST["grid"].EndsWith("(Linden Lab)");
                Console.WriteLine(login.FirstName + " " + login.LastName + " is attempting to log into " + POST["grid"] + " (" + login.URI + ")");
                if (client.Network.Login(login))
                {
                    // Ensure that the challenge isn't matched by another request with the same SID.
                    // We don't do this until after successful login because otherwise a second attempt will always fail.
                    user.Challenge = null;
                    AvatarTracker avatars = new AvatarTracker(client);
                    Events        events  = new Events(user);
                    user.Events  = events;
                    user.Avatars = avatars;
                    // Register event handlers
                    this.RegisterCallbacks(user);
                    // De-ruth.
                    client.Appearance.SetPreviousAppearance(false);
                    // Pythagoras says that 181.0193m is the optimal view distance to see the whole sim.
                    client.Self.Movement.Camera.Far = 181.0193f;

                    // This doesn't seem to work.
                    // client.Self.Movement.Camera.SetPositionOrientation(new LLVector3(128, 128, 0), 0, 0, 0);

                    // Everything's happy. Log the requested message list, if any.
                    if (POST.ContainsKey("events"))
                    {
                        user.ParseRequestedEvents(POST["events"]);
                    }

                    // If we got this far, it worked. Announce this.
                    textWriter.WriteLine("{\"success\": 1}");
                }
                else
                {
                    // Return whatever errors may have transpired.
                    textWriter.WriteLine("{success: false, message: " + AjaxLife.StringToJSON(client.Network.LoginMessage) + "}");
                }
            }
            catch (Exception exception)
            {
                request.Response.ContentType = "text/plain";
                textWriter.WriteLine(exception.Message);
            }
            textWriter.Flush();
        }