From fa79433d2eafbb11b5ca737fde8939c7b592e557 Mon Sep 17 00:00:00 2001
From: Sean Dague
Date: Tue, 11 Mar 2008 18:06:25 +0000
Subject: clone off pCampBot to OpenSim.TestSuite, as I'm going to be making
 enough breaking changes that I'd rather not mess up people currently using
 pCampBot effectively.

---
 OpenSim/TestSuite/BotManager.cs | 239 ++++++++++++++++++++++++++++++++++++++++
 OpenSim/TestSuite/PhysicsBot.cs | 203 ++++++++++++++++++++++++++++++++++
 OpenSim/TestSuite/pCampBot.cs   | 114 +++++++++++++++++++
 3 files changed, 556 insertions(+)
 create mode 100644 OpenSim/TestSuite/BotManager.cs
 create mode 100644 OpenSim/TestSuite/PhysicsBot.cs
 create mode 100644 OpenSim/TestSuite/pCampBot.cs

(limited to 'OpenSim')

diff --git a/OpenSim/TestSuite/BotManager.cs b/OpenSim/TestSuite/BotManager.cs
new file mode 100644
index 0000000..efd1613
--- /dev/null
+++ b/OpenSim/TestSuite/BotManager.cs
@@ -0,0 +1,239 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above copyright
+*       notice, this list of conditions and the following disclaimer in the
+*       documentation and/or other materials provided with the distribution.
+*     * Neither the name of the OpenSim Project nor the
+*       names of its contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* 
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using libsecondlife;
+using libsecondlife.Packets;
+using Nini.Config;
+using System.Threading;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+
+namespace pCampBot
+{
+    /// <summary>
+    /// Thread/Bot manager for the application
+    /// </summary>
+    public class BotManager : conscmd_callback
+    {
+        private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+        protected ConsoleBase m_console;
+        protected List<PhysicsBot> m_lBot;
+        protected Thread[] m_td;
+        protected bool m_verbose = true;
+        protected Random somthing = new Random(System.Environment.TickCount);
+        protected int numbots = 0;
+        protected IConfig Previous_config;
+        
+        /// <summary>
+        /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data
+        /// </summary>
+        public BotManager()
+        {
+            m_log.Info("In bot manager");
+            // m_console = CreateConsole();
+            // MainConsole.Instance = m_console;
+            m_lBot = new List<PhysicsBot>();
+        }
+
+        /// <summary>
+        /// Startup number of bots specified in the starting arguments
+        /// </summary>
+        /// <param name="botcount">How many bots to start up</param>
+        /// <param name="cs">The configuration for the bots to use</param>
+        public void dobotStartup(int botcount, IConfig cs)
+        {
+            Previous_config = cs;
+            m_td = new Thread[botcount];
+            for (int i = 0; i < botcount; i++)
+            {
+                startupBot(i, cs);
+            }
+        }
+
+        /// <summary>
+        /// Add additional bots (and threads) to our bot pool
+        /// </summary>
+        /// <param name="botcount">How Many of them to add</param>
+        public void addbots(int botcount)
+        {
+            int len = m_td.Length;
+            Thread[] m_td2 = new Thread[len + botcount];
+            for (int i = 0; i < len; i++)
+            {
+                m_td2[i] = m_td[i];
+            }
+            m_td = m_td2;
+            int newlen = len + botcount;
+            for (int i = len; i < newlen; i++)
+            {
+                startupBot(i, Previous_config);
+            }
+        }
+       
+        /// <summary>
+        /// This starts up the bot and stores the thread for the bot in the thread array
+        /// </summary>
+        /// <param name="pos">The position in the thread array to stick the bot's thread</param>
+        /// <param name="cs">Configuration of the bot</param>
+        public void startupBot(int pos, IConfig cs)
+        {
+            PhysicsBot pb = new PhysicsBot(cs);
+
+            pb.OnConnected += handlebotEvent;
+            pb.OnDisconnected += handlebotEvent;
+            if (cs.GetString("firstname", "random") == "random") pb.firstname = CreateRandomName();
+            if (cs.GetString("lastname", "random") == "random") pb.lastname = CreateRandomName();
+
+            m_td[pos] = new Thread(pb.startup);
+            m_td[pos].Name = "CampBot_" + pos;
+            m_td[pos].IsBackground = true;
+            m_td[pos].Start();
+            m_lBot.Add(pb);
+            OpenSim.Framework.ThreadTracker.Add(m_td[pos]);
+        }
+
+        /// <summary>
+        /// Creates a random name for the bot
+        /// </summary>
+        /// <returns></returns>
+        private string CreateRandomName()
+        {
+            string returnstring = "";
+            string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
+            
+            for (int i = 0; i < 7; i++)
+            {
+                returnstring += chars.Substring(somthing.Next(chars.Length),1);
+            }
+            return returnstring;
+        }
+
+        /// <summary>
+        /// High level connnected/disconnected events so we can keep track of our threads by proxy
+        /// </summary>
+        /// <param name="callbot"></param>
+        /// <param name="eventt"></param>
+        public void handlebotEvent(PhysicsBot callbot, EventType eventt)
+        {
+            switch (eventt)
+            {
+                case EventType.CONNECTED:
+                    m_log.Info("[ " + callbot.firstname + " " + callbot.lastname + "]: Connected");
+                    numbots++;
+                    break;
+                case EventType.DISCONNECTED:
+                    m_log.Info("[ " + callbot.firstname + " " + callbot.lastname + "]: Disconnected");
+                    m_td[m_lBot.IndexOf(callbot)].Abort();
+                    numbots--;
+                    if (numbots >1)
+                        Environment.Exit(0);
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Shutting down all bots
+        /// </summary>
+        public void doBotShutdown()
+        {
+            foreach (PhysicsBot pb in m_lBot)
+            {
+                pb.shutdown();
+            }
+        }
+
+        /// <summary>
+        /// Standard CreateConsole routine
+        /// </summary>
+        /// <returns></returns>
+        protected ConsoleBase CreateConsole()
+        {
+            return new ConsoleBase("Region", this);
+        }
+
+        /// <summary>
+        /// I don't think the bots use this..     
+        /// </summary>
+        /// <param name="commandParams"></param>
+        /// <param name="pos"></param>
+        /// <returns></returns>
+        private string CombineParams(string[] commandParams, int pos)
+        {
+            string result = String.Empty;
+            for (int i = pos; i < commandParams.Length; i++)
+            {
+                result += commandParams[i] + " ";
+            }
+            result = result.TrimEnd(' ');
+            return result;
+        }
+        
+        /// <summary>
+        /// Command runnint tool..  Currently use it to add bots, shutdown and (dangerous)Forcequit
+        /// </summary>
+        /// <param name="command"></param>
+        /// <param name="cmdparams"></param>
+        public void RunCmd(string command, string[] cmdparams)
+        {
+            switch (command)
+            {
+                case "shutdown":
+                    m_console.Warn("BOTMANAGER", "Shutting down bots");
+                    doBotShutdown();
+                    break;
+                case "quit":
+                    m_console.Warn("DANGER", "This should only be used to quit the program if you've already used the shutdown command and the program hasn't quit");
+                    Environment.Exit(0);
+                    break;
+                case "addbots":
+                    int newbots = 0;
+                    Helpers.TryParse(cmdparams[0], out newbots);
+                    
+                    if (newbots > 0)
+                        addbots(newbots);
+                    break;
+                case "help":
+                    m_console.Notice("HELP", "\nshutdown - graceful shutdown\naddbots <n> - adds n bots to the test\nquit - forcequits, dangerous if you have not already run shutdown");
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Required method to implement the conscmd_callback interface
+        /// </summary>
+        /// <param name="ShowWhat"></param>
+        public void Show(string ShowWhat)
+        {
+        }
+    }
+}
diff --git a/OpenSim/TestSuite/PhysicsBot.cs b/OpenSim/TestSuite/PhysicsBot.cs
new file mode 100644
index 0000000..3e12bb1
--- /dev/null
+++ b/OpenSim/TestSuite/PhysicsBot.cs
@@ -0,0 +1,203 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above copyright
+*       notice, this list of conditions and the following disclaimer in the
+*       documentation and/or other materials provided with the distribution.
+*     * Neither the name of the OpenSim Project nor the
+*       names of its contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* 
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using libsecondlife;
+using libsecondlife.Packets;
+using Nini.Config;
+using System.Threading;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using Timer = System.Timers.Timer;
+
+namespace pCampBot
+{
+    public class PhysicsBot
+    {
+        public delegate void AnEvent(PhysicsBot callbot, EventType someevent); // event delegate for bot events
+        public IConfig startupConfig; // bot config, passed from BotManager
+
+        public string firstname;
+        public string lastname;
+        public string password;
+        public string loginURI;
+
+        public event AnEvent OnConnected;
+        public event AnEvent OnDisconnected;
+
+        protected Timer m_action; // Action Timer
+
+        protected Random somthing = new Random(System.Environment.TickCount);// We do stuff randomly here
+
+        private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+        
+        //New instance of a SecondLife client
+        public SecondLife client = new SecondLife();
+
+        protected string[] talkarray;
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="bsconfig">nini config for the bot</param>
+        public PhysicsBot(IConfig bsconfig)
+        {
+            startupConfig = bsconfig;
+            readconfig();
+            talkarray = readexcuses();
+        }
+
+        //We do our actions here.  This is where one would 
+        //add additional steps and/or things the bot should do
+
+        void m_action_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
+        {
+            //client.Throttle.Task = 500000f;
+            //client.Throttle.Set();
+            int walkorrun = somthing.Next(4); // Randomize between walking and running. The greater this number,
+                                              // the greater the bot's chances to walk instead of run.
+            if (walkorrun == 0)
+            {
+                client.Self.Movement.AlwaysRun = true;
+            }
+            else
+            {
+                client.Self.Movement.AlwaysRun = false;
+            }
+
+            LLVector3 pos = client.Self.SimPosition;
+            LLVector3 newpos = new LLVector3(somthing.Next(255), somthing.Next(255), somthing.Next(255));
+            client.Self.Movement.TurnToward(newpos);
+
+            for (int i = 0; i < 2000; i++)
+            {
+                client.Self.Movement.AtPos = true;
+                Thread.Sleep(somthing.Next(25, 75)); // Makes sure the bots keep walking for this time.
+            }
+            client.Self.Jump();
+
+            string randomf = talkarray[somthing.Next(talkarray.Length)];
+            if (talkarray.Length > 1 && randomf.Length > 1)
+                client.Self.Chat(randomf, 0, ChatType.Normal);
+
+            //Thread.Sleep(somthing.Next(1, 10)); // Apparently its better without it right now.
+
+        }
+
+        /// <summary>
+        /// Read the Nini config and initialize
+        /// </summary>
+        public void readconfig()
+        {
+            firstname = startupConfig.GetString("firstname", "random");
+            lastname = startupConfig.GetString("lastname", "random");
+            password = startupConfig.GetString("password", "12345");
+            loginURI = startupConfig.GetString("loginuri");
+
+
+
+        }
+
+        /// <summary>
+        /// Tells LibSecondLife to logout and disconnect.  Raises the disconnect events once it finishes.
+        /// </summary>
+        public void shutdown()
+        {
+            client.Network.Logout();
+        }
+
+        /// <summary>
+        /// This is the bot startup loop.
+        /// </summary>
+        public void startup()
+        {
+            client.Settings.LOGIN_SERVER = loginURI;
+            client.Network.OnConnected += new NetworkManager.ConnectedCallback(this.Network_OnConnected);
+            client.Network.OnSimConnected += new NetworkManager.SimConnectedCallback(this.Network_OnConnected);
+            client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(this.Network_OnDisconnected);
+            if (client.Network.Login(firstname, lastname, password, "pCampBot", "Your name"))
+            {
+
+                if (OnConnected != null)
+                {
+                    m_action = new Timer(somthing.Next(1000, 10000));
+                    m_action.Elapsed += new System.Timers.ElapsedEventHandler(m_action_Elapsed);
+                    m_action.Start();
+                    OnConnected(this, EventType.CONNECTED);
+                    client.Self.Jump();
+
+                }
+            }
+            else
+            {
+                MainConsole.Instance.Error(firstname + " " + lastname, "Can't login: " + client.Network.LoginMessage);
+                if (OnDisconnected != null)
+                {
+                    OnDisconnected(this, EventType.DISCONNECTED);
+                }
+            }
+        }
+
+        public void Network_OnConnected(object sender)
+        {
+            if (OnConnected != null)
+            {
+                OnConnected(this, EventType.CONNECTED);
+            }
+        }
+
+        public void Simulator_Connected(object sender)
+        {
+        }
+
+        public void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message)
+        {
+            if (OnDisconnected != null)
+            {
+                OnDisconnected(this, EventType.DISCONNECTED);
+            }
+        }
+
+        public string[] readexcuses()
+        {
+            string allexcuses = "";
+
+            string file = Path.Combine(Util.configDir(), "pCampBotSentences.txt");
+            if (File.Exists(file))
+            {
+                StreamReader csr = File.OpenText(file);
+                allexcuses = csr.ReadToEnd();
+                csr.Close();
+            }
+
+            return allexcuses.Split(Environment.NewLine.ToCharArray());
+        }
+    }
+}
diff --git a/OpenSim/TestSuite/pCampBot.cs b/OpenSim/TestSuite/pCampBot.cs
new file mode 100644
index 0000000..d42d4bd
--- /dev/null
+++ b/OpenSim/TestSuite/pCampBot.cs
@@ -0,0 +1,114 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above copyright
+*       notice, this list of conditions and the following disclaimer in the
+*       documentation and/or other materials provided with the distribution.
+*     * Neither the name of the OpenSim Project nor the
+*       names of its contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* 
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using libsecondlife;
+using libsecondlife.Packets;
+using Nini.Config;
+using log4net;
+using log4net.Config;
+using System.Threading;
+using OpenSim.Framework.Console;
+
+namespace pCampBot
+{
+    /// <summary>
+    /// Event Types from the BOT.  Add new events here
+    /// </summary>
+    public enum EventType:int
+    {
+        NONE = 0,
+        CONNECTED = 1,
+        DISCONNECTED = 2
+    }
+
+    public class pCampBot
+    {
+        
+        private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+        
+        [STAThread]
+        public static void Main(string[] args)
+        {
+            // log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+            // log4net call
+            // BasicConfigurator.Configure();
+
+            IConfig config = ParseConfig(args);
+            if (config.Get("help") != null || config.Get("loginuri") == null) {
+                Help();
+            } else {
+                int botcount = config.GetInt("botcount", 1);
+                
+                BotManager bm = new BotManager();
+                
+                System.Console.WriteLine("Error enabled: {0}", m_log.IsErrorEnabled);
+                //startup specified number of bots.  1 is the default
+                m_log.Error("pCampBot started with " + botcount + "bots");
+
+//                 bm.dobotStartup(botcount, config);
+//                 while (true)
+//                 {
+//                     MainConsole.Instance.Prompt();
+//                 }
+            }
+        }
+
+        private static IConfig ParseConfig(String[] args)
+        {
+            //Set up our nifty config..  thanks to nini
+            ArgvConfigSource cs = new ArgvConfigSource(args);
+            
+            cs.AddSwitch("Startup", "botcount","n");
+            cs.AddSwitch("Startup", "loginuri","l");
+            cs.AddSwitch("Startup", "firstname");
+            cs.AddSwitch("Startup", "lastname");
+            cs.AddSwitch("Startup", "password");
+            cs.AddSwitch("Startup", "help","h");
+            
+            IConfig ol = cs.Configs["Startup"];
+            return ol;
+        }
+        
+        private static void Help()
+        {
+            System.Console.WriteLine(
+                                     "usage: pCampBot <-loginuri loginuri> [OPTIONS]\n" +
+                                     "Spawns a set of bots to test an OpenSim region\n\n" +
+                                     "  -l, -loginuri      loginuri for sim to log into (required)\n" +
+                                     "  -n, -botcount      number of bots to start (default: 1)\n" +
+                                     "  -firstname         first name for the bot(s) (default: random string)\n" +
+                                     "  -lastname          lastname for the bot(s) (default: random string)\n" +
+                                     "  -password          password for the bots(s) (default: random string)\n" +
+                                     "  -h, -help          show this message"
+                                     );
+        }
+    }
+}
-- 
cgit v1.1