Ejemplo n.º 1
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID agentKey;

            try
            {
                bool check = false;
                if (Parameters.ContainsKey("key"))
                {
                    check =
                        UUID
                        .TryParse(Parameters["key"].ToString().Replace("_", " "),
                                  out agentKey);
                }
                else
                {
                    return("<error>arguments</error>");
                }
                if (check)
                {
                    bool response = getOnline(b, agentKey);
                    return($"<online>{response.ToString()}</online>");
                }
                else
                {
                    return("<error>unknown</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return("<error>parsekey</error>");
            }
        }
Ejemplo n.º 2
0
        }         // end ParseArguments

        /// <summary>
        /// Register all RestPlugins to the RestBot static plugin dictionary
        /// </summary>
        /// <param name="assembly">Given assembly to search for</param>
        static void RegisterAllCommands(Assembly assembly)
        {
            foreach (Type t in assembly.GetTypes())
            {
                try
                {
                    if (t.IsSubclassOf(typeof(RestPlugin)))
                    {
                        ConstructorInfo?info = t.GetConstructor(Type.EmptyTypes); // ask for parameter-less constructor for this class, if it exists (gwyneth 20220425)
                        if (info == null)
                        {
                            // Not a serious warning, some plugins might be incorrectly configured but still work well
                            DebugUtilities.WriteWarning($"Couldn't get constructor without parameters for plugin {t.GetType().Name}!");
                        }
                        else
                        {
                            RestPlugin plugin = (RestPlugin)info.Invoke(new object[0]);
                            RestBot.AddPlugin(plugin);
                        }
                    }
                }
                catch (Exception e)
                {
                    DebugUtilities.WriteError(e.Message);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Get rid of a specific session.
        /// </summary>
        /// <remarks>Also calls the garbage collector after a successful bot logout (gwyneth 20220411)</remarks>
        /// <param name="key">Session UUID</param>
        public static void DisposeSession(UUID key)
        {
            DebugUtilities.WriteDebug($"Disposing of session {key.ToString()}");
            if (Sessions != null)
            {
                if (!Sessions.ContainsKey(key))
                {
                    return;
                }
                Session s = Sessions[key];
                if (s != null && s.Bot != null)                 // should never happen, we checked before
                {
                    if (s.StatusCallback != null)
                    {
                        s.Bot.OnBotStatus -= s.StatusCallback;
                    }
                    s.Bot.Client.Network.Logout();

                    // Run garbage collector every time a bot logs out.
                    CollectGarbage();
                }
                else
                {
                    DebugUtilities.WriteError($"Weird error in logging out session {key.ToString()} - it was on the Sessions dictionary, but strangely without a 'bot attached");
                }
                Sessions.Remove(key);
            }
            else
            {
                DebugUtilities.WriteError($"DisposeSession called on {key.ToString()}, but we have no Sessions dictionary!");
            }
        } // end DisposeSession()
Ejemplo n.º 4
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID folderID;

            DebugUtilities.WriteDebug("Entering folder key parser");
            try
            {
                bool check = false;
                if (Parameters.ContainsKey("key"))
                {
                    DebugUtilities.WriteDebug("Attempting to parse from POST");
                    check =
                        UUID
                        .TryParse(Parameters["key"].ToString().Replace("_", " "),
                                  out folderID);
                    DebugUtilities.WriteDebug("Succesfully parsed POST");
                }
                else
                {
                    folderID = UUID.Zero;                     // start with root folder
                    check    = true;
                }

                if (
                    check                     // means that we have a correctly parsed key OR no key
                    )
                //  which is fine too (attempts root folder)
                {
                    DebugUtilities.WriteDebug("Entering loop");

                    Manager   = b.Client.Inventory;
                    Inventory = Manager.Store;

                    StringBuilder response = new StringBuilder();

                    InventoryFolder startFolder = new InventoryFolder(folderID);

                    if (folderID == UUID.Zero)
                    {
                        startFolder = Inventory.RootFolder;
                    }

                    PrintFolder(b, startFolder, response);
                    DebugUtilities.WriteDebug("Complete");

                    return($"<inventory>{response}</inventory>");
                }
                else
                {
                    return($"<error>{MethodName}: parsekey</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Handler event for this plugin.
        /// </summary>
        /// <param name="b">A currently active RestBot</param>
        /// <param name="Parameters">A dictionary containing the group UUID and the message to send to group IM</param>
        /// <returns>XML with information on the sent group IM message, if successful;
        /// XML error otherwise</returns>
        public override string Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID   groupUUID;
            string message;

            try
            {
                bool check = false;
                if (Parameters.ContainsKey("key"))
                {
                    check = UUID.TryParse(Parameters["key"].ToString().Replace("_", " "), out groupUUID);
                }
                else
                {
                    return("<error>arguments: no key</error>");
                }
                if (check)
                {
                    if (Parameters.ContainsKey("message"))
                    {
                        message = Parameters["message"].ToString().Replace("%20", " ").Replace("+", " ");
                    }
                    else
                    {
                        return("<error>arguments: no message</error>");
                    }
                }
                else
                {
                    return("<error>parsekey</error>");
                }

                message = message.TrimEnd();
                if (message.Length > 1023)
                {
                    message = message.Remove(1023);
                    DebugUtilities.WriteDebug(session + " " + MethodName + " Message truncated at 1024 characters");
                }

                string response = sendIMGroup(b, groupUUID, message);

                if (string.IsNullOrEmpty(response))
                {
                    return("<error>group message not sent, or answer was empty</error>");
                }

                return("<message>" + response.Trim() + "</message>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return("<error>loads of errors</error>");
            }
        }
Ejemplo n.º 6
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            uint
                regionX,
                regionY;

            Utils
            .LongToUInts(b.Client.Network.CurrentSim.Handle,
                         out regionX,
                         out regionY);

            try
            {
                string target = String.Empty;

                if (Parameters.ContainsKey("target"))
                {
                    target =
                        Parameters["target"]
                        .ToString()
                        .Replace("%20", " ")
                        .Replace("+", " ");
                }
                else
                {
                    return($"<error>{MethodName}: missing argument for target</error>");
                }

                if (target.Length == 0 || target == "off")
                {
                    Active        = false;
                    targetLocalID = 0;
                    b.Client.Self.AutoPilotCancel();
                    return($"<{MethodName}>off</{MethodName}>");
                }
                else
                {
                    if (Follow(target))
                    {
                        return($"<{MethodName}>on</{MethodName}>");
                    }
                    else
                    {
                        return($"<error>cannot follow {target}</error>");
                    }
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 7
0
 Process(RestBot b, Dictionary <string, string> Parameters)
 {
     try
     {
         return($"<{MethodName}><CurrentSim>{b.Client.Network.CurrentSim.ToString()}</CurrentSim><Position>{b.Client.Self.SimPosition.X},{b.Client.Self.SimPosition.Y},{b.Client.Self.SimPosition.Z}</Position></{MethodName}>");
     }
     catch (Exception e)
     {
         DebugUtilities.WriteError(e.Message);
         return($"<error>{MethodName}: {e.Message}</error>");
     }
 }
Ejemplo n.º 8
0
 Process(RestBot b, Dictionary <string, string> Parameters)
 {
     try
     {
         b.Client.Self.Stand();
         return($"<{MethodName}>standing</{MethodName}>");
     }
     catch (Exception e)
     {
         DebugUtilities.WriteError(e.Message);
         return($"<error>{MethodName}: {e.Message}</error>");
     }
 }
Ejemplo n.º 9
0
        public override string Process(RestBot b, Dictionary <string, string> Parameters)
        {
            try
            {
                string type   = String.Empty;
                bool   check  = true;
                float  radius = 0.0f;

                if (Parameters.ContainsKey("type"))
                {
                    type = Parameters["type"].ToString().Replace("+", " ");
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("radius"))
                {
                    check &= float.TryParse(Parameters["radius"], out radius);
                }
                else
                {
                    check = false;
                }

                if (!check)
                {
                    return("<error>parameters have to be type, radius</error>");
                }

                // *** get current location ***
                Vector3 location = b.Client.Self.SimPosition;

                Primitive found = b.Client.Network.CurrentSim.ObjectsPrimitives.Find(
                    delegate(Primitive prim) {
                    return(prim.Properties.Name == type);
                });


                return($"<nearby_prim><pos>{found.Position.X},{found.Position.Y},{found.Position.Z}</pos></nearby_prim>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 10
0
 Process(RestBot b, Dictionary <string, string> Parameters)
 {
     try
     {
         return(String
                .Format("<position>{0},{1},{2}</position>",
                        b.Client.Self.SimPosition.X,
                        b.Client.Self.SimPosition.Y,
                        b.Client.Self.SimPosition.Z));
     }
     catch (Exception e)
     {
         DebugUtilities.WriteError(e.Message);
         return($"<error>{e.Message}</error>");
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Handler event for this plugin.
        /// </summary>
        /// <param name="b">A currently active RestBot</param>
        /// <param name="Parameters">A dictionary containing the group name, or UUID</param>
        /// <returns>XML containing the group name that was activated, if successful; XML error otherwise.</returns>
        public override string Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID   groupUUID;
            string groupName;

            DebugUtilities.WriteDebug("Entering group key parser");
            try
            {
                if (Parameters.ContainsKey("name"))
                {
                    groupName = Parameters["name"].ToString().Replace("%20", " ").Replace("+", " ");
                }
                else
                {
                    return($"<error>{MethodName}: arguments</error>");
                }
                DebugUtilities.WriteDebug("Activating group");

                groupUUID = GroupName2UUID(b, groupName);
                if (UUID.Zero != groupUUID)
                {
                    string response = activateGroup(b, groupUUID);
                    DebugUtilities.WriteDebug("Complete");
                    if (response != null)
                    {
                        return($"<active>{response.Trim()}</active>");
                    }
                    else
                    {
                        return($"<error>{MethodName}: group could not be activated</error>");
                    }
                }
                else
                {
                    DebugUtilities.WriteDebug($"Error: group {groupName} doesn't exist");
                    return($"<error>{MethodName}: group name '{groupName}' doesn't exist.</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: parsekey</error>");
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Handler event for this plugin.
        /// </summary>
        /// <param name="b">A currently active RestBot</param>
        /// <param name="Parameters">A dictionary containing the group UUID</param>
        /// <returns>XML with information on the activated group key if successful,
        /// XML error otherwise</returns>
        public override string Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID groupUUID;

            DebugUtilities.WriteDebug("Entering group key parser");
            try
            {
                bool check = false;
                if (Parameters.ContainsKey("key"))
                {
                    DebugUtilities.WriteDebug("Attempting to parse from POST");
                    check = UUID.TryParse(Parameters["key"].ToString().Replace("_", " "), out groupUUID);
                    DebugUtilities.WriteDebug("Succesfully parsed POST");
                }
                else
                {
                    return($"<error>{MethodName}: invalid arguments</error>");
                }
                if (check)
                {
                    DebugUtilities.WriteDebug("Activating group");
                    string?response = activateGroup(b, groupUUID);
                    DebugUtilities.WriteDebug("Complete");
                    if (response != null)
                    {
                        return($"<active>{response.Trim()}</active>");
                    }
                    else
                    {
                        return($"<error>{MethodName}: group could not be activated</error>");
                    }
                }
                else
                {
                    return($"<error>{MethodName}: parsekey</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: parsekey</error>");
            }
        }
Ejemplo n.º 13
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            /// <summary>UUID for the prim/object that we intend the bot to touch</summary>
            UUID touchTargetID = UUID.Zero;

            DebugUtilities.WriteDebug($"{b.sessionid} {MethodName} - Searching for prim to touch");
            try
            {
                bool check = false;
                if (Parameters.ContainsKey("prim"))
                {
                    check =
                        UUID
                        .TryParse(Parameters["prim"].ToString().Replace("_", " "),
                                  out touchTargetID);
                }

                if (!check)
                {
                    return("<error>prim to touch not specified</error>");
                }

                // If we get to this point means that we have a correctly parsed key for the target prim
                DebugUtilities.WriteDebug($"{b.sessionid} {MethodName} - Trying to touch {touchTargetID.ToString()}...");

                Primitive targetPrim = b.Client.Network.CurrentSim.ObjectsPrimitives.Find(
                    prim => prim.ID == touchTargetID
                    );

                if (targetPrim != null)
                {
                    b.Client.Self.Touch(targetPrim.LocalID);
                    return($"<{MethodName}>touching {targetPrim.ID.ToString()} ({targetPrim.LocalID})</{MethodName}>");
                }

                return($"<error>no prim with UUID {touchTargetID} found</error>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{e.Message}</error>");
            }
        }
Ejemplo n.º 14
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID agentKey;

            try
            {
                bool check = false;
                if (Parameters.ContainsKey("key"))
                {
                    check =
                        UUID
                        .TryParse(Parameters["key"].ToString().Replace("_", " "),
                                  out agentKey);
                }
                else
                {
                    return("<error>arguments</error>");
                }
                if (check)
                {
                    string?response = getGroups(b, agentKey);                      // string can be null
                    if (response == null)
                    {
                        return("<error>not found</error>");
                    }
                    else
                    {
                        return(response);
                    }
                }
                else
                {
                    return("<error>unknown</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return("<error>parsekey</error>");
            }
        }
Ejemplo n.º 15
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID agentKey;

            DebugUtilities.WriteDebug("Entering avatarname parser");
            try
            {
                bool check = false;
                if (Parameters.ContainsKey("key"))
                {
                    DebugUtilities.WriteDebug("Attempting to parse from POST");
                    check =
                        UUID
                        .TryParse(Parameters["key"].ToString().Replace("_", " "),
                                  out agentKey);
                    DebugUtilities.WriteDebug("Succesfully parsed POST");
                }
                else
                {
                    return("<error>arguments</error>");
                }
                if (check)
                {
                    DebugUtilities.WriteDebug("Parsing name");
                    string response = getName(b, agentKey);
                    DebugUtilities.WriteDebug("Parsed name");
                    DebugUtilities.WriteDebug("Complete");
                    return($"<name>{response.Trim()}</name>");
                }
                else
                {
                    return("<error>parsekey</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return("<error>parsekey</error>");
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Process a request (assuming it exists)
        /// </summary>
        /// <param name="headers">Request headers (including path, etc.)</param>
        /// <param name="body">Request body (will usually have all parameters from POST)</param>
        public static string DoProcessing(RequestHeaders headers, string body)
        {
            // Abort if we don't even have a valid configuration; too many things depend on it... (gwyneth 20220213)
            if (Program.config == null)
            {
                return("<error>No valid configuration loaded, aborting</error>");
            }

            //Setup variables
            DebugUtilities.WriteInfo($"New request - {headers.RequestLine.Path}");
            //Split the URL
            string[] parts = headers.RequestLine.Path.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length < 1)
            {
                return("<error>invalidmethod</error>");
            }
            string Method = parts[0];
            /// <summary>Process the request params from POST, URL</summary>
            Dictionary <string, string> Parameters = RestBot.HandleDataFromRequest(headers, body);
            string debugparams = String.Empty;
            string debugparts  = String.Empty;

            foreach (KeyValuePair <string, string> kvp in Parameters)
            {
                debugparams = debugparams + "[" + kvp.Key + "=" + kvp.Value + "] ";
            }
            DebugUtilities.WriteDebug($"Parameters (total: {Parameters.Count()}) - '{debugparams}'");
            foreach (string s in parts)
            {
                debugparts = debugparts + "[ " + s + " ]";
            }
            DebugUtilities.WriteDebug($"Parts (total: {parts.Count()}) - '{debugparts}'");
            if (Method == "establish_session")
            {
                DebugUtilities.WriteDebug("We have an `establish_session` method.");
                // Alright, we're going to try to establish a session
                // Start location is optional (gwyneth 20220421)
                if (parts.Length >= 2 && parts[1] == Program.config.security.serverPass &&
                    Parameters.ContainsKey("first") && Parameters.ContainsKey("last") && Parameters.ContainsKey("pass"))
                {
                    DebugUtilities.WriteDebug("Found required parameters for establish_session");
                    if (Sessions != null)
                    {
                        foreach (KeyValuePair <UUID, Session> ss in Sessions)
                        {
                            if (ss.Value != null && ss.Value.Bot != null)
                            {
                                DebugUtilities.WriteSpecial($"Avatar check: [{ss.Value.Bot.First.ToLower()}/{ss.Value.Bot.Last.ToLower()}] = [{Parameters["first"].ToLower()}/{Parameters["last"].ToLower()}]");
                                if (Parameters["first"].ToLower() == ss.Value.Bot.First.ToLower() &&
                                    Parameters["last"].ToLower() == ss.Value.Bot.Last.ToLower()
                                    )
                                {
                                    DebugUtilities.WriteWarning($"Already running avatar {Parameters["first"]} {Parameters["last"]}");

                                    /// <value>Temporary string to construct a full response, if possible; if not, we catch the
                                    /// exception and return a much shorter version</value>
                                    /// <remarks>This is a hack. The issue is that we're probably acessing nullable
                                    /// elements without checking. (gwyneth 20220428)</remarks>
                                    string returnString = "";

                                    try
                                    {
                                        // Attempt to get a
                                        returnString = $@"<existing_session>true</existing_session>
	<session_id>{ss.Key.ToString()}</session_id>
	<key>{ss.Value.Bot.Client.Self.AgentID.ToString()}</key>
	<name>{ss.Value.Bot.Client.Self.FirstName} {ss.Value.Bot.Client.Self.LastName}</name>
	<FirstName>{ss.Value.Bot.Client.Self.FirstName}</FirstName>
	<LastName>{ss.Value.Bot.Client.Self.LastName}</LastName>
	<status>{ss.Value.Bot.myStatus.ToString()}</status>
	<uptime>{ss.Value.Bot.getUptimeISO8601()}</uptime>
	<start>{ss.Value.Bot.Start}</start>
	<CurrentSim>{ss.Value.Bot.Client.Network.CurrentSim.ToString()}</CurrentSim>
	<Position>{ss.Value.Bot.Client.Self.SimPosition.X},{ss.Value.Bot.Client.Self.SimPosition.Y},{ss.Value.Bot.Client.Self.SimPosition.Z}</Position>
	<Rotation>{ss.Value.Bot.Client.Self.SimRotation.X},{ss.Value.Bot.Client.Self.SimRotation.Y},{ss.Value.Bot.Client.Self.SimRotation.Z},{ss.Value.Bot.Client.Self.SimRotation.W}</Rotation>
";
                                    }
                                    catch (Exception e)
                                    {
                                        DebugUtilities.WriteError($"Could not generate full response, error was: '{e.Message}'; falling back to the simple, minimalistic answer");
                                        returnString = $"<existing_session>true</existing_session><session_id>{ss.Key.ToString()}</session_id>";
                                    }
                                    return(returnString);
                                }
                            }
                        }
                    }
                    else
                    {
                        DebugUtilities.WriteDebug("No available sessions...");
                    }
                    UUID    id = UUID.Random();
                    Session s  = new Session();
                    s.ID           = id;
                    s.Hostname     = headers.Hostname;
                    s.LastAccessed = DateTime.Now;
                    // Needs the $1$ for the md5 on the login for LibreMetaverse
                    if (!Parameters["pass"].StartsWith("$1$"))
                    {
                        Parameters["pass"] = "******" + Parameters["pass"];
                    }
                    // check if user has provided us with a starting location (default is to use the last location)
                    // (gwyneth 20220420)
                    string gridLocation = Parameters.ContainsKey("start") ? Parameters["start"] : "last";
                    s.Bot = new RestBot(s.ID, Parameters["first"], Parameters["last"], Parameters["pass"], gridLocation);

                    if (Sessions != null)
                    {
                        lock (Sessions)
                        {
                            Sessions.Add(id, s);
                        }
                    }
                    else
                    {
                        // no "else", we have no dictionary
                        DebugUtilities.WriteWarning("Possible issue: we have null Sessions when adding, which shouldn't happen");
                    }
                    RestBot.LoginReply reply = s.Bot.Login();
                    if (reply.wasFatal)
                    {
                        if (Sessions != null)
                        {
                            lock (Sessions)
                            {
                                if (Sessions.ContainsKey(id))
                                {
                                    Sessions.Remove(id);
                                }
                            }
                        }
                        else
                        {
                            // no "else", we have no dictionary
                            DebugUtilities.WriteWarning("Possible issue: we have null Sessions when removing, which shouldn't happen");
                        }
                    }
                    return(reply.xmlReply);
                }
                else
                {
                    String result = String.Empty;
                    if (parts.Length < 2)
                    {
                        result = "Missing a part.";
                    }
                    if (!Parameters.ContainsKey("first"))
                    {
                        result = result + " Missing 'first' arg.";
                    }
                    if (!Parameters.ContainsKey("last"))
                    {
                        result = result + " Missing 'last' arg.";
                    }
                    if (!Parameters.ContainsKey("pass"))
                    {
                        result = result + " Missing 'pass' arg.";
                    }
                    return($"<error>arguments: {result}</error>");
                }
            }
            // Note: formerly undocumented functionality!! (gwyneth 20220414)
            else if (Method == "server_quit")
            {
                if (parts.Length < 2)
                {
                    return($"<error>{Method}: missing 'pass' arg.</error>");
                }
                if (parts[1] == Program.config.security.serverPass)
                {
                    if (Sessions != null)
                    {
                        foreach (KeyValuePair <UUID, Session> s in Sessions)
                        {
                            lock (Sessions) DisposeSession(s.Key);
                        }
                        StillRunning = false;
                        // note: a caveat of this undocumented method is that it requires a _new_
                        // incoming request to actually kill the server... could be a ping, though. (gwyneth 20220414)
                        return("<status>success - all bot sessions were logged out and a request was made for queued shutdown</status>");
                    }
                    else
                    {
                        // it's fine if there are no sessions (gwyneth 20220414)
                        return("<status>success - no sessions were active</status>");
                    }
                }
                else
                {
                    // wrong password sent! (gwyneth 20220414)
                    return($"<error>{Method}: server authentication failure</error>");
                }
            }
            else if (Method == "ping")
            {
                if (parts.Length < 2)
                {
                    return($"<error>{Method}: missing 'pass' arg.</error>");
                }
                if (parts[1] == Program.config.security.serverPass)
                {
                    return($"<{Method}>I'm alive!</{Method}>");
                }
                else
                {
                    // wrong password sent! (gwyneth 20220414)
                    return($"<error>{Method}: server authentication failure</error>");
                }
            }
            else if (Method == "session_list")
            {
                if (parts.Length < 2)
                {
                    return("<error>missing 'pass' arg.</error>");
                }
                if (parts[1] == Program.config.security.serverPass)
                {
                    bool check = false;
                    if (Program.Sessions.Count != 0)                     // no sessions? that's fine, no need to abort
                    {
                        check = true;
                    }

                    string response = $"<{Method}>";
                    if (check)                          // optimisation: if empty, no need to run the foreach (gwyneth 20220424)
                    {
                        foreach (KeyValuePair <OpenMetaverse.UUID, RESTBot.Session> kvp in Program.Sessions)
                        {
                            if (kvp.Value.Bot != null && kvp.Value.Bot.Client != null && kvp.Value.Bot.Client.Self != null && kvp.Value.Bot.Client.Network != null)
                            {
                                response += $@"
	<session>
		<session_id>{kvp.Key.ToString()}</session_id>
		<key>{kvp.Value.Bot.Client.Self.AgentID.ToString()}</key>
		<name>{kvp.Value.Bot.Client.Self.FirstName} {kvp.Value.Bot.Client.Self.LastName}</name>
		<FirstName>{kvp.Value.Bot.Client.Self.FirstName}</FirstName>
		<LastName>{kvp.Value.Bot.Client.Self.LastName}</LastName>
		<status>{kvp.Value.Bot.myStatus.ToString()}</status>
		<uptime>{kvp.Value.Bot.getUptimeISO8601()}</uptime>
		<start>{kvp.Value.Bot.Start}</start>
		<CurrentSim>{kvp.Value.Bot.Client.Network.CurrentSim.ToString()}</CurrentSim>
		<Position>{kvp.Value.Bot.Client.Self.SimPosition.X},{kvp.Value.Bot.Client.Self.SimPosition.Y},{kvp.Value.Bot.Client.Self.SimPosition.Z}</Position>
		<Rotation>{kvp.Value.Bot.Client.Self.SimRotation.X},{kvp.Value.Bot.Client.Self.SimRotation.Y},{kvp.Value.Bot.Client.Self.SimRotation.Z},{kvp.Value.Bot.Client.Self.SimRotation.W}</Rotation>
	</session>"    ;
                            }
                            else
                            {
                                // Somehow, we have a session ID that has no bot assigned;
                                // this should never be the case, but... (gwyneth 20220426)
                                response += $"<session><session_id>{kvp.Key.ToString()}</session_id><key>{UUID.Zero.ToString()}</key></session>";
                            }
                        }
                    }
                    else
                    {
                        response += "no sessions";
                    }
                    response += $"</{Method}>";
                    return(response);
                }
                else
                {
                    // wrong password sent! (gwyneth 20220414)
                    return($"<error>{Method}: server authentication failure</error>");
                }
            }
            else if (Method == "stats")
            {
                if (parts.Length < 2)
                {
                    return($"<error>{Method}: missing 'pass' arg.</error>");
                }
                if (parts[1] == Program.config.security.serverPass)
                {
                    string response = "<stats><bots>" + ((Sessions != null) ? Sessions.Count.ToString() : "0") + "</bots>"
                                      + "<uptime>" + (DateTime.Now - uptime) + "</uptime></stats>";
                    return(response);
                }
                else
                {
                    return($"<error>{Method}: server authentication failure</error>");
                }
            }

            //Only a method? pssh.
            if (parts.Length == 1)
            {
                return("<error>no session key found</error>");
            }

            UUID sess = new UUID();

            try
            {
                sess = new UUID(parts[1]);
            }
            catch (FormatException)
            {
                return("<error>cannot parse the session key</error>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
            }

            //Session checking
            if (!ValidSession(sess, headers.Hostname))
            {
                return("<error>invalidsession</error>");
            }

            //YEY PROCESSING
            RestBot?r = null;

            if (Sessions != null)
            {
                r = Sessions[sess].Bot;
            }

            if (r == null)
            {
                return($"<error>no RestBot found for session {sess.ToString()}</error>");
            }
            //Last accessed for plugins
            if (Sessions != null)
            {
                Sessions[sess].LastAccessed = DateTime.Now;
            }
            //Pre-error checking
            if (r.myStatus != RestBot.Status.Connected) //Still logging in?
            {
                return($"<error>{r.myStatus.ToString()}</error>");
            }
            else if (!r.Client.Network.Connected) //Disconnected?
            {
                return("<error>clientdisconnected</error>");
            }
            else if (Method == "exit")
            {
                DisposeSession(sess);
                return("<disposed>true</disposed>");
            }
            else if (Method == "stats")
            {
                string response = "<bots>" + ((Sessions != null) ? Sessions.Count.ToString() : "NaN") + "</bots>";
                response += "<uptime>" + (DateTime.Now - uptime) + "</uptime>";
                return(response);
            }

            return(r.DoProcessing(Parameters, parts));
        } // end DoProcessing
Ejemplo n.º 17
0
        /// <summary>
        /// Handler event for this plugin.
        /// </summary>
        /// <param name="b">A currently active RestBot</param>
        /// <param name="Parameters">A dictionary containing the message </param>
        /// <returns></returns>
        public override string Process(RestBot b, Dictionary <string, string> Parameters)
        {
            string      message;
            string      subject;
            UUID        groupUUID      = UUID.Zero;
            UUID        attachmentUUID = UUID.Zero;
            GroupNotice notice;

            try
            {
                if (Parameters.ContainsKey("subject"))
                {
                    subject = Parameters["subject"].ToString().Replace("%20", " ").Replace("+", " ");
                }
                else
                {
                    return("<error>No notice subject</error>");
                }

                if (Parameters.ContainsKey("message"))
                {
                    message = Parameters["message"].ToString().Replace("%20", " ").Replace("+", " ");
                }
                else
                {
                    return("<error>No notice message</error>");
                }

                if (Parameters.ContainsKey("group"))
                {
                    if (!UUID.TryParse(Parameters["group"].ToString().Replace("_", " "), out groupUUID))
                    {
                        return("<error>parsekey group</error>");
                    }
                }
                else
                {
                    return("<error>arguments: no group key</error>");
                }

                if (Parameters.ContainsKey("attachment"))
                {
                    if (!UUID.TryParse(Parameters["attachment"].ToString().Replace("_", " "), out attachmentUUID))
                    {
                        return("<error>parsekey attachment</error>");
                    }
                }
                else
                {
                    // just a warning, attachment can be empty
                    DebugUtilities.WriteWarning(session + " " + MethodName + " Notice has no attachment (no problem)");
                }

                DebugUtilities.WriteDebug(session + " " + MethodName + " Attempting to create a notice");

                /* This doesn't work as it should!
                 * if (!b.Client.Inventory.Store.Contains(attachmentUUID))
                 * {
                 *      DebugUtilities.WriteWarning(session + " " + MethodName + " Item UUID " + attachmentUUID.ToString() + " not found on inventory (are you using an Asset UUID by mistake?)");
                 *      attachmentUUID = UUID.Zero;
                 * }
                 */

                notice = new GroupNotice();

                notice.Subject      = subject;
                notice.Message      = message;
                notice.AttachmentID = attachmentUUID;                 // this is the inventory UUID, not the asset UUID
                notice.OwnerID      = b.Client.Self.AgentID;

                b.Client.Groups.SendGroupNotice(groupUUID, notice);

                DebugUtilities.WriteDebug($"{session} {MethodName} Sent Notice from avatar {notice.OwnerID.ToString()} to group: {groupUUID.ToString()} subject: '{notice.Subject.ToString()}' message: '{notice.Message.ToString()}' Optional attachment: {notice.AttachmentID.ToString()} Serialisation: {Utils.BytesToString(notice.SerializeAttachment())}");

                return("<notice>sent</notice>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return("<error>loads of errors</error>");
            }
        }
Ejemplo n.º 18
0
        public override string Process(RestBot b, Dictionary <string, string> Parameters)
        {
            try
            {
                string type   = String.Empty;
                bool   check  = true;
                float  radius = 0.0f;

                if (Parameters.ContainsKey("type"))
                {
                    type = Parameters["type"].ToString().Replace("+", " ");
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("radius"))
                {
                    check &= float.TryParse(Parameters["radius"], out radius);
                }
                else
                {
                    check = false;
                }

                if (!check)
                {
                    return("<error>parameters have to be type, radius</error>");
                }

                // *** get current location ***
                Vector3 location = b.Client.Self.SimPosition;

                // *** find all objects in radius ***
                List <Primitive> prims = b.Client.Network.CurrentSim.ObjectsPrimitives.FindAll(
                    delegate(Primitive prim)
                {
                    Vector3 pos = prim.Position;
                    return((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius));
                }
                    );

                // *** request properties of these objects ***
                bool complete = RequestObjectProperties(prims, 0);

                String resultSet = String.Empty;

                foreach (Primitive p in prims)
                {
                    string?name = p.Properties != null ? p.Properties.Name : null;
                    if (String.IsNullOrEmpty(type) || ((name != null) && (name.Contains(type))))
                    {
                        resultSet += $"<prim><name>{name}</name><pos>{p.Position.X},{p.Position.Y},{p.Position.Z}</pos><id>{p.ID}</id></prim>";
                    }
                }
                return("<nearby_prims>" + resultSet + "</nearby_prims>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{e.Message}</error>");
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Login block
        /// </summary>
        public LoginReply Login()
        {
            LoginReply response = new LoginReply();

            DebugUtilities.WriteSpecial("Login block was called in Login()");
            if (Client.Network.Connected)
            {
                DebugUtilities.WriteError("Uhm, Login() was called when we where already connected. Hurr");
                return(new LoginReply());
            }

            //Client.Network.LoginProgress +=
            //    delegate(object? sender, LoginProgressEventArgs e)
            //    {
            //        DebugUtilities.WriteDebug($"Login {e.Status}: {e.Message}");
            //        if (e.Status == LoginStatus.Success)
            //        {
            //            DebugUtilities.WriteSpecial("Logged in successfully");
            //            myStatus = Status.Connected;
            //            response.wasFatal = false;
            //            response.xmlReply = "<success><session_id>" + sessionid.ToString() + "</session_id></success>";
            //        }
            //        else if (e.Status == LoginStatus.Failed)
            //        {
            //            DebugUtilities.WriteError("$There was an error while connecting: {Client.Network.LoginErrorKey}");
            //            response.wasFatal = true;
            //            response.xmlReply = "<error></error>";
            //        }
            //    };
            // Optimize the throttle
            Client.Throttle.Wind  = 0;
            Client.Throttle.Cloud = 0;
            Client.Throttle.Land  = 1000000;
            Client.Throttle.Task  = 1000000;

            // we add this check here because LOGIN_SERVER should never be assigned null (gwyneth 20220213)
            if (Program.config != null && Program.config.networking.loginuri != null)
            {
                Client.Settings.LOGIN_SERVER = Program.config.networking.loginuri;                      // could be String.Empty, so we check below...
            }
            else if (RESTBot.XMLConfig.Configuration.defaultLoginURI != null)
            {
                Client.Settings.LOGIN_SERVER = RESTBot.XMLConfig.Configuration.defaultLoginURI;                 // could ALSO be String.Empty, so we check below...
            }
            else
            {
                Client.Settings.LOGIN_SERVER = String.Empty;
            }

            // Any of the above _might_ have set LOGIN_SERVER to an empty string, so we check first if we have
            // something inside the string. (gwyneth 20220213)
            // To-do: validate the URL first? It's not clear if .NET 6 already does that at some point...
            if (Client.Settings.LOGIN_SERVER == String.Empty)
            {
                // we don't know where to login to!
                response.wasFatal = true;
                response.xmlReply = "<error fatal=\"true\">No login URI provided</error>";
                DebugUtilities.WriteError("No login URI provided; aborting...");
                return(response);
            }
            DebugUtilities.WriteDebug($"Login URI: {Client.Settings.LOGIN_SERVER}");

            LoginParams loginParams =
                Client.Network.DefaultLoginParams(First, Last, MD5Password, "RestBot", Program.Version);

            loginParams.Start = Start;

            if (Client.Network.Login(loginParams))
            {
                DebugUtilities.WriteSpecial($"{First} {Last} logged in successfully");
                myStatus          = Status.Connected;
                response.wasFatal = false;
                response.xmlReply =
                    $@"<success>
	<session_id>{sessionid.ToString()}</session_id>
	<key>{Client.Self.AgentID.ToString()}</key>
	<name>{Client.Self.FirstName} {Client.Self.LastName}</name>
	<FirstName>{Client.Self.FirstName}</FirstName>
	<LastName>{Client.Self.LastName}</LastName>
	<CurrentSim>{Client.Network.CurrentSim.ToString()}</CurrentSim>
	<Position>{Client.Self.SimPosition.X},{Client.Self.SimPosition.Y},{Client.Self.SimPosition.Z}</Position>
	<Rotation>{Client.Self.SimRotation.X},{Client.Self.SimRotation.Y},{Client.Self.SimRotation.Z},{Client.Self.SimRotation.W}</Rotation>
</success>";
            }
            else
            {
                DebugUtilities
                .WriteError($"There was an error while connecting: {Client.Network.LoginErrorKey}");
                switch (Client.Network.LoginErrorKey)
                {
                case "connect":
                case "key":
                case "disabled":
                    response.wasFatal = true;
                    response.xmlReply =
                        $"<error fatal=\"true\">{Client.Network.LoginMessage}</error>";
                    break;

                case "presence":
                case "timed out":
                case "god":
                    DebugUtilities
                    .WriteWarning("Nonfatal error while logging in.. this may be normal");
                    response.wasFatal = false;
                    response.xmlReply =
                        $"<error fatal=\"false\">{Client.Network.LoginMessage}</error><retry>10</retry><session_id>{sessionid}</session_id>";

                    DebugUtilities
                    .WriteSpecial("Relogin attempt will be made in 10 minutes");
                    ReloginTimer.Interval = 10 * 60 * 1000;                             //10 minutes
                    ReloginTimer.Start();
                    break;

                default:
                    DebugUtilities
                    .WriteError($"{sessionid.ToString()} UNKNOWN ERROR {Client.Network.LoginErrorKey} WHILE ATTEMPTING TO LOGIN");
                    response.wasFatal = true;
                    response.xmlReply =
                        $"<error fatal=\"true\">Unknown error '{Client.Network.LoginErrorKey}' has occurred.</error>";
                    break;
                }

                if (response.wasFatal == false)
                {
                    myStatus = Status.Reconnecting;
                }
            }

            //Client.Network.BeginLogin(loginParams);
            return(response);
        }         // end Login()
Ejemplo n.º 20
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            try
            {
                string sim = "";
                float
                    x      = 128.0f,
                    y      = 128.0f,
                    z      = 30.0f;
                bool check = true;

                if (Parameters.ContainsKey("sim"))
                {
                    sim = Parameters["sim"].ToString();
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("x"))
                {
                    check &= float.TryParse(Parameters["x"], out x);
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("y"))
                {
                    check &= float.TryParse(Parameters["y"], out y);
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("z"))
                {
                    check &= float.TryParse(Parameters["z"], out z);
                }
                else
                {
                    check = false;
                }

                if (!check)
                {
                    return($"<error>{MethodName} parameters have to be simulator name, x, y, z</error>");
                }
                // debug: calculate destination vector, show data, just to make sure it's correct (gwyneth 20220411)
                Vector3 teleportPoint = new Vector3(x, y, z);
                DebugUtilities.WriteDebug($"attempting teleport to ({x}), ({y}), ({z}) - vector: {teleportPoint.ToString()}");

                if (b.Client.Self.Teleport(sim, teleportPoint))
                {
                    if (b.Client.Network.CurrentSim != null)
                    {
                        return(String
                               .Format("<teleport><CurrentSim>{0}</CurrentSim><Position>{1},{2},{3}</Position></teleport>",
                                       b.Client.Network.CurrentSim.ToString(),
                                       b.Client.Self.SimPosition.X,
                                       b.Client.Self.SimPosition.Y,
                                       b.Client.Self.SimPosition.Z));
                    }
                    else
                    {
                        return($"<error>Teleport failed, no sim handle found: {b.Client.Self.TeleportMessage}</error>");
                    }
                }
                else
                {
                    return($"<error>Teleport failed: {b.Client.Self.TeleportMessage}</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 21
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID embedItemID = UUID.Zero;
            string
                notecardName,
                notecardData;

            DebugUtilities.WriteDebug("Entering key parser");
            try
            {
                // item ID to embed is optional; handle later
                if (Parameters.ContainsKey("key"))
                {
                    UUID
                    .TryParse(Parameters["key"].ToString().Replace("_", " "),
                              out embedItemID);
                }

                // notecard data is required!
                if (Parameters.ContainsKey("notecard"))
                {
                    DebugUtilities
                    .WriteDebug("Attempting to parse notecard data from POST");
                    notecardData = Parameters["notecard"];
                }
                else
                {
                    return("<error>notecard text data not found</error>");
                }

                // notecard name is optional, we'll assign a random name
                if (Parameters.ContainsKey("name"))
                {
                    DebugUtilities
                    .WriteDebug("Attempting to parse notecard name from POST");
                    notecardName = Parameters["name"];

                    DebugUtilities.WriteDebug("Succesfully parsed POST");
                }
                else
                {
                    notecardName = "(no name)";
                }

                UUID
                    notecardItemID  = UUID.Zero,
                    notecardAssetID = UUID.Zero;
                bool
                    success                  = false,
                    finalUploadSuccess       = false;
                string         message       = String.Empty;
                AutoResetEvent notecardEvent = new AutoResetEvent(false);

                DebugUtilities
                .WriteDebug($"Notecard data ('{notecardName}') found: '{notecardData}'");


                #region Notecard asset data

                AssetNotecard notecard = new AssetNotecard();
                notecard.BodyText = notecardData;

                // Item embedding
                if (embedItemID != UUID.Zero)
                {
                    // Try to fetch the inventory item
                    InventoryItem?item = FetchItem(b, embedItemID);
                    if (item != null)
                    {
                        notecard.EmbeddedItems = new List <InventoryItem> {
                            item
                        };
                        notecard.BodyText += (char)0xdbc0 + (char)0xdc00;
                    }
                    else
                    {
                        return("Failed to fetch inventory item " + embedItemID);
                    }
                }

                notecard.Encode();


                #endregion Notecard asset data


                b
                .Client
                .Inventory
                .RequestCreateItem(b
                                   .Client
                                   .Inventory
                                   .FindFolderForType(AssetType.Notecard),
                                   notecardName,
                                   notecardName + " created by LibreMetaverse RESTbot " + DateTime.Now,
                                   AssetType.Notecard,
                                   UUID.Random(),
                                   InventoryType.Notecard,
                                   PermissionMask.All,
                                   delegate(bool createSuccess, InventoryItem item)
                {
                    if (createSuccess)
                    {
                        #region Upload an empty notecard asset first

                        AutoResetEvent emptyNoteEvent = new AutoResetEvent(false);
                        AssetNotecard empty           = new AssetNotecard();
                        empty.BodyText = "\n";
                        empty.Encode();

                        b
                        .Client
                        .Inventory
                        .RequestUploadNotecardAsset(empty.AssetData,
                                                    item.UUID,
                                                    delegate(
                                                        bool uploadSuccess,
                                                        string status,
                                                        UUID itemID,
                                                        UUID assetID)
                        {
                            notecardItemID  = itemID;
                            notecardAssetID = assetID;
                            success         = uploadSuccess;
                            message         = status ?? "Unknown error uploading notecard asset";
                            emptyNoteEvent.Set();
                        });

                        emptyNoteEvent.WaitOne(NOTECARD_CREATE_TIMEOUT, false);


                        #endregion Upload an empty notecard asset first


                        if (success)
                        {
                            // Upload the actual notecard asset
                            b
                            .Client
                            .Inventory
                            .RequestUploadNotecardAsset(notecard.AssetData, item.UUID,
                                                        delegate(bool uploadSuccess, string status, UUID itemID, UUID assetID)
                            {
                                notecardItemID     = itemID;
                                notecardAssetID    = assetID;
                                finalUploadSuccess = uploadSuccess;
                                message            = status ?? "Unknown error uploading notecard asset";
                                notecardEvent.Set();
                            });
                        }
                        else
                        {
                            notecardEvent.Set();
                        }
                    }
                    else
                    {
                        message = "Notecard item creation failed";
                        notecardEvent.Set();
                    }
                });                         // end delegate // end RequestCreateItem

                notecardEvent.WaitOne(NOTECARD_CREATE_TIMEOUT, false);

                // DebugUtilities.WriteDebug("Notecard possibly created, ItemID " + notecardItemID + " AssetID " + notecardAssetID + " Content: '" + DownloadNotecard(b, notecardItemID, notecardAssetID) + "'");
                if (finalUploadSuccess)
                {
                    DebugUtilities
                    .WriteDebug($"Notecard successfully created, ItemID {notecardItemID}; AssetID {notecardAssetID}; Content: '{DownloadNotecard(b, notecardItemID, notecardAssetID)}'");
                    return($"<notecard><ItemID>{notecardItemID}</ItemID><AssetID>{notecardAssetID}</AssetID><name>{notecardName}</name></notecard>");
                }
                else
                {
                    return($"<error>Notecard creation failed: {message}</error>");
                }
            }             // end try
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 22
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            /// <summary>UUID for the prim/object that we intend the bot to sit on</summary>
            UUID sitTargetID = UUID.Zero;

            DebugUtilities.WriteDebug($"{b.sessionid} {MethodName} - Searching for prim to sit on");
            try
            {
                bool check = false;
                /// <summary>optionally, we can skip prim search and force sitting on UUID</summary>
                bool force = false;

                if (Parameters.ContainsKey("target"))
                {
                    check =
                        UUID
                        .TryParse(Parameters["target"].ToString().Replace("_", " "),
                                  out sitTargetID);
                }

                if (!check)
                {
                    return($"<error>{MethodName} no sit target specified</error>");
                }

                // optional
                if (Parameters.ContainsKey("force"))
                {
                    check = bool.TryParse(Parameters["force"], out force);
                }

                if (!check)
                {
                    return($"<error>{MethodName} force sit attempted with wrong setting; only true/false are allowed</error>");
                }

                // If we get to this point means that we have a correctly parsed key for the target prim
                DebugUtilities.WriteDebug($"{b.sessionid} {MethodName} - Trying to sit on {sitTargetID.ToString()}...");

                // If not forcing, we'll search for a prim with this UUID in the 'bot interest list
                // and retrieve the information from that prim. (gwyneth 20220410)
                if (!force)
                {
                    Primitive targetPrim = b.Client.Network.CurrentSim.ObjectsPrimitives.Find(
                        prim => prim.ID == sitTargetID
                        );

                    if (targetPrim != null)
                    {
                        b.Client.Self.RequestSit(targetPrim.ID, Vector3.Zero);
                        b.Client.Self.Sit();
                        return($"<{MethodName}>sitting on \"{targetPrim.Properties.Name}\" ({targetPrim.ID.ToString()} [Local ID: {targetPrim.LocalID}])</{MethodName}>");
                    }

                    return($"<error>{MethodName}: no prim with UUID {sitTargetID} found</error>");
                }
                else                    // forcing to sit on a prim we KNOW that exists! (gwyneth 20220410)
                {
                    b.Client.Self.RequestSit(sitTargetID, Vector3.Zero);
                    b.Client.Self.Sit();
                    return($"<{MethodName}>forced sitting on {sitTargetID.ToString()}</{MethodName}>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 23
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID itemID;

            DebugUtilities.WriteDebug("List Item - Entering key parser");
            try
            {
                bool check = false;
                if (Parameters.ContainsKey("key"))
                {
                    DebugUtilities.WriteDebug("Attempting to parse from POST");
                    check =
                        UUID
                        .TryParse(Parameters["key"].ToString().Replace("_", " "),
                                  out itemID);
                    DebugUtilities.WriteDebug("Succesfully parsed POST");
                }
                else
                {
                    return($"<error>{MethodName}: parsekey</error>");
                }

                if (
                    check                     // means that we have a correctly parsed key
                    )
                {
                    DebugUtilities
                    .WriteDebug("Fetching " + itemID.ToString());

                    InventoryItem oneItem;

                    oneItem =
                        b.Client.Inventory.FetchItem(itemID, b.Client.Self.AgentID, 5000);

                    // to-do: catch timeout explicitly
                    if (oneItem == null)
                    {
                        return($"<error>item {itemID.ToString()} not found</error>");
                    }

                    string response;

                    response = $@"<item>
	<AssetUUID>{oneItem.AssetUUID.ToString()}</AssetUUID>
	<PermissionsOwner>{PermMaskString(oneItem.Permissions.OwnerMask)}</PermissionsOwner>
	<PermissionsGroup>{PermMaskString(oneItem.Permissions.GroupMask)}</PermissionsGroup>
	<AssetType>{oneItem.AssetType.ToString()}</AssetType>
	<InventoryType>{oneItem.InventoryType.ToString()}</InventoryType>
	<CreatorID>{oneItem.CreatorID.ToString()}</CreatorID>
	<Description>{oneItem.Description.ToString()}</Description>
	<GroupID>{oneItem.GroupID.ToString()}</GroupID>
	<GroupOwned>{oneItem.GroupOwned.ToString()}</GroupOwned>
	<SalePrice>{oneItem.SalePrice.ToString()}</SalePrice>
	<SaleType>{oneItem.SaleType.ToString()}</SaleType>
	<Flags>{oneItem.Flags.ToString()}</Flags>
	<CreationDate>
		{oneItem.CreationDate.ToString()}
	</CreationDate>
	<LastOwnerID>{oneItem.LastOwnerID.ToString()}</LastOwnerID>
</item>";
                    return(response);
                }
                else
                {
                    return($"<error>{MethodName}: parsekey</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 24
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            try
            {
                string name  = "";
                bool   check = true;

                // "target" is essentially an avatar name (first, last) (gwyneth 20220120)
                if (Parameters.ContainsKey("target"))
                {
                    name = Parameters["target"].ToString().Replace("+", " ");
                }
                else
                {
                    check = false;
                }

                if (!check)
                {
                    return("<error>parameters have to be target avatar name (first, last)</error>");
                }

                lock (b.Client.Network.Simulators)
                {
                    for (int i = 0; i < b.Client.Network.Simulators.Count; i++)
                    {
                        DebugUtilities
                        .WriteDebug("Found Avatars: " +
                                    b.Client.Network.Simulators[i].ObjectsAvatars.Count);
                        Avatar?target =
                            b
                            .Client
                            .Network
                            .Simulators[i]
                            .ObjectsAvatars
                            .Find(delegate(Avatar avatar)
                        {
                            DebugUtilities.WriteDebug($"Found avatar: {avatar.Name}");
                            return(avatar.Name == name);
                        });

                        if (target != null)
                        {
                            return(String
                                   .Format("<goal_position>{0},{1},{2}</goal_position><curr_position>{3},{4},{5}</curr_position>",
                                           target.Position.X,
                                           target.Position.Y,
                                           target.Position.Z,
                                           b.Client.Self.SimPosition.X,
                                           b.Client.Self.SimPosition.Y,
                                           b.Client.Self.SimPosition.Z));
                        }
                        else
                        {
                            DebugUtilities.WriteError($"Error obtaining the avatar: {name}");
                        }
                    }
                }
                return("<error>avatar_position failed.</error>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{e.Message}</error>");
            }
        }
Ejemplo n.º 25
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            uint
                regionX,
                regionY;

            Utils
            .LongToUInts(b.Client.Network.CurrentSim.Handle,
                         out regionX,
                         out regionY);

            try
            {
                double
                    x        = 0.0f,
                    y        = 0.0f,
                    z        = 0.0f,
                    distance = 0.0f;
                bool check   = true;
                /// <summary>Selects between running (true) or walking (false)</summary>
                bool run = false;

                if (Parameters.ContainsKey("x"))
                {
                    check &= double.TryParse(Parameters["x"], out x);
                    DebugUtilities.WriteDebug($"{MethodName} Parse: {Parameters["x"]} into {x}");
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("y"))
                {
                    check &= double.TryParse(Parameters["y"], out y);
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("z"))
                {
                    check &= double.TryParse(Parameters["z"], out z);
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("distance"))
                {
                    check &= double.TryParse(Parameters["distance"], out distance);
                }

                if (Parameters.ContainsKey("run"))
                {
                    check &= bool.TryParse(Parameters["run"], out run);
                }

                if (!check)
                {
                    return($"<error>{MethodName} parameters have to be x, y, z, [distance, run]</error>");
                }

                if (run)
                {
                    b.Client.Self.Movement.AlwaysRun = true;
                }
                else
                {
                    b.Client.Self.Movement.AlwaysRun = false;
                }
                goalPos = new Vector3((float)x, (float)y, (float)z);
                b.Client.Self.Movement.TurnToward(goalPos, false);

                // Check for null and, if so, abort with error (gwyneth 20220213)
                if (me == null)
                {
                    DebugUtilities.WriteError("'me' was null!");
                    return($"<error>{MethodName}: 'me' was null</error>");
                }

                prevDistance = Vector3.Distance(goalPos, me.Client.Self.SimPosition);

                // Convert the local coordinates to global ones by adding the region handle parts to x and y
                b
                .Client
                .Self
                .AutoPilot(goalPos.X + regionX, goalPos.Y + regionY, goalPos.Z);
                Active   = true;
                attempts = 20;                  // reset attempts, or else they'll be stuck at zero... (gwyneth 20220304)
                while (Active)
                {
                    Thread.Sleep(1 * 1000);
                }
                DebugUtilities.WriteSpecial($"End {MethodName} Thread!");
                return($"<{MethodName}>{b.Client.Self.GlobalPosition.X},{b.Client.Self.GlobalPosition.Y},{b.Client.Self.GlobalPosition.Z}</{MethodName}>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 26
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            Utils
            .LongToUInts(b.Client.Network.CurrentSim.Handle,
                         out regionX,
                         out regionY);

            try
            {
                double
                    x             = 0.0f,
                    y             = 0.0f,
                    z             = 0.0f;
                bool   check      = true;
                bool   run        = false;
                string avatarName = String.Empty;

                if (Parameters.ContainsKey("avatar"))
                {
                    avatarName = Parameters["avatar"].ToString().Replace("+", " ");
                }
                else
                {
                    check = false;
                }

                // added it here, but I'm not sure if it's correct... (gwyneth 20220409)
                if (Parameters.ContainsKey("run"))
                {
                    check &= bool.TryParse(Parameters["run"], out run);
                }

                if (!check)
                {
                    return($"<error>{MethodName} parameters have to be avatar name to follow</error>");
                }

                if (run)
                {
                    b.Client.Self.Movement.AlwaysRun = true;
                }
                else
                {
                    b.Client.Self.Movement.AlwaysRun = false;
                }

                lock (b.Client.Network.Simulators)
                {
                    for (int i = 0; i < b.Client.Network.Simulators.Count; i++)
                    {
                        DebugUtilities
                        .WriteDebug($"Found {b.Client.Network.Simulators[i].ObjectsAvatars.Count} Avatar(s)");
                        target =
                            b
                            .Client
                            .Network
                            .Simulators[i]
                            .ObjectsAvatars
                            .Find(delegate(Avatar avatar)
                        {
                            DebugUtilities.WriteDebug($"Found avatar: {avatar.Name}");
                            return(avatar.Name == avatarName);
                        });

                        if (target != null)
                        {
                            goalPos = target.Position;
                        }
                        else
                        {
                            DebugUtilities
                            .WriteError($"{MethodName} - Error finding position of '{avatarName}'");
                            return($"<error>{MethodName} error finding position of '{avatarName}'</error>");
                        }
                    }
                }

                goalPos = new Vector3((float)x, (float)y, (float)z);
                b.Client.Self.Movement.TurnToward(goalPos, false);

                // C# 8+ is stricter with nulls; if 'me' is null, we got a problem,
                // because there is no way to calculate the distance; so we simply set it to zero
                // in that case; this may play havoc with the algorithm, though. (gwyneth 20220213)
                if (me != null)
                {
                    prevDistance = Vector3.Distance(goalPos, me.Client.Self.SimPosition);
                }
                else
                {
                    prevDistance = 0;
                }
                if (prevDistance > 30)
                {
                    b.Client.Self.Movement.AlwaysRun = true;
                }
                else
                {
                    b.Client.Self.Movement.AlwaysRun = false;
                }

                // Convert the local coordinates to global ones by adding the region handle parts to x and y
                b
                .Client
                .Self
                .AutoPilot(goalPos.X + regionX, goalPos.Y + regionY, goalPos.Z);
                Active = true;

                while (Active)
                {
                    Thread.Sleep(1 * 1000);
                }
                DebugUtilities.WriteSpecial($"End {MethodName} Thread!");
                return($"<{MethodName}>{b.Client.Self.GlobalPosition.X},{b.Client.Self.GlobalPosition.Y},{b.Client.Self.GlobalPosition.Z}</{MethodName}>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Handler event for this plugin.
        /// </summary>
        /// <param name="b">A currently active RestBot</param>
        /// <param name="Parameters">A dictionary containing the UUID of the avatar to invite, the UUID of
        /// the group to invite, and the role UUID to invite the avatar in to</param>
        /// <returns>XML with information about a successful invite to a group/role; XML error otherwise</returns>
        /// <remarks><para>Currently, avatars can only be invited to a singke role at the time.</para>
        /// <para>To-do: work on allowing invitations to multiple roles simultaenously!</para></remarks>
        public override string Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID        avatar = UUID.Zero;
            UUID        group  = UUID.Zero;
            UUID        role   = UUID.Zero;
            List <UUID> roles  = new List <UUID>();

            try
            {
                bool check = false;
                if (Parameters.ContainsKey("avatar"))
                {
                    check = UUID.TryParse(Parameters["avatar"].ToString().Replace("_", " "), out avatar);
                }
                else
                {
                    return("<error>arguments: no avatar key</error>");
                }
                if (check)
                {
                    if (Parameters.ContainsKey("group"))
                    {
                        check = UUID.TryParse(Parameters["group"].ToString().Replace("_", " "), out group);
                    }
                    else
                    {
                        return("<error>arguments: no group key</error>");
                    }

                    // to-do: avatars can be invited to multiple roles.
                    if (Parameters.ContainsKey("role"))
                    {
                        if (!UUID.TryParse(Parameters["role"].ToString().Replace("_", " "), out role))
                        {
                            // just a warning, role is optional
                            DebugUtilities.WriteDebug(session + " " + MethodName + " no role found, but that's ok");
                        }
                        roles.Add(role);
                    }
                    else
                    {
                        roles.Add(UUID.Zero);                         // no roles to add
                    }
                }
                else
                {
                    return("<error>parsekey</error>");
                }

                DebugUtilities.WriteDebug(session + " " + MethodName + " Group UUID: " + group + " Avatar UUID to join group: " + avatar + " Role UUID for avatar to join: " + roles.ToString() + " (NULL_KEY is fine)");

                b.Client.Groups.Invite(group, roles, avatar);

                return("<invitation>invited " + avatar + " to " + group + "</invitation>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return("<error>loads of errors</error>");
            }
        }
Ejemplo n.º 28
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            UUID
                itemID,
                avatarKey;
            InventoryManager Manager;

            DebugUtilities.WriteDebug("Entering key parser");
            try
            {
                bool check = false;
                if (Parameters.ContainsKey("itemID"))
                {
                    DebugUtilities.WriteDebug("Attempting to parse from POST");
                    check =
                        UUID
                        .TryParse(Parameters["itemID"].ToString().Replace("_", " "),
                                  out itemID);

                    if (check)
                    {
                        check =
                            UUID
                            .TryParse(Parameters["avatarKey"].ToString().Replace("_", " "),
                                      out avatarKey);
                        DebugUtilities.WriteDebug("Succesfully parsed POST");
                    }
                    else
                    {
                        return($"<error>{MethodName}: parsekey itemID</error>");
                    }
                }
                else
                {
                    return($"<error{MethodName}:>parsekey</error>");
                }

                if (
                    check                     // means that we have a correctly parsed key
                    )
                {
                    DebugUtilities
                    .WriteDebug($"Give Item {itemID.ToString()} to avatar {avatarKey.ToString()}");

                    // Extract item information from inventory
                    InventoryItem oneItem;

                    oneItem =
                        b.Client.Inventory.FetchItem(itemID, b.Client.Self.AgentID, 5000);

                    // to-do: catch timeout explicitly
                    if (oneItem == null)
                    {
                        return($"<error>item {itemID.ToString()} not found</error>");
                    }

                    // attempt to send it to the avatar
                    Manager = b.Client.Inventory;

                    Manager
                    .GiveItem(oneItem.UUID,
                              oneItem.Name,
                              oneItem.AssetType,
                              avatarKey,
                              false);

                    return($"<item><name>{oneItem.Name}</name><assetType>{oneItem.AssetType}</assetType><itemID>{itemID.ToString()}</itemID><avatarKey>{avatarKey.ToString()}</avatarKey></item>");
                }
                else
                {
                    return($"<error>{MethodName}: parsekey avatarKey</error>");
                }
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        }
Ejemplo n.º 29
0
        } = "0.0.0.0";                                                                                  // will be filled in later by Main() (gwyneth 20220425)

        /// <summary>
        /// Bootstrap method.
        /// </summary>
        /// <param name="args">Arguments passed to the application</param>
        /// <remarks>The arguments seem to get promptly ignored! (gwyneth 20220109)</remarks>
        static void Main(string[] args)
        {
            // LogManager.GetLogger(typeof(RestBot));

            // new function to parse some useful arguments and do interesting things (gwyneth 20220425)
            ParseArguments(args);

            // see if we can get the version string
            try
            {
                // Note: we ought to also extract the Assembly name, we presume it's the default (gwyneth 20220426)
#if Windows
                var fileVersionInfo = FileVersionInfo.GetVersionInfo("@RESTbot.dll");
#else
                var fileVersionInfo = FileVersionInfo.GetVersionInfo("@RESTbot");
#endif
                Version = fileVersionInfo.FileVersion + "-file";
            }
            catch (Exception e1)
            {
                // nope, this doesn't work under macOS
                DebugUtilities.WriteDebug($"Cannot retrieve file version, exception caught: {e1.Message}");
                // let's try to get the assembly name instead
                try
                {
                    var assembly = Assembly.GetExecutingAssembly();
                    Version = assembly.GetName().Version + "-assembly";
                }
                catch (Exception e2)
                {
                    // nope, that didn't work either
                    DebugUtilities.WriteDebug($"Cannot retrieve assembly version either, exception caught: {e2.Message}");
                    // finally, our last choice is trying the Informational Version
                    try
                    {
                        var assembly = Assembly.GetEntryAssembly();
                        if (assembly != null)
                        {
                            var customAttribute = assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>();
                            if (customAttribute != null)
                            {
                                var infoVersion = customAttribute.InformationalVersion;

                                if (infoVersion != null)
                                {
                                    Version = infoVersion;
                                }
                            }
                        }
                    }
                    catch (Exception e3)
                    {
                        // we're out of luck today, we cannot even get the Informational Versoin
                        DebugUtilities.WriteDebug($"Also cannot retrieve informational version, exception caught: {e3.Message}");
                        // we'll have to stick with the hard-coded default Version instead...
                    }
                }
            }
            if (Version == null)
            {
                Version = "0.0.0.0";
            }
            DebugUtilities.WriteInfo($"RESTbot file version: {Version}");

            DebugUtilities.WriteInfo($"Reading config file '{configFile}'...");
            config = XMLConfig.Configuration.LoadConfiguration(configFile);
            if (config == null)
            {
                // configuration is mandatory! (gwyneth 20220213)
                DebugUtilities.WriteError($"Unable to open configuration file '{configFile}'! Aborting...");
                Environment.Exit(1);
                return;
            }

            DebugUtilities.WriteInfo("RESTbot startup");
            // Sessions should never be null (?) (gwyneth 20220214)
            if (Sessions == null)
            {
                // Trouble expects us later on, when adding and removing sessions...
                DebugUtilities.WriteError("Error initialising Sessions directory; it was set to null!");
            }

            /// <summary>Get the file version of LibreMetaverse.</summary>
            /// <remarks><see href="https://stackoverflow.com/a/14612480/1035977"/> (gwyneth 20220414)</remarks>
            FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(@"LibreMetaverse.dll");

            // Print the file name and version number.
            DebugUtilities.WriteInfo($"LibreMetaverse DLL version: {myFileVersionInfo.FileDescription} {myFileVersionInfo.FileVersion}");

            DebugUtilities.WriteInfo("Loading plugins");
            RegisterAllCommands(Assembly.GetExecutingAssembly());
            DebugUtilities.WriteDebug("Loading stateful plugins");
            RegisterAllStatefulPlugins(Assembly.GetExecutingAssembly());

            DebugUtilities.WriteInfo($"Listening on port {config.networking.port.ToString()}");

            // Set up the listener / router
            Listener = new RESTBot.Server.Router(IPAddress.Parse(config.networking.ip), config.networking.port);

            StillRunning = true;
            DebugUtilities.WriteInfo("Startup complete");
            uptime = DateTime.Now;

            // let's see if we can figure out how much memory is being wasted
            int stupidCounter = 0;
            while (StillRunning)
            {
                System.Threading.Thread.Sleep(1);
                //TODO: Replace above with a manualresetevent

                if (stupidCounter % 3600000 == 0)                       // stop every hour and check available memory (gwyneth 20220210)
                {
                    CollectGarbage();
                }
                stupidCounter++;
            }

            Listener.StillRunning = false;
        }
Ejemplo n.º 30
0
        Process(RestBot b, Dictionary <string, string> Parameters)
        {
            // uint
            //  regionX,
            //  regionY;
            // Utils
            //  .LongToUInts(b.Client.Network.CurrentSim.Handle,
            //  out regionX,
            //  out regionY);

            try
            {
                double
                    x      = 0.0f,
                    y      = 0.0f,
                    z      = 0.0f;
                bool check = true;

                if (Parameters.ContainsKey("x"))
                {
                    check &= double.TryParse(Parameters["x"], out x);
                    DebugUtilities.WriteDebug($"{MethodName} Parse: {Parameters["x"]} into {x}");
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("y"))
                {
                    check &= double.TryParse(Parameters["y"], out y);
                }
                else
                {
                    check = false;
                }

                if (Parameters.ContainsKey("z"))
                {
                    check &= double.TryParse(Parameters["z"], out z);
                }
                else
                {
                    check = false;
                }

                if (!check)
                {
                    return($"<error>{MethodName} parameters have to be x, y, z</error>");
                }

                goalPos = new Vector3((float)x, (float)y, (float)z);
                b.Client.Self.Movement.TurnToward(goalPos, false);

                return($"<{MethodName}><location>{b.Client.Self.GlobalPosition.X},{b.Client.Self.GlobalPosition.Y},{b.Client.Self.GlobalPosition.Z}</location><rotation>{b.Client.Self.SimRotation.X},{b.Client.Self.SimRotation.Y},{b.Client.Self.SimRotation.Z},{b.Client.Self.SimRotation.W}</rotation></{MethodName}>");
            }
            catch (Exception e)
            {
                DebugUtilities.WriteError(e.Message);
                return($"<error>{MethodName}: {e.Message}</error>");
            }
        } // end turnto process