diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index be7a5a1a49..f7af26e3c8 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -158,8 +158,6 @@ namespace pCampBot behaviours.ForEach(b => b.Initialize(this)); - Client = new GridClient(); - Random = new Random(Environment.TickCount);// We do stuff randomly here FirstName = firstName; LastName = lastName; @@ -170,6 +168,59 @@ namespace pCampBot Manager = bm; Behaviours = behaviours; + + // Only calling for use as a template. + CreateLibOmvClient(); + } + + private void CreateLibOmvClient() + { + GridClient newClient = new GridClient(); + + if (Client != null) + { + newClient.Settings.LOGIN_SERVER = Client.Settings.LOGIN_SERVER; + newClient.Settings.ALWAYS_DECODE_OBJECTS = Client.Settings.ALWAYS_DECODE_OBJECTS; + newClient.Settings.AVATAR_TRACKING = Client.Settings.AVATAR_TRACKING; + newClient.Settings.OBJECT_TRACKING = Client.Settings.OBJECT_TRACKING; + newClient.Settings.SEND_AGENT_THROTTLE = Client.Settings.SEND_AGENT_THROTTLE; + newClient.Settings.SEND_AGENT_UPDATES = Client.Settings.SEND_AGENT_UPDATES; + newClient.Settings.SEND_PINGS = Client.Settings.SEND_PINGS; + newClient.Settings.STORE_LAND_PATCHES = Client.Settings.STORE_LAND_PATCHES; + newClient.Settings.USE_ASSET_CACHE = Client.Settings.USE_ASSET_CACHE; + newClient.Settings.MULTIPLE_SIMS = Client.Settings.MULTIPLE_SIMS; + newClient.Throttle.Asset = Client.Throttle.Asset; + newClient.Throttle.Land = Client.Throttle.Land; + newClient.Throttle.Task = Client.Throttle.Task; + newClient.Throttle.Texture = Client.Throttle.Texture; + newClient.Throttle.Wind = Client.Throttle.Wind; + newClient.Throttle.Total = Client.Throttle.Total; + } + else + { + newClient.Settings.LOGIN_SERVER = LoginUri; + newClient.Settings.ALWAYS_DECODE_OBJECTS = false; + newClient.Settings.AVATAR_TRACKING = false; + newClient.Settings.OBJECT_TRACKING = false; + newClient.Settings.SEND_AGENT_THROTTLE = true; + newClient.Settings.SEND_PINGS = true; + newClient.Settings.STORE_LAND_PATCHES = false; + newClient.Settings.USE_ASSET_CACHE = false; + newClient.Settings.MULTIPLE_SIMS = true; + newClient.Throttle.Asset = 100000; + newClient.Throttle.Land = 100000; + newClient.Throttle.Task = 100000; + newClient.Throttle.Texture = 100000; + newClient.Throttle.Wind = 100000; + newClient.Throttle.Total = 400000; + } + + newClient.Network.LoginProgress += this.Network_LoginProgress; + newClient.Network.SimConnected += this.Network_SimConnected; + newClient.Network.Disconnected += this.Network_OnDisconnected; + newClient.Objects.ObjectUpdate += Objects_NewPrim; + + Client = newClient; } //We do our actions here. This is where one would @@ -192,7 +243,7 @@ namespace pCampBot /// /// Tells LibSecondLife to logout and disconnect. Raises the disconnect events once it finishes. /// - public void shutdown() + public void Disconnect() { ConnectionState = ConnectionState.Disconnecting; @@ -202,34 +253,27 @@ namespace pCampBot Client.Network.Logout(); } + public void Connect() + { + Thread connectThread = new Thread(ConnectInternal); + connectThread.Name = Name; + connectThread.IsBackground = true; + + connectThread.Start(); + } + /// /// This is the bot startup loop. /// - public void startup() + private void ConnectInternal() { - Client.Settings.LOGIN_SERVER = LoginUri; - Client.Settings.ALWAYS_DECODE_OBJECTS = false; - 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; - Client.Settings.MULTIPLE_SIMS = true; - Client.Throttle.Asset = 100000; - Client.Throttle.Land = 100000; - Client.Throttle.Task = 100000; - Client.Throttle.Texture = 100000; - Client.Throttle.Wind = 100000; - Client.Throttle.Total = 400000; - Client.Network.LoginProgress += this.Network_LoginProgress; - Client.Network.SimConnected += this.Network_SimConnected; - Client.Network.Disconnected += this.Network_OnDisconnected; - Client.Objects.ObjectUpdate += Objects_NewPrim; - ConnectionState = ConnectionState.Connecting; + // Current create a new client on each connect. libomv doesn't seem to process new sim + // information (e.g. EstablishAgentCommunication events) if connecting after a disceonnect with the same + // client + CreateLibOmvClient(); + if (Client.Network.Login(FirstName, LastName, Password, "pCampBot", StartLocation, "Your name")) { ConnectionState = ConnectionState.Connected; @@ -474,6 +518,8 @@ namespace pCampBot // || args.Reason == NetworkManager.DisconnectType.NetworkTimeout) // && OnDisconnected != null) + + if ( (args.Reason == NetworkManager.DisconnectType.ClientInitiated || args.Reason == NetworkManager.DisconnectType.ServerInitiated diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index fe6048a508..f40a84d4ad 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -181,6 +181,12 @@ namespace pCampBot m_console.Commands.AddCommand( "bot", false, "quit", "quit", "Shutdown bots and exit", HandleShutdown); + m_console.Commands.AddCommand( + "bot", false, "connect", "connect []", "Connect bots", + "If an is given, then the first disconnected bots by postfix number are connected.\n" + + "If no is given, then all currently disconnected bots are connected.", + HandleConnect); + m_console.Commands.AddCommand( "bot", false, "disconnect", "disconnect []", "Disconnect bots", "Disconnecting bots will interupt any bot connection process, including connection on startup.\n" @@ -206,7 +212,7 @@ namespace pCampBot /// /// How many bots to start up /// The configuration for the bots to use - public void dobotStartup(int botcount, IConfig startupConfig) + public void CreateBots(int botcount, IConfig startupConfig) { m_firstName = startupConfig.GetString("firstname"); m_lastNameStem = startupConfig.GetString("lastname"); @@ -220,39 +226,55 @@ namespace pCampBot Array.ForEach( startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b)); - ConnectBots( - botcount, m_firstName, m_lastNameStem, m_password, m_loginUri, m_startUri, m_fromBotNumber, m_wearSetting, m_behaviourSwitches); + for (int i = 0; i < botcount; i++) + { + lock (m_bots) + { + string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); + + // We must give each bot its own list of instantiated behaviours since they store state. + List behaviours = new List(); + + // Hard-coded for now + if (m_behaviourSwitches.Contains("c")) + behaviours.Add(new CrossBehaviour()); + + if (m_behaviourSwitches.Contains("g")) + behaviours.Add(new GrabbingBehaviour()); + + if (m_behaviourSwitches.Contains("n")) + behaviours.Add(new NoneBehaviour()); + + if (m_behaviourSwitches.Contains("p")) + behaviours.Add(new PhysicsBehaviour()); + + if (m_behaviourSwitches.Contains("t")) + behaviours.Add(new TeleportBehaviour()); + + CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); + } + } } - private bool ConnectBots( - int botcount, string firstName, string lastNameStem, string password, string loginUri, string startUri, int fromBotNumber, string wearSetting, - HashSet behaviourSwitches) + public void ConnectBots(int botcount) { ConnectingBots = true; - Thread startBotThread - = new Thread( - o => ConnectBotsInternal( - botcount, firstName, lastNameStem, password, loginUri, startUri, fromBotNumber, wearSetting, - behaviourSwitches)); + Thread connectBotThread = new Thread(o => ConnectBotsInternal(botcount)); - startBotThread.Name = "Bots connection thread"; - startBotThread.Start(); - - return true; + connectBotThread.Name = "Bots connection thread"; + connectBotThread.Start(); } - private void ConnectBotsInternal( - int botcount, string firstName, string lastNameStem, string password, string loginUri, string startUri, int fromBotNumber, string wearSetting, - HashSet behaviourSwitches) + private void ConnectBotsInternal(int botcount) { MainConsole.Instance.OutputFormat( "[BOT MANAGER]: Starting {0} bots connecting to {1}, location {2}, named {3} {4}_", botcount, - loginUri, - startUri, - firstName, - lastNameStem); + m_loginUri, + m_startUri, + m_firstName, + m_lastNameStem); MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay); MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", InitBotSendAgentUpdates); @@ -269,28 +291,7 @@ namespace pCampBot 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. - List behaviours = new List(); - - // Hard-coded for now - if (behaviourSwitches.Contains("c")) - behaviours.Add(new CrossBehaviour()); - - if (behaviourSwitches.Contains("g")) - behaviours.Add(new GrabbingBehaviour()); - - if (behaviourSwitches.Contains("n")) - behaviours.Add(new NoneBehaviour()); - - if (behaviourSwitches.Contains("p")) - behaviours.Add(new PhysicsBehaviour()); - - if (behaviourSwitches.Contains("t")) - behaviours.Add(new TeleportBehaviour()); - - StartBot(this, behaviours, firstName, lastName, password, loginUri, startUri, wearSetting); + m_bots[i].Connect(); } // Stagger logins @@ -360,7 +361,7 @@ namespace pCampBot // } /// - /// This starts up the bot and stores the thread for the bot in the thread array + /// This creates a bot but does not start it. /// /// /// Behaviours for this bot to perform. @@ -370,12 +371,12 @@ namespace pCampBot /// Login URI /// Location to start the bot. Can be "last", "home" or a specific sim name. /// - public void StartBot( + public void CreateBot( BotManager bm, List behaviours, string firstName, string lastName, string password, string loginUri, string startLocation, string wearSetting) { MainConsole.Instance.OutputFormat( - "[BOT MANAGER]: Starting bot {0} {1}, behaviours are {2}", + "[BOT MANAGER]: Creating 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, startLocation, loginUri); @@ -387,12 +388,6 @@ namespace pCampBot pb.OnDisconnected += handlebotEvent; m_bots.Add(pb); - - Thread pbThread = new Thread(pb.startup); - pbThread.Name = pb.Name; - pbThread.IsBackground = true; - - pbThread.Start(); } /// @@ -427,6 +422,37 @@ namespace pCampBot return new LocalConsole("pCampbot"); } + private void HandleConnect(string module, string[] cmd) + { + if (ConnectingBots) + { + MainConsole.Instance.Output("Still connecting bots. Please wait for previous process to complete."); + return; + } + + lock (m_bots) + { + int botsToConnect; + int disconnectedBots = m_bots.Count(b => b.ConnectionState == ConnectionState.Disconnected); + + if (cmd.Length == 1) + { + botsToConnect = disconnectedBots; + } + else + { + if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[1], out botsToConnect)) + return; + + botsToConnect = Math.Min(botsToConnect, disconnectedBots); + } + + MainConsole.Instance.OutputFormat("Connecting {0} bots", botsToConnect); + + ConnectBots(botsToConnect); + } + } + private void HandleDisconnect(string module, string[] cmd) { lock (m_bots) @@ -461,10 +487,12 @@ namespace pCampBot if (thisBot.ConnectionState == ConnectionState.Connected) { - Util.FireAndForget(o => thisBot.shutdown()); + Util.FireAndForget(o => thisBot.Disconnect()); disconnectedBots++; } } + + DisconnectingBots = false; } } diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index e58b130212..ada39eeea3 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -95,7 +95,8 @@ namespace pCampBot int botcount = commandLineConfig.GetInt("botcount", 1); - bm.dobotStartup(botcount, commandLineConfig); + bm.CreateBots(botcount, commandLineConfig); + bm.ConnectBots(botcount); while (true) {