aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-09-03 18:51:55 +0100
committerJustin Clark-Casey (justincc)2013-09-03 18:51:55 +0100
commit9bd62715704685738c55c6de8127b16cc6695bdb (patch)
tree2e05a893e763f9d02484f341d50f023d738a43f5
parentAnd fix break in "show bot" from commit 9c65207 (diff)
downloadopensim-SC-9bd62715704685738c55c6de8127b16cc6695bdb.zip
opensim-SC-9bd62715704685738c55c6de8127b16cc6695bdb.tar.gz
opensim-SC-9bd62715704685738c55c6de8127b16cc6695bdb.tar.bz2
opensim-SC-9bd62715704685738c55c6de8127b16cc6695bdb.tar.xz
Add ability to adjust pCampbot bot behaviours whilst running with "add behaviour <behaviour-name> <bot-number>" console commad
Diffstat (limited to '')
-rw-r--r--OpenSim/Tools/pCampBot/Bot.cs51
-rw-r--r--OpenSim/Tools/pCampBot/BotManager.cs147
2 files changed, 157 insertions, 41 deletions
diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs
index d418288..6037516 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,31 @@ 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 AddBehaviour(IBehaviour behaviour)
188 {
189 lock (Behaviours)
190 {
191 if (!Behaviours.ContainsKey(behaviour.AbbreviatedName))
192 {
193 behaviour.Initialize(this);
194 Behaviours.Add(behaviour.AbbreviatedName, behaviour);
195
196 return true;
197 }
198 }
199
200 return false;
201 }
202
185 private void CreateLibOmvClient() 203 private void CreateLibOmvClient()
186 { 204 {
187 GridClient newClient = new GridClient(); 205 GridClient newClient = new GridClient();
@@ -237,16 +255,21 @@ namespace pCampBot
237 private void Action() 255 private void Action()
238 { 256 {
239 while (ConnectionState != ConnectionState.Disconnecting) 257 while (ConnectionState != ConnectionState.Disconnecting)
258 {
240 lock (Behaviours) 259 lock (Behaviours)
241 Behaviours.ForEach( 260 {
242 b => 261 foreach (IBehaviour behaviour in Behaviours.Values)
243 { 262 {
244 Thread.Sleep(Random.Next(3000, 10000)); 263 Thread.Sleep(Random.Next(3000, 10000));
245 264
246 // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); 265 // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType());
247 b.Action(); 266 behaviour.Action();
248 } 267 }
249 ); 268 }
269
270 // XXX: This is a really shitty way of yielding so that behaviours can be added/removed
271 Thread.Sleep(100);
272 }
250 } 273 }
251 274
252 /// <summary> 275 /// <summary>
diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs
index 3e446af..51c5ff4 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,18 @@ 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 "Can be performed on connected or disconnected bots.",
201 HandleAddBehaviour);
202
203// m_console.Commands.AddCommand(
204// "bot", false, "remove behaviour", "remove behaviour <abbreviated-name> <bot-number>",
205// "Remove a behaviour from a bot",
206// "Can be performed on connected or disconnected bots.",
207// HandleRemoveBehaviour);
208
209 m_console.Commands.AddCommand(
198 "bot", false, "sit", "sit", "Sit all bots on the ground.", 210 "bot", false, "sit", "sit", "Sit all bots on the ground.",
199 HandleSit); 211 HandleSit);
200 212
@@ -235,7 +247,7 @@ namespace pCampBot
235 m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last")); 247 m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last"));
236 248
237 Array.ForEach<string>( 249 Array.ForEach<string>(
238 startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b)); 250 startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_defaultBehaviourSwitches.Add(b));
239 251
240 for (int i = 0; i < botcount; i++) 252 for (int i = 0; i < botcount; i++)
241 { 253 {
@@ -243,28 +255,50 @@ namespace pCampBot
243 { 255 {
244 string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); 256 string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber);
245 257
246 // We must give each bot its own list of instantiated behaviours since they store state. 258 CreateBot(
247 List<IBehaviour> behaviours = new List<IBehaviour>(); 259 this,
248 260 CreateBehavioursFromAbbreviatedNames(m_defaultBehaviourSwitches),
249 // Hard-coded for now 261 m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting);
250 if (m_behaviourSwitches.Contains("c")) 262 }
251 behaviours.Add(new CrossBehaviour()); 263 }
264 }
265
266 private List<IBehaviour> CreateBehavioursFromAbbreviatedNames(HashSet<string> abbreviatedNames)
267 {
268 // We must give each bot its own list of instantiated behaviours since they store state.
269 List<IBehaviour> behaviours = new List<IBehaviour>();
270
271 // Hard-coded for now
272 foreach (string abName in abbreviatedNames)
273 {
274 IBehaviour newBehaviour = null;
275
276 if (abName == "c")
277 newBehaviour = new CrossBehaviour();
278
279 if (abName == "g")
280 newBehaviour = new GrabbingBehaviour();
252 281
253 if (m_behaviourSwitches.Contains("g")) 282 if (abName == "n")
254 behaviours.Add(new GrabbingBehaviour()); 283 newBehaviour = new NoneBehaviour();
255 284
256 if (m_behaviourSwitches.Contains("n")) 285 if (abName == "p")
257 behaviours.Add(new NoneBehaviour()); 286 newBehaviour = new PhysicsBehaviour();
258 287
259 if (m_behaviourSwitches.Contains("p")) 288 if (abName == "t")
260 behaviours.Add(new PhysicsBehaviour()); 289 newBehaviour = new TeleportBehaviour();
261
262 if (m_behaviourSwitches.Contains("t"))
263 behaviours.Add(new TeleportBehaviour());
264 290
265 CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); 291 if (newBehaviour != null)
292 {
293 behaviours.Add(newBehaviour);
294 }
295 else
296 {
297 MainConsole.Instance.OutputFormat("No behaviour with abbreviated name {0} found", abName);
266 } 298 }
267 } 299 }
300
301 return behaviours;
268 } 302 }
269 303
270 public void ConnectBots(int botcount) 304 public void ConnectBots(int botcount)
@@ -453,6 +487,44 @@ namespace pCampBot
453 } 487 }
454 } 488 }
455 489
490 private void HandleAddBehaviour(string module, string[] cmd)
491 {
492 if (cmd.Length != 4)
493 {
494 MainConsole.Instance.OutputFormat("Usage: add behaviour <abbreviated-behaviour> <bot-number>");
495 return;
496 }
497
498 string rawBehaviours = cmd[2];
499 int botNumber;
500
501 if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber))
502 return;
503
504 Bot bot = GetBotFromNumber(botNumber);
505
506 if (bot == null)
507 {
508 MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
509 return;
510 }
511
512 HashSet<string> rawAbbreviatedSwitchesToAdd = new HashSet<string>();
513 Array.ForEach<string>(rawBehaviours.Split(new char[] { ',' }), b => rawAbbreviatedSwitchesToAdd.Add(b));
514
515 List<IBehaviour> behavioursAdded = new List<IBehaviour>();
516
517 foreach (IBehaviour behaviour in CreateBehavioursFromAbbreviatedNames(rawAbbreviatedSwitchesToAdd))
518 {
519 if (bot.AddBehaviour(behaviour))
520 behavioursAdded.Add(behaviour);
521 }
522
523 MainConsole.Instance.OutputFormat(
524 "Added behaviours {0} to bot {1}",
525 string.Join(", ", behavioursAdded.ConvertAll<string>(b => b.Name).ToArray()), bot.Name);
526 }
527
456 private void HandleDisconnect(string module, string[] cmd) 528 private void HandleDisconnect(string module, string[] cmd)
457 { 529 {
458 lock (m_bots) 530 lock (m_bots)
@@ -594,7 +666,7 @@ namespace pCampBot
594 currentSim != null ? currentSim.Name : "(none)", 666 currentSim != null ? currentSim.Name : "(none)",
595 bot.ConnectionState, 667 bot.ConnectionState,
596 bot.SimulatorsCount, 668 bot.SimulatorsCount,
597 string.Join(",", bot.Behaviours.ConvertAll<string>(behaviour => behaviour.AbbreviatedName).ToArray())); 669 string.Join(",", bot.Behaviours.Keys.ToArray()));
598 } 670 }
599 } 671 }
600 672
@@ -621,16 +693,11 @@ namespace pCampBot
621 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber)) 693 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber))
622 return; 694 return;
623 695
624 string name = string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); 696 Bot bot = GetBotFromNumber(botNumber);
625
626 Bot bot;
627
628 lock (m_bots)
629 bot = m_bots.Find(b => b.Name == name);
630 697
631 if (bot == null) 698 if (bot == null)
632 { 699 {
633 MainConsole.Instance.Output("No bot found with name {0}", name); 700 MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
634 return; 701 return;
635 } 702 }
636 703
@@ -650,13 +717,39 @@ namespace pCampBot
650 MainConsole.Instance.Output("Settings"); 717 MainConsole.Instance.Output("Settings");
651 718
652 ConsoleDisplayList statusCdl = new ConsoleDisplayList(); 719 ConsoleDisplayList statusCdl = new ConsoleDisplayList();
653 statusCdl.AddRow("Behaviours", string.Join(", ", bot.Behaviours.ConvertAll<string>(b => b.Name).ToArray())); 720
721 statusCdl.AddRow(
722 "Behaviours",
723 string.Join(", ", bot.Behaviours.Values.ToList().ConvertAll<string>(b => b.Name).ToArray()));
724
654 GridClient botClient = bot.Client; 725 GridClient botClient = bot.Client;
655 statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); 726 statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES);
656 727
657 MainConsole.Instance.Output(statusCdl.ToString()); 728 MainConsole.Instance.Output(statusCdl.ToString());
658 } 729 }
659 730
731 /// <summary>
732 /// Get a specific bot from its number.
733 /// </summary>
734 /// <returns>null if no bot was found</returns>
735 /// <param name='botNumber'></param>
736 private Bot GetBotFromNumber(int botNumber)
737 {
738 string name = GenerateBotNameFromNumber(botNumber);
739
740 Bot bot;
741
742 lock (m_bots)
743 bot = m_bots.Find(b => b.Name == name);
744
745 return bot;
746 }
747
748 private string GenerateBotNameFromNumber(int botNumber)
749 {
750 return string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber);
751 }
752
660 internal void Grid_GridRegion(object o, GridRegionEventArgs args) 753 internal void Grid_GridRegion(object o, GridRegionEventArgs args)
661 { 754 {
662 lock (RegionsKnown) 755 lock (RegionsKnown)