From 5933f9448d839b9f6db391dedc493bb5cc951d66 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 13 Aug 2013 23:54:50 +0100 Subject: [PATCH 1/8] Add a SendAgentUpdates setting to a new pCampbot.ini.example file which can control whether bots send agent updates pCampbot.ini.example is used by copying to pCampbot.ini, like other ini files --- OpenSim/Tools/pCampBot/Bot.cs | 20 +--------------- OpenSim/Tools/pCampBot/BotManager.cs | 35 ++++++++++++++++------------ OpenSim/Tools/pCampBot/pCampBot.cs | 35 +++++++++++++++++++++++----- bin/pCampbot.ini.example | 9 +++++++ 4 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 bin/pCampbot.ini.example diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 9821180bc6..c56d29b975 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -63,11 +63,6 @@ namespace pCampBot /// public BotManager Manager { get; private set; } - /// - /// Bot config, passed from BotManager. - /// - private IConfig startupConfig; - /// /// Behaviours implemented by this bot. /// @@ -153,9 +148,6 @@ namespace pCampBot LoginUri = loginUri; Manager = bm; - startupConfig = bm.Config; - readconfig(); - Behaviours = behaviours; } @@ -176,14 +168,6 @@ namespace pCampBot ); } - /// - /// Read the Nini config and initialize - /// - public void readconfig() - { - wear = startupConfig.GetString("wear", "no"); - } - /// /// Tells LibSecondLife to logout and disconnect. Raises the disconnect events once it finishes. /// @@ -207,6 +191,7 @@ namespace pCampBot Client.Settings.AVATAR_TRACKING = false; Client.Settings.OBJECT_TRACKING = false; Client.Settings.SEND_AGENT_THROTTLE = true; + Client.Settings.SEND_AGENT_UPDATES = false; Client.Settings.SEND_PINGS = true; Client.Settings.STORE_LAND_PATCHES = false; Client.Settings.USE_ASSET_CACHE = false; @@ -481,9 +466,6 @@ namespace pCampBot public void Objects_NewPrim(object sender, PrimEventArgs args) { -// if (Name.EndsWith("4")) -// throw new Exception("Aaargh"); - Primitive prim = args.Prim; if (prim != null) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 74bd36a9a9..16b02b9c1b 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -62,6 +62,11 @@ namespace pCampBot /// protected CommandConsole m_console; + /// + /// Controls whether bots start out sending agent updates on connection. + /// + public bool BotsInitSendAgentUpdates { get; set; } + /// /// Created bots, whether active or inactive. /// @@ -72,11 +77,6 @@ namespace pCampBot /// public Random Rng { get; private set; } - /// - /// Overall configuration. - /// - public IConfig Config { get; private set; } - /// /// Track the assets we have and have not received so we don't endlessly repeat requests. /// @@ -92,6 +92,8 @@ namespace pCampBot /// public BotManager() { + BotsInitSendAgentUpdates = true; + LoginDelay = DefaultLoginDelay; Rng = new Random(Environment.TickCount); @@ -148,18 +150,17 @@ namespace pCampBot /// /// How many bots to start up /// The configuration for the bots to use - public void dobotStartup(int botcount, IConfig cs) + public void dobotStartup(int botcount, IConfig startupConfig) { - Config = cs; - - string firstName = cs.GetString("firstname"); - string lastNameStem = cs.GetString("lastname"); - string password = cs.GetString("password"); - string loginUri = cs.GetString("loginuri"); + string firstName = startupConfig.GetString("firstname"); + string lastNameStem = startupConfig.GetString("lastname"); + string password = startupConfig.GetString("password"); + string loginUri = startupConfig.GetString("loginuri"); + string wearSetting = startupConfig.GetString("wear", "no"); HashSet behaviourSwitches = new HashSet(); Array.ForEach( - cs.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); + startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); MainConsole.Instance.OutputFormat( "[BOT MANAGER]: Starting {0} bots connecting to {1}, named {2} {3}_", @@ -169,6 +170,7 @@ namespace pCampBot lastNameStem); MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay); + MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", BotsInitSendAgentUpdates); for (int i = 0; i < botcount; i++) { @@ -193,7 +195,7 @@ namespace pCampBot if (behaviourSwitches.Contains("t")) behaviours.Add(new TeleportBehaviour()); - StartBot(this, behaviours, firstName, lastName, password, loginUri); + StartBot(this, behaviours, firstName, lastName, password, loginUri, wearSetting); } } @@ -226,15 +228,18 @@ namespace pCampBot /// Last name /// Password /// Login URI + /// public void StartBot( BotManager bm, List behaviours, - string firstName, string lastName, string password, string loginUri) + string firstName, string lastName, string password, string loginUri, string wearSetting) { MainConsole.Instance.OutputFormat( "[BOT MANAGER]: Starting bot {0} {1}, behaviours are {2}", firstName, lastName, string.Join(",", behaviours.ConvertAll(b => b.Name).ToArray())); Bot pb = new Bot(bm, behaviours, firstName, lastName, password, loginUri); + pb.wear = wearSetting; + pb.Client.Settings.SEND_AGENT_UPDATES = BotsInitSendAgentUpdates; pb.OnConnected += handlebotEvent; pb.OnDisconnected += handlebotEvent; diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index 2707a49f7d..e43037d9cb 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -26,6 +26,7 @@ */ using System; +using System.IO; using System.Reflection; using System.Threading; using log4net; @@ -50,28 +51,50 @@ namespace pCampBot { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public const string ConfigFileName = "pCampbot.ini"; + [STAThread] public static void Main(string[] args) { XmlConfigurator.Configure(); - IConfig config = ParseConfig(args); - if (config.Get("help") != null || config.Get("loginuri") == null) + IConfig commandLineConfig = ParseConfig(args); + if (commandLineConfig.Get("help") != null || commandLineConfig.Get("loginuri") == null) { Help(); } - else if (config.Get("firstname") == null || config.Get("lastname") == null || config.Get("password") == null) + else if ( + commandLineConfig.Get("firstname") == null + || commandLineConfig.Get("lastname") == null + || commandLineConfig.Get("password") == null) { Console.WriteLine("ERROR: You must supply a firstname, lastname and password for the bots."); } else { - int botcount = config.GetInt("botcount", 1); - BotManager bm = new BotManager(); + string iniFilePath = Path.GetFullPath(Path.Combine(Util.configDir(), ConfigFileName)); + + if (File.Exists(iniFilePath)) + { + m_log.InfoFormat("[PCAMPBOT]: Reading configuration settings from {0}", iniFilePath); + + IConfigSource configSource = new IniConfigSource(iniFilePath); + + IConfig botConfig = configSource.Configs["Bot"]; + + if (botConfig != null) + { + bm.BotsInitSendAgentUpdates + = botConfig.GetBoolean("SendAgentUpdates", bm.BotsInitSendAgentUpdates); + } + } + + int botcount = commandLineConfig.GetInt("botcount", 1); + //startup specified number of bots. 1 is the default - Thread startBotThread = new Thread(o => bm.dobotStartup(botcount, config)); + Thread startBotThread = new Thread(o => bm.dobotStartup(botcount, commandLineConfig)); startBotThread.Name = "Initial start bots thread"; startBotThread.Start(); diff --git a/bin/pCampbot.ini.example b/bin/pCampbot.ini.example new file mode 100644 index 0000000000..81cdcf4b1d --- /dev/null +++ b/bin/pCampbot.ini.example @@ -0,0 +1,9 @@ +; This is the example config file for pCampbot +; To use it, copy this file to pCampbot.ini and change settings if required + +[Bot] + ; Control whether bots should regularly send agent updates + ; Not sending agent updates will reduce CPU requirements for pCampbot but greatly + ; reduce the realism compared to viewers which are constantly sending AgentUpdates UDP packets + ; Defaults to true. + SendAgentUpdates = true From 0feb5da31e0986d46ea06ffb9804cf30f700e119 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 13 Aug 2013 21:06:24 -0700 Subject: [PATCH 2/8] BulletSim: move the creation of the avatar movement actor creating to taint time. Attempt to fix a problem of teleporting within the same region where the remove and addition of the physical avatar occasionally ends up with a non-moving avatar. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index d584782e74..502f85f02b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -89,13 +89,6 @@ public sealed class BSCharacter : BSPhysObject // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); - // The avatar's movement is controlled by this motor that speeds up and slows down - // the avatar seeking to reach the motor's target speed. - // This motor runs as a prestep action for the avatar so it will keep the avatar - // standing as well as moving. Destruction of the avatar will destroy the pre-step action. - m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName); - PhysicalActors.Add(AvatarMoveActorName, m_moveActor); - DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6}", LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); @@ -106,6 +99,13 @@ public sealed class BSCharacter : BSPhysObject // New body and shape into PhysBody and PhysShape PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this); + // The avatar's movement is controlled by this motor that speeds up and slows down + // the avatar seeking to reach the motor's target speed. + // This motor runs as a prestep action for the avatar so it will keep the avatar + // standing as well as moving. Destruction of the avatar will destroy the pre-step action. + m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName); + PhysicalActors.Add(AvatarMoveActorName, m_moveActor); + SetPhysicalProperties(); }); return; From 2146b201694a128764e66680d151b68d83610880 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Aug 2013 16:51:51 +0100 Subject: [PATCH 3/8] Add the ability to explicitly specify a login start location to pCampbot via the -start parameter --- OpenSim/Tools/pCampBot/Bot.cs | 7 +++- OpenSim/Tools/pCampBot/BotManager.cs | 60 ++++++++++++++++++++++++---- OpenSim/Tools/pCampBot/pCampBot.cs | 36 +++++++++-------- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index c56d29b975..79344e89de 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -97,6 +97,8 @@ namespace pCampBot public string Name { get; private set; } public string Password { get; private set; } public string LoginUri { get; private set; } + public string StartLocation { get; private set; } + public string saveDir; public string wear; @@ -132,7 +134,7 @@ namespace pCampBot /// public Bot( BotManager bm, List behaviours, - string firstName, string lastName, string password, string loginUri) + string firstName, string lastName, string password, string startLocation, string loginUri) { ConnectionState = ConnectionState.Disconnected; @@ -146,6 +148,7 @@ namespace pCampBot Name = string.Format("{0} {1}", FirstName, LastName); Password = password; LoginUri = loginUri; + StartLocation = startLocation; Manager = bm; Behaviours = behaviours; @@ -209,7 +212,7 @@ namespace pCampBot ConnectionState = ConnectionState.Connecting; - if (Client.Network.Login(FirstName, LastName, Password, "pCampBot", "Your name")) + if (Client.Network.Login(FirstName, LastName, Password, "pCampBot", StartLocation, "Your name")) { ConnectionState = ConnectionState.Connected; diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 16b02b9c1b..57bd737527 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -65,7 +65,7 @@ namespace pCampBot /// /// Controls whether bots start out sending agent updates on connection. /// - public bool BotsInitSendAgentUpdates { get; set; } + public bool InitBotSendAgentUpdates { get; set; } /// /// Created bots, whether active or inactive. @@ -92,7 +92,7 @@ namespace pCampBot /// public BotManager() { - BotsInitSendAgentUpdates = true; + InitBotSendAgentUpdates = true; LoginDelay = DefaultLoginDelay; @@ -156,21 +156,25 @@ namespace pCampBot string lastNameStem = startupConfig.GetString("lastname"); string password = startupConfig.GetString("password"); string loginUri = startupConfig.GetString("loginuri"); + string startLocation = startupConfig.GetString("start", "last"); string wearSetting = startupConfig.GetString("wear", "no"); + string startUri = ParseInputStartLocationToUri(startLocation); + HashSet behaviourSwitches = new HashSet(); Array.ForEach( startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); MainConsole.Instance.OutputFormat( - "[BOT MANAGER]: Starting {0} bots connecting to {1}, named {2} {3}_", + "[BOT MANAGER]: Starting {0} bots connecting to {1}, location {2}, named {3} {4}_", botcount, loginUri, + startUri, firstName, lastNameStem); MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay); - MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", BotsInitSendAgentUpdates); + MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", InitBotSendAgentUpdates); for (int i = 0; i < botcount; i++) { @@ -195,10 +199,49 @@ namespace pCampBot if (behaviourSwitches.Contains("t")) behaviours.Add(new TeleportBehaviour()); - StartBot(this, behaviours, firstName, lastName, password, loginUri, wearSetting); + StartBot(this, behaviours, firstName, lastName, password, loginUri, startUri, wearSetting); } } + /// + /// Parses the command line start location to a start string/uri that the login mechanism will recognize. + /// + /// + /// The input start location to URI. + /// + /// + /// Start location. + /// + private string ParseInputStartLocationToUri(string startLocation) + { + if (startLocation == "home" || startLocation == "last") + return startLocation; + + string regionName; + + // Just a region name or only one (!) extra component. Like a viewer, we will stick 128/128/0 on the end + Vector3 startPos = new Vector3(128, 128, 0); + + string[] startLocationComponents = startLocation.Split('/'); + + regionName = startLocationComponents[0]; + + if (startLocationComponents.Length >= 2) + { + float.TryParse(startLocationComponents[1], out startPos.X); + + if (startLocationComponents.Length >= 3) + { + float.TryParse(startLocationComponents[2], out startPos.Y); + + if (startLocationComponents.Length >= 4) + float.TryParse(startLocationComponents[3], out startPos.Z); + } + } + + return string.Format("uri:{0}&{1}&{2}&{3}", regionName, startPos.X, startPos.Y, startPos.Z); + } + // /// // /// Add additional bots (and threads) to our bot pool // /// @@ -228,18 +271,19 @@ namespace pCampBot /// Last name /// Password /// Login URI + /// Location to start the bot. Can be "last", "home" or a specific sim name. /// public void StartBot( BotManager bm, List behaviours, - string firstName, string lastName, string password, string loginUri, string wearSetting) + string firstName, string lastName, string password, string loginUri, string startLocation, string wearSetting) { MainConsole.Instance.OutputFormat( "[BOT MANAGER]: Starting bot {0} {1}, behaviours are {2}", firstName, lastName, string.Join(",", behaviours.ConvertAll(b => b.Name).ToArray())); - Bot pb = new Bot(bm, behaviours, firstName, lastName, password, loginUri); + Bot pb = new Bot(bm, behaviours, firstName, lastName, password, startLocation, loginUri); pb.wear = wearSetting; - pb.Client.Settings.SEND_AGENT_UPDATES = BotsInitSendAgentUpdates; + pb.Client.Settings.SEND_AGENT_UPDATES = InitBotSendAgentUpdates; pb.OnConnected += handlebotEvent; pb.OnDisconnected += handlebotEvent; diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index e43037d9cb..9c9ed3b232 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -86,8 +86,8 @@ namespace pCampBot if (botConfig != null) { - bm.BotsInitSendAgentUpdates - = botConfig.GetBoolean("SendAgentUpdates", bm.BotsInitSendAgentUpdates); + bm.InitBotSendAgentUpdates + = botConfig.GetBoolean("SendAgentUpdates", bm.InitBotSendAgentUpdates); } } @@ -119,6 +119,7 @@ namespace pCampBot cs.AddSwitch("Startup", "botcount", "n"); cs.AddSwitch("Startup", "loginuri", "l"); + cs.AddSwitch("Startup", "start", "s"); cs.AddSwitch("Startup", "firstname"); cs.AddSwitch("Startup", "lastname"); cs.AddSwitch("Startup", "password"); @@ -137,22 +138,23 @@ namespace pCampBot // name, to load an specific folder, or save, to save an avatar with some already existing wearables // worn to the folder MyAppearance/FirstName_LastName, and the load it. 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 bots\n" + - " -lastname lastname for the bots. Each lastname will have _ appended, e.g. Ima Bot_0\n" + - " -password password for the bots\n" + - " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" + - " current options are:\n" + - " p (physics - bots constantly move and jump around)\n" + - " g (grab - bots randomly click prims whether set clickable or not)\n" + - " n (none - bots do nothing)\n" + - " t (teleport - bots regularly teleport between regions on the grid)\n" + + "usage: pCampBot <-loginuri loginuri> [OPTIONS]\n" + + "Spawns a set of bots to test an OpenSim region\n\n" + + " -l, -loginuri loginuri for grid/standalone (required)\n" + + " -s, -start start location for bots. Can be \"last\", \"home\" or a specific location with or without co-ords (e.g. \"region1\" or \"region2/50/30/90\"\n" + + " -n, -botcount number of bots to start (default: 1)\n" + + " -firstname first name for the bots\n" + + " -lastname lastname for the bots. Each lastname will have _ appended, e.g. Ima Bot_0\n" + + " -password password for the bots\n" + + " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" + + " current options are:\n" + + " p (physics - bots constantly move and jump around)\n" + + " g (grab - bots randomly click prims whether set clickable or not)\n" + + " n (none - bots do nothing)\n" + + " t (teleport - bots regularly teleport between regions on the grid)\n" // " c (cross)" + - " -wear set appearance folder to load from (default: no)\n" + - " -h, -help show this message"); + + " -wear set appearance folder to load from (default: no)\n" + + " -h, -help show this message.\n"); } } } From 3a62f39044403e7bf453c7b5b1fe825a48e908f3 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Aug 2013 18:26:11 +0100 Subject: [PATCH 4/8] Add a -form switch to pCampbot to allow one to login a sequence of bots starting from numbers other than 0 --- OpenSim/Tools/pCampBot/BotManager.cs | 3 ++- OpenSim/Tools/pCampBot/pCampBot.cs | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 57bd737527..0fdfa0e050 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -157,6 +157,7 @@ namespace pCampBot string password = startupConfig.GetString("password"); string loginUri = startupConfig.GetString("loginuri"); string startLocation = startupConfig.GetString("start", "last"); + int fromBotNumber = startupConfig.GetInt("from", 0); string wearSetting = startupConfig.GetString("wear", "no"); string startUri = ParseInputStartLocationToUri(startLocation); @@ -178,7 +179,7 @@ namespace pCampBot for (int i = 0; i < botcount; i++) { - string lastName = string.Format("{0}_{1}", lastNameStem, i); + string lastName = string.Format("{0}_{1}", lastNameStem, i + fromBotNumber); // We must give each bot its own list of instantiated behaviours since they store state. List behaviours = new List(); diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index 9c9ed3b232..c8b6304cef 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -118,6 +118,7 @@ namespace pCampBot ArgvConfigSource cs = new ArgvConfigSource(args); cs.AddSwitch("Startup", "botcount", "n"); + cs.AddSwitch("Startup", "from", "f"); cs.AddSwitch("Startup", "loginuri", "l"); cs.AddSwitch("Startup", "start", "s"); cs.AddSwitch("Startup", "firstname"); @@ -137,15 +138,17 @@ namespace pCampBot // You can either say no, to not load anything, yes, to load one of the default wearables, a folder // name, to load an specific folder, or save, to save an avatar with some already existing wearables // worn to the folder MyAppearance/FirstName_LastName, and the load it. + Console.WriteLine( "usage: pCampBot <-loginuri loginuri> [OPTIONS]\n" + "Spawns a set of bots to test an OpenSim region\n\n" + " -l, -loginuri loginuri for grid/standalone (required)\n" - + " -s, -start start location for bots. Can be \"last\", \"home\" or a specific location with or without co-ords (e.g. \"region1\" or \"region2/50/30/90\"\n" - + " -n, -botcount number of bots to start (default: 1)\n" + + " -s, -start optional start location for bots. Can be \"last\", \"home\" or a specific location with or without co-ords (e.g. \"region1\" or \"region2/50/30/90\"\n" + " -firstname first name for the bots\n" + " -lastname lastname for the bots. Each lastname will have _ appended, e.g. Ima Bot_0\n" + " -password password for the bots\n" + + " -n, -botcount optional number of bots to start (default: 1)\n" + + " -f, -from optional starting number for login bot names, e.g. 25 will login Ima Bot_25, Ima Bot_26, etc. (default: 0)" + " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" + " current options are:\n" + " p (physics - bots constantly move and jump around)\n" @@ -153,7 +156,7 @@ namespace pCampBot + " n (none - bots do nothing)\n" + " t (teleport - bots regularly teleport between regions on the grid)\n" // " c (cross)" + - + " -wear set appearance folder to load from (default: no)\n" + + " -wear optional folder from which to load appearance data, \"no\" if there is no such folder (default: no)\n" + " -h, -help show this message.\n"); } } From 97c514daa5a3b4e4137bf01b7bee3fffc13a75d7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Aug 2013 19:21:07 +0100 Subject: [PATCH 5/8] Shutdown a bot's actions by making it check for disconnecting state rather than aborting the thread. Aborting the thread appears to be causing shutdown issues. --- OpenSim/Tools/pCampBot/Bot.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 79344e89de..dac8ccb49b 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -158,7 +158,7 @@ namespace pCampBot //add additional steps and/or things the bot should do private void Action() { - while (true) + while (ConnectionState != ConnectionState.Disconnecting) lock (Behaviours) Behaviours.ForEach( b => @@ -178,8 +178,8 @@ namespace pCampBot { ConnectionState = ConnectionState.Disconnecting; - if (m_actionThread != null) - m_actionThread.Abort(); +// if (m_actionThread != null) +// m_actionThread.Abort(); Client.Network.Logout(); } From fd519748e9c828e03468dc61b331115f07b3fadd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Aug 2013 19:35:02 +0100 Subject: [PATCH 6/8] Add method doc to Scene.RemoveClient() to ask any callers to use Scene.IncomingCloseAgent() instead. IncomingCloseAgent() now sets the scene presence state machine properly, which is necessary to avoid races between multiple sources of close. Hence, it's also necessary for everyone to consistently call IncomingCloseAgent() Calling RemoveClient() directly is currently generating an attention-grabbing exception though this right now this is harmless. --- OpenSim/Region/Framework/Scenes/Scene.cs | 12 ++++++++++++ OpenSim/Region/Framework/Scenes/SceneBase.cs | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a3bd388abc..d187377488 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3382,6 +3382,18 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Remove the given client from the scene. + /// + /// + /// Only clientstack code should call this directly. All other code should call IncomingCloseAgent() instead + /// to properly operate the state machine and avoid race conditions with other close requests (such as directly + /// from viewers). + /// + /// ID of agent to close + /// + /// Close the neighbour child agents associated with this client. + /// public override void RemoveClient(UUID agentID, bool closeChildAgents) { AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index d2097ea7ad..5252b9638a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -217,6 +217,19 @@ namespace OpenSim.Region.Framework.Scenes #region Add/Remove Agent/Avatar public abstract ISceneAgent AddNewClient(IClientAPI client, PresenceType type); + + /// + /// Remove the given client from the scene. + /// + /// + /// Only clientstack code should call this directly. All other code should call IncomingCloseAgent() instead + /// to properly operate the state machine and avoid race conditions with other close requests (such as directly + /// from viewers). + /// + /// ID of agent to close + /// + /// Close the neighbour child agents associated with this client. + /// public abstract void RemoveClient(UUID agentID, bool closeChildAgents); public bool TryGetScenePresence(UUID agentID, out object scenePresence) From 225cf0d0102d05721bd01120928b9d1d85c811a7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Aug 2013 19:53:10 +0100 Subject: [PATCH 7/8] Add pCampbot RequestObjectTextures ini setting to control whether textures are requested for received objects. --- OpenSim/Tools/pCampBot/BotManager.cs | 7 +++++++ OpenSim/Tools/pCampBot/pCampBot.cs | 2 ++ bin/pCampbot.ini.example | 10 ++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 0fdfa0e050..5988584f0a 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -67,6 +67,11 @@ namespace pCampBot /// public bool InitBotSendAgentUpdates { get; set; } + /// + /// Controls whether bots request textures for the object information they receive + /// + public bool InitBotRequestObjectTextures { get; set; } + /// /// Created bots, whether active or inactive. /// @@ -93,6 +98,7 @@ namespace pCampBot public BotManager() { InitBotSendAgentUpdates = true; + InitBotRequestObjectTextures = true; LoginDelay = DefaultLoginDelay; @@ -176,6 +182,7 @@ namespace pCampBot MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay); MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", InitBotSendAgentUpdates); + MainConsole.Instance.OutputFormat("[BOT MANAGER]: InitBotRequestObjectTextures is {0}", InitBotRequestObjectTextures); for (int i = 0; i < botcount; i++) { diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index c8b6304cef..b02f9170f9 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -88,6 +88,8 @@ namespace pCampBot { bm.InitBotSendAgentUpdates = botConfig.GetBoolean("SendAgentUpdates", bm.InitBotSendAgentUpdates); + bm.InitBotRequestObjectTextures + = botConfig.GetBoolean("RequestObjectTextures", bm.InitBotRequestObjectTextures); } } diff --git a/bin/pCampbot.ini.example b/bin/pCampbot.ini.example index 81cdcf4b1d..f44feaee1f 100644 --- a/bin/pCampbot.ini.example +++ b/bin/pCampbot.ini.example @@ -3,7 +3,13 @@ [Bot] ; Control whether bots should regularly send agent updates - ; Not sending agent updates will reduce CPU requirements for pCampbot but greatly - ; reduce the realism compared to viewers which are constantly sending AgentUpdates UDP packets + ; Not doing this will reduce CPU requirements for pCampbot but greatly + ; reduce the realism compared to viewers which are constantly sending AgentUpdates UDP packets. ; Defaults to true. SendAgentUpdates = true + + ; Control whether bots will requests textures when receiving object information + ; Not doing this will reduce CPU requirements for pCampbot but greatly + ; reduce the realism compared to viewers which requests such texture data if not already cached. + ; Defaults to true. + RequestObjectTextures = true From 2c67aa0f41193bf2271b75f060093f44819cdeae Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Aug 2013 21:07:29 +0100 Subject: [PATCH 8/8] If pCampbot has been asked to shutdown, don't carry on logging in queued bots --- OpenSim/Tools/pCampBot/BotManager.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 5988584f0a..397a98e37c 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -51,6 +51,11 @@ namespace pCampBot public const int DefaultLoginDelay = 5000; + /// + /// True if pCampbot is in the process of shutting down. + /// + public bool ShuttingDown { get; private set; } + /// /// Delay between logins of multiple bots. /// @@ -186,6 +191,9 @@ namespace pCampBot for (int i = 0; i < botcount; i++) { + if (ShuttingDown) + break; + string lastName = string.Format("{0}_{1}", lastNameStem, i + fromBotNumber); // We must give each bot its own list of instantiated behaviours since they store state. @@ -363,7 +371,9 @@ namespace pCampBot private void HandleShutdown(string module, string[] cmd) { - m_log.Info("[BOTMANAGER]: Shutting down bots"); + MainConsole.Instance.Output("Shutting down"); + + ShuttingDown = true; doBotShutdown(); }