aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Tools
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Tools')
-rw-r--r--OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs7
-rw-r--r--OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs6
-rw-r--r--OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs9
-rw-r--r--OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs6
-rw-r--r--OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs7
-rw-r--r--OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs9
-rw-r--r--OpenSim/Tools/pCampBot/Bot.cs77
-rw-r--r--OpenSim/Tools/pCampBot/BotManager.cs243
-rw-r--r--OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs13
9 files changed, 325 insertions, 52 deletions
diff --git a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs
index 9a9371d..9bc8512 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs
@@ -35,6 +35,11 @@ namespace pCampBot
35{ 35{
36 public class AbstractBehaviour : IBehaviour 36 public class AbstractBehaviour : IBehaviour
37 { 37 {
38 /// <summary>
39 /// Abbreviated name of this behaviour.
40 /// </summary>
41 public string AbbreviatedName { get; protected set; }
42
38 public string Name { get; protected set; } 43 public string Name { get; protected set; }
39 44
40 public Bot Bot { get; protected set; } 45 public Bot Bot { get; protected set; }
@@ -45,5 +50,7 @@ namespace pCampBot
45 { 50 {
46 Bot = bot; 51 Bot = bot;
47 } 52 }
53
54 public virtual void Close() {}
48 } 55 }
49} 56}
diff --git a/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs
index 1e01c64..4d806fc 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs
@@ -47,7 +47,11 @@ namespace pCampBot
47 47
48 public const int m_regionCrossingTimeout = 1000 * 60; 48 public const int m_regionCrossingTimeout = 1000 * 60;
49 49
50 public CrossBehaviour() { Name = "Cross"; } 50 public CrossBehaviour()
51 {
52 AbbreviatedName = "c";
53 Name = "Cross";
54 }
51 55
52 public override void Action() 56 public override void Action()
53 { 57 {
diff --git a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs
index 66a336a..59f6244 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs
@@ -29,6 +29,7 @@ using OpenMetaverse;
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq; 31using System.Linq;
32using System.Threading;
32using pCampBot.Interfaces; 33using pCampBot.Interfaces;
33 34
34namespace pCampBot 35namespace pCampBot
@@ -41,7 +42,11 @@ namespace pCampBot
41 /// </remarks> 42 /// </remarks>
42 public class GrabbingBehaviour : AbstractBehaviour 43 public class GrabbingBehaviour : AbstractBehaviour
43 { 44 {
44 public GrabbingBehaviour() { Name = "Grabbing"; } 45 public GrabbingBehaviour()
46 {
47 AbbreviatedName = "g";
48 Name = "Grabbing";
49 }
45 50
46 public override void Action() 51 public override void Action()
47 { 52 {
@@ -56,6 +61,8 @@ namespace pCampBot
56 Bot.Client.Self.Grab(prim.LocalID); 61 Bot.Client.Self.Grab(prim.LocalID);
57 Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero); 62 Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero);
58 Bot.Client.Self.DeGrab(prim.LocalID); 63 Bot.Client.Self.DeGrab(prim.LocalID);
64
65 Thread.Sleep(1000);
59 } 66 }
60 } 67 }
61} \ No newline at end of file 68} \ No newline at end of file
diff --git a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs
index 9cf8a54..9a3075c 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs
@@ -38,6 +38,10 @@ namespace pCampBot
38 /// </summary> 38 /// </summary>
39 public class NoneBehaviour : AbstractBehaviour 39 public class NoneBehaviour : AbstractBehaviour
40 { 40 {
41 public NoneBehaviour() { Name = "None"; } 41 public NoneBehaviour()
42 {
43 AbbreviatedName = "n";
44 Name = "None";
45 }
42 } 46 }
43} \ No newline at end of file 47} \ No newline at end of file
diff --git a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs
index daa7485..6fd2b7c 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs
@@ -46,6 +46,7 @@ namespace pCampBot
46 46
47 public PhysicsBehaviour() 47 public PhysicsBehaviour()
48 { 48 {
49 AbbreviatedName = "p";
49 Name = "Physics"; 50 Name = "Physics";
50 talkarray = readexcuses(); 51 talkarray = readexcuses();
51 } 52 }
@@ -77,6 +78,12 @@ namespace pCampBot
77 Bot.Client.Self.Chat(randomf, 0, ChatType.Normal); 78 Bot.Client.Self.Chat(randomf, 0, ChatType.Normal);
78 } 79 }
79 80
81 public override void Close()
82 {
83 if (Bot.ConnectionState == ConnectionState.Connected)
84 Bot.Client.Self.Jump(false);
85 }
86
80 private string[] readexcuses() 87 private string[] readexcuses()
81 { 88 {
82 string allexcuses = ""; 89 string allexcuses = "";
diff --git a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs
index fbb4e96..81f250d 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq; 30using System.Linq;
31using System.Reflection; 31using System.Reflection;
32using System.Threading;
32using log4net; 33using log4net;
33using OpenMetaverse; 34using OpenMetaverse;
34using pCampBot.Interfaces; 35using pCampBot.Interfaces;
@@ -42,7 +43,11 @@ namespace pCampBot
42 { 43 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 45
45 public TeleportBehaviour() { Name = "Teleport"; } 46 public TeleportBehaviour()
47 {
48 AbbreviatedName = "t";
49 Name = "Teleport";
50 }
46 51
47 public override void Action() 52 public override void Action()
48 { 53 {
@@ -70,6 +75,8 @@ namespace pCampBot
70 Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition); 75 Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition);
71 76
72 Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition); 77 Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition);
78
79 Thread.Sleep(Bot.Random.Next(3000, 10000));
73 } 80 }
74 } 81 }
75} \ No newline at end of file 82} \ No newline at end of file
diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs
index d418288..d0a4ef3 100644
--- a/OpenSim/Tools/pCampBot/Bot.cs
+++ b/OpenSim/Tools/pCampBot/Bot.cs
@@ -72,9 +72,10 @@ namespace pCampBot
72 /// Behaviours implemented by this bot. 72 /// Behaviours implemented by this bot.
73 /// </summary> 73 /// </summary>
74 /// <remarks> 74 /// <remarks>
75 /// Lock this list before manipulating it. 75 /// Indexed by abbreviated name. There can only be one instance of a particular behaviour.
76 /// Lock this structure before manipulating it.
76 /// </remarks> 77 /// </remarks>
77 public List<IBehaviour> Behaviours { get; private set; } 78 public Dictionary<string, IBehaviour> Behaviours { get; private set; }
78 79
79 /// <summary> 80 /// <summary>
80 /// Objects that the bot has discovered. 81 /// Objects that the bot has discovered.
@@ -165,8 +166,6 @@ namespace pCampBot
165 { 166 {
166 ConnectionState = ConnectionState.Disconnected; 167 ConnectionState = ConnectionState.Disconnected;
167 168
168 behaviours.ForEach(b => b.Initialize(this));
169
170 Random = new Random(Environment.TickCount);// We do stuff randomly here 169 Random = new Random(Environment.TickCount);// We do stuff randomly here
171 FirstName = firstName; 170 FirstName = firstName;
172 LastName = lastName; 171 LastName = lastName;
@@ -176,12 +175,53 @@ namespace pCampBot
176 StartLocation = startLocation; 175 StartLocation = startLocation;
177 176
178 Manager = bm; 177 Manager = bm;
179 Behaviours = behaviours; 178
179 Behaviours = new Dictionary<string, IBehaviour>();
180 foreach (IBehaviour behaviour in behaviours)
181 AddBehaviour(behaviour);
180 182
181 // Only calling for use as a template. 183 // Only calling for use as a template.
182 CreateLibOmvClient(); 184 CreateLibOmvClient();
183 } 185 }
184 186
187 public bool TryGetBehaviour(string abbreviatedName, out IBehaviour behaviour)
188 {
189 lock (Behaviours)
190 return Behaviours.TryGetValue(abbreviatedName, out behaviour);
191 }
192
193 public bool AddBehaviour(IBehaviour behaviour)
194 {
195 lock (Behaviours)
196 {
197 if (!Behaviours.ContainsKey(behaviour.AbbreviatedName))
198 {
199 behaviour.Initialize(this);
200 Behaviours.Add(behaviour.AbbreviatedName, behaviour);
201
202 return true;
203 }
204 }
205
206 return false;
207 }
208
209 public bool RemoveBehaviour(string abbreviatedName)
210 {
211 lock (Behaviours)
212 {
213 IBehaviour behaviour;
214
215 if (!Behaviours.TryGetValue(abbreviatedName, out behaviour))
216 return false;
217
218 behaviour.Close();
219 Behaviours.Remove(abbreviatedName);
220
221 return true;
222 }
223 }
224
185 private void CreateLibOmvClient() 225 private void CreateLibOmvClient()
186 { 226 {
187 GridClient newClient = new GridClient(); 227 GridClient newClient = new GridClient();
@@ -237,16 +277,25 @@ namespace pCampBot
237 private void Action() 277 private void Action()
238 { 278 {
239 while (ConnectionState != ConnectionState.Disconnecting) 279 while (ConnectionState != ConnectionState.Disconnecting)
280 {
240 lock (Behaviours) 281 lock (Behaviours)
241 Behaviours.ForEach( 282 {
242 b => 283 foreach (IBehaviour behaviour in Behaviours.Values)
243 { 284 {
244 Thread.Sleep(Random.Next(3000, 10000)); 285// Thread.Sleep(Random.Next(3000, 10000));
245 286
246 // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); 287 // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType());
247 b.Action(); 288 behaviour.Action();
248 } 289 }
249 ); 290 }
291
292 // XXX: This is a really shitty way of yielding so that behaviours can be added/removed
293 Thread.Sleep(100);
294 }
295
296 lock (Behaviours)
297 foreach (IBehaviour b in Behaviours.Values)
298 b.Close();
250 } 299 }
251 300
252 /// <summary> 301 /// <summary>
diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs
index 5c3835b..3c1b11e 100644
--- a/OpenSim/Tools/pCampBot/BotManager.cs
+++ b/OpenSim/Tools/pCampBot/BotManager.cs
@@ -140,7 +140,7 @@ namespace pCampBot
140 /// <summary> 140 /// <summary>
141 /// Behaviour switches for bots. 141 /// Behaviour switches for bots.
142 /// </summary> 142 /// </summary>
143 private HashSet<string> m_behaviourSwitches = new HashSet<string>(); 143 private HashSet<string> m_defaultBehaviourSwitches = new HashSet<string>();
144 144
145 /// <summary> 145 /// <summary>
146 /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data 146 /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data
@@ -195,6 +195,20 @@ namespace pCampBot
195 HandleDisconnect); 195 HandleDisconnect);
196 196
197 m_console.Commands.AddCommand( 197 m_console.Commands.AddCommand(
198 "bot", false, "add behaviour", "add behaviour <abbreviated-name> [<bot-number>]",
199 "Add a behaviour to a bot",
200 "If no bot number is specified then behaviour is added to all bots.\n"
201 + "Can be performed on connected or disconnected bots.",
202 HandleAddBehaviour);
203
204 m_console.Commands.AddCommand(
205 "bot", false, "remove behaviour", "remove behaviour <abbreviated-name> [<bot-number>]",
206 "Remove a behaviour from a bot",
207 "If no bot number is specified then behaviour is added to all bots.\n"
208 + "Can be performed on connected or disconnected bots.",
209 HandleRemoveBehaviour);
210
211 m_console.Commands.AddCommand(
198 "bot", false, "sit", "sit", "Sit all bots on the ground.", 212 "bot", false, "sit", "sit", "Sit all bots on the ground.",
199 HandleSit); 213 HandleSit);
200 214
@@ -212,7 +226,7 @@ namespace pCampBot
212 "bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus); 226 "bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus);
213 227
214 m_console.Commands.AddCommand( 228 m_console.Commands.AddCommand(
215 "bot", false, "show bot", "show bot <n>", 229 "bot", false, "show bot", "show bot <bot-number>",
216 "Shows the detailed status and settings of a particular bot.", HandleShowBotStatus); 230 "Shows the detailed status and settings of a particular bot.", HandleShowBotStatus);
217 231
218 m_bots = new List<Bot>(); 232 m_bots = new List<Bot>();
@@ -235,7 +249,7 @@ namespace pCampBot
235 m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last")); 249 m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last"));
236 250
237 Array.ForEach<string>( 251 Array.ForEach<string>(
238 startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b)); 252 startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_defaultBehaviourSwitches.Add(b));
239 253
240 for (int i = 0; i < botcount; i++) 254 for (int i = 0; i < botcount; i++)
241 { 255 {
@@ -243,28 +257,50 @@ namespace pCampBot
243 { 257 {
244 string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); 258 string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber);
245 259
246 // We must give each bot its own list of instantiated behaviours since they store state. 260 CreateBot(
247 List<IBehaviour> behaviours = new List<IBehaviour>(); 261 this,
248 262 CreateBehavioursFromAbbreviatedNames(m_defaultBehaviourSwitches),
249 // Hard-coded for now 263 m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting);
250 if (m_behaviourSwitches.Contains("c")) 264 }
251 behaviours.Add(new CrossBehaviour()); 265 }
266 }
267
268 private List<IBehaviour> CreateBehavioursFromAbbreviatedNames(HashSet<string> abbreviatedNames)
269 {
270 // We must give each bot its own list of instantiated behaviours since they store state.
271 List<IBehaviour> behaviours = new List<IBehaviour>();
272
273 // Hard-coded for now
274 foreach (string abName in abbreviatedNames)
275 {
276 IBehaviour newBehaviour = null;
252 277
253 if (m_behaviourSwitches.Contains("g")) 278 if (abName == "c")
254 behaviours.Add(new GrabbingBehaviour()); 279 newBehaviour = new CrossBehaviour();
255 280
256 if (m_behaviourSwitches.Contains("n")) 281 if (abName == "g")
257 behaviours.Add(new NoneBehaviour()); 282 newBehaviour = new GrabbingBehaviour();
258 283
259 if (m_behaviourSwitches.Contains("p")) 284 if (abName == "n")
260 behaviours.Add(new PhysicsBehaviour()); 285 newBehaviour = new NoneBehaviour();
261
262 if (m_behaviourSwitches.Contains("t"))
263 behaviours.Add(new TeleportBehaviour());
264 286
265 CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); 287 if (abName == "p")
288 newBehaviour = new PhysicsBehaviour();
289
290 if (abName == "t")
291 newBehaviour = new TeleportBehaviour();
292
293 if (newBehaviour != null)
294 {
295 behaviours.Add(newBehaviour);
296 }
297 else
298 {
299 MainConsole.Instance.OutputFormat("No behaviour with abbreviated name {0} found", abName);
266 } 300 }
267 } 301 }
302
303 return behaviours;
268 } 304 }
269 305
270 public void ConnectBots(int botcount) 306 public void ConnectBots(int botcount)
@@ -453,6 +489,118 @@ namespace pCampBot
453 } 489 }
454 } 490 }
455 491
492 private void HandleAddBehaviour(string module, string[] cmd)
493 {
494 if (cmd.Length < 3 || cmd.Length > 4)
495 {
496 MainConsole.Instance.OutputFormat("Usage: add behaviour <abbreviated-behaviour> [<bot-number>]");
497 return;
498 }
499
500 string rawBehaviours = cmd[2];
501
502 List<Bot> botsToEffect = new List<Bot>();
503
504 if (cmd.Length == 3)
505 {
506 lock (m_bots)
507 botsToEffect.AddRange(m_bots);
508 }
509 else
510 {
511 int botNumber;
512 if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber))
513 return;
514
515 Bot bot = GetBotFromNumber(botNumber);
516
517 if (bot == null)
518 {
519 MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
520 return;
521 }
522
523 botsToEffect.Add(bot);
524 }
525
526
527 HashSet<string> rawAbbreviatedSwitchesToAdd = new HashSet<string>();
528 Array.ForEach<string>(rawBehaviours.Split(new char[] { ',' }), b => rawAbbreviatedSwitchesToAdd.Add(b));
529
530 foreach (Bot bot in botsToEffect)
531 {
532 List<IBehaviour> behavioursAdded = new List<IBehaviour>();
533
534 foreach (IBehaviour behaviour in CreateBehavioursFromAbbreviatedNames(rawAbbreviatedSwitchesToAdd))
535 {
536 if (bot.AddBehaviour(behaviour))
537 behavioursAdded.Add(behaviour);
538 }
539
540 MainConsole.Instance.OutputFormat(
541 "Added behaviours {0} to bot {1}",
542 string.Join(", ", behavioursAdded.ConvertAll<string>(b => b.Name).ToArray()), bot.Name);
543 }
544 }
545
546 private void HandleRemoveBehaviour(string module, string[] cmd)
547 {
548 if (cmd.Length < 3 || cmd.Length > 4)
549 {
550 MainConsole.Instance.OutputFormat("Usage: remove behaviour <abbreviated-behaviour> [<bot-number>]");
551 return;
552 }
553
554 string rawBehaviours = cmd[2];
555
556 List<Bot> botsToEffect = new List<Bot>();
557
558 if (cmd.Length == 3)
559 {
560 lock (m_bots)
561 botsToEffect.AddRange(m_bots);
562 }
563 else
564 {
565 int botNumber;
566 if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber))
567 return;
568
569 Bot bot = GetBotFromNumber(botNumber);
570
571 if (bot == null)
572 {
573 MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
574 return;
575 }
576
577 botsToEffect.Add(bot);
578 }
579
580 HashSet<string> abbreviatedBehavioursToRemove = new HashSet<string>();
581 Array.ForEach<string>(rawBehaviours.Split(new char[] { ',' }), b => abbreviatedBehavioursToRemove.Add(b));
582
583 foreach (Bot bot in botsToEffect)
584 {
585 List<IBehaviour> behavioursRemoved = new List<IBehaviour>();
586
587 foreach (string b in abbreviatedBehavioursToRemove)
588 {
589 IBehaviour behaviour;
590
591 if (bot.TryGetBehaviour(b, out behaviour))
592 {
593 bot.RemoveBehaviour(b);
594 behavioursRemoved.Add(behaviour);
595 }
596 }
597
598 MainConsole.Instance.OutputFormat(
599 "Removed behaviours {0} to bot {1}",
600 string.Join(", ", behavioursRemoved.ConvertAll<string>(b => b.Name).ToArray()), bot.Name);
601 }
602 }
603
456 private void HandleDisconnect(string module, string[] cmd) 604 private void HandleDisconnect(string module, string[] cmd)
457 { 605 {
458 lock (m_bots) 606 lock (m_bots)
@@ -572,10 +720,11 @@ namespace pCampBot
572 private void HandleShowBotsStatus(string module, string[] cmd) 720 private void HandleShowBotsStatus(string module, string[] cmd)
573 { 721 {
574 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 722 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
575 cdt.AddColumn("Name", 30); 723 cdt.AddColumn("Name", 24);
576 cdt.AddColumn("Region", 30); 724 cdt.AddColumn("Region", 24);
577 cdt.AddColumn("Status", 14); 725 cdt.AddColumn("Status", 13);
578 cdt.AddColumn("Connections", 11); 726 cdt.AddColumn("Conns", 5);
727 cdt.AddColumn("Behaviours", 20);
579 728
580 Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>(); 729 Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>();
581 foreach (object o in Enum.GetValues(typeof(ConnectionState))) 730 foreach (object o in Enum.GetValues(typeof(ConnectionState)))
@@ -583,13 +732,17 @@ namespace pCampBot
583 732
584 lock (m_bots) 733 lock (m_bots)
585 { 734 {
586 foreach (Bot pb in m_bots) 735 foreach (Bot bot in m_bots)
587 { 736 {
588 Simulator currentSim = pb.Client.Network.CurrentSim; 737 Simulator currentSim = bot.Client.Network.CurrentSim;
589 totals[pb.ConnectionState]++; 738 totals[bot.ConnectionState]++;
590 739
591 cdt.AddRow( 740 cdt.AddRow(
592 pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState, pb.SimulatorsCount); 741 bot.Name,
742 currentSim != null ? currentSim.Name : "(none)",
743 bot.ConnectionState,
744 bot.SimulatorsCount,
745 string.Join(",", bot.Behaviours.Keys.ToArray()));
593 } 746 }
594 } 747 }
595 748
@@ -616,16 +769,11 @@ namespace pCampBot
616 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber)) 769 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber))
617 return; 770 return;
618 771
619 string name = string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); 772 Bot bot = GetBotFromNumber(botNumber);
620
621 Bot bot;
622
623 lock (m_bots)
624 bot = m_bots.Find(b => b.Name == name);
625 773
626 if (bot == null) 774 if (bot == null)
627 { 775 {
628 MainConsole.Instance.Output("No bot found with name {0}", name); 776 MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
629 return; 777 return;
630 } 778 }
631 779
@@ -645,12 +793,39 @@ namespace pCampBot
645 MainConsole.Instance.Output("Settings"); 793 MainConsole.Instance.Output("Settings");
646 794
647 ConsoleDisplayList statusCdl = new ConsoleDisplayList(); 795 ConsoleDisplayList statusCdl = new ConsoleDisplayList();
796
797 statusCdl.AddRow(
798 "Behaviours",
799 string.Join(", ", bot.Behaviours.Values.ToList().ConvertAll<string>(b => b.Name).ToArray()));
800
648 GridClient botClient = bot.Client; 801 GridClient botClient = bot.Client;
649 statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); 802 statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES);
650 803
651 MainConsole.Instance.Output(statusCdl.ToString()); 804 MainConsole.Instance.Output(statusCdl.ToString());
652 } 805 }
653 806
807 /// <summary>
808 /// Get a specific bot from its number.
809 /// </summary>
810 /// <returns>null if no bot was found</returns>
811 /// <param name='botNumber'></param>
812 private Bot GetBotFromNumber(int botNumber)
813 {
814 string name = GenerateBotNameFromNumber(botNumber);
815
816 Bot bot;
817
818 lock (m_bots)
819 bot = m_bots.Find(b => b.Name == name);
820
821 return bot;
822 }
823
824 private string GenerateBotNameFromNumber(int botNumber)
825 {
826 return string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber);
827 }
828
654 internal void Grid_GridRegion(object o, GridRegionEventArgs args) 829 internal void Grid_GridRegion(object o, GridRegionEventArgs args)
655 { 830 {
656 lock (RegionsKnown) 831 lock (RegionsKnown)
diff --git a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs
index 9c984be..0ed4825 100644
--- a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs
@@ -32,6 +32,11 @@ namespace pCampBot.Interfaces
32 public interface IBehaviour 32 public interface IBehaviour
33 { 33 {
34 /// <summary> 34 /// <summary>
35 /// Abbreviated name of this behaviour.
36 /// </summary>
37 string AbbreviatedName { get; }
38
39 /// <summary>
35 /// Name of this behaviour. 40 /// Name of this behaviour.
36 /// </summary> 41 /// </summary>
37 string Name { get; } 42 string Name { get; }
@@ -46,6 +51,14 @@ namespace pCampBot.Interfaces
46 void Initialize(Bot bot); 51 void Initialize(Bot bot);
47 52
48 /// <summary> 53 /// <summary>
54 /// Close down this behaviour.
55 /// </summary>
56 /// <remarks>
57 /// This is triggered if a behaviour is removed via explicit command and when a bot is disconnected
58 /// </remarks>
59 void Close();
60
61 /// <summary>
49 /// Action to take when this behaviour is invoked. 62 /// Action to take when this behaviour is invoked.
50 /// </summary> 63 /// </summary>
51 /// <param name="bot"></param> 64 /// <param name="bot"></param>