aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
authorMelanie Thielker2009-02-07 12:25:39 +0000
committerMelanie Thielker2009-02-07 12:25:39 +0000
commit54c6a920baa0ef02a9ea09e08cc1effcef3b0a3a (patch)
treef606cbdbc383ec21fee28f0a1454140a1c714278 /OpenSim/Framework
parentThank you dslake for a patch that: (diff)
downloadopensim-SC-54c6a920baa0ef02a9ea09e08cc1effcef3b0a3a.zip
opensim-SC-54c6a920baa0ef02a9ea09e08cc1effcef3b0a3a.tar.gz
opensim-SC-54c6a920baa0ef02a9ea09e08cc1effcef3b0a3a.tar.bz2
opensim-SC-54c6a920baa0ef02a9ea09e08cc1effcef3b0a3a.tar.xz
Replace the console for all OpenSim apps with a new console featuring command
line editing, context sensitive help (press ? at any time), command line history, a new plugin command system and new appender features thet let you type while the console is scrolling. Seamlessly integrates the ICommander interfaces.
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/Console/ConsoleBase.cs661
-rw-r--r--OpenSim/Framework/Console/ConsoleCallbacksBase.cs35
-rw-r--r--OpenSim/Framework/Console/OpenSimAppender.cs16
-rw-r--r--OpenSim/Framework/IScene.cs3
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs119
5 files changed, 588 insertions, 246 deletions
diff --git a/OpenSim/Framework/Console/ConsoleBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs
index 30af23a..f990748 100644
--- a/OpenSim/Framework/Console/ConsoleBase.cs
+++ b/OpenSim/Framework/Console/ConsoleBase.cs
@@ -26,22 +26,250 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Text;
30using System.Diagnostics;
31using System.Net;
32using System.Reflection; 30using System.Reflection;
33using System.Text.RegularExpressions; 31using System.Diagnostics;
32using System.Collections.Generic;
34using log4net; 33using log4net;
35 34
36namespace OpenSim.Framework.Console 35namespace OpenSim.Framework.Console
37{ 36{
37 public delegate void CommandDelegate(string module, string[] cmd);
38
39 public class Commands
40 {
41 private class CommandInfo
42 {
43 public string module;
44 public string help_text;
45 public string long_help;
46 public CommandDelegate fn;
47 }
48
49 private Dictionary<string, Object> tree =
50 new Dictionary<string, Object>();
51
52 public List<string> GetHelp()
53 {
54 List<string> help = new List<string>();
55
56 help.AddRange(CollectHelp(tree));
57
58 help.Sort();
59
60 return help;
61 }
62
63 private List<string> CollectHelp(Dictionary<string, Object> dict)
64 {
65 List<string> result = new List<string>();
66
67 foreach (KeyValuePair<string, object> kvp in dict)
68 {
69 if (kvp.Value is Dictionary<string, Object>)
70 {
71 result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
72 }
73 else
74 {
75 if (((CommandInfo)kvp.Value).long_help != String.Empty)
76 result.Add(((CommandInfo)kvp.Value).help_text+" - "+
77 ((CommandInfo)kvp.Value).long_help);
78 }
79 }
80 return result;
81 }
82
83 public void AddCommand(string module, string command, string help, string longhelp, CommandDelegate fn)
84 {
85 string[] parts = Parser.Parse(command);
86
87 Dictionary<string, Object> current = tree;
88 foreach (string s in parts)
89 {
90 if (current.ContainsKey(s))
91 {
92 if (current[s] is Dictionary<string, Object>)
93 {
94 current = (Dictionary<string, Object>)current[s];
95 }
96 else
97 return;
98 }
99 else
100 {
101 current[s] = new Dictionary<string, Object>();
102 current = (Dictionary<string, Object>)current[s];
103 }
104 }
105
106 if (current.ContainsKey(String.Empty))
107 return;
108 CommandInfo info = new CommandInfo();
109 info.module = module;
110 info.help_text = help;
111 info.long_help = longhelp;
112 info.fn = fn;
113 current[String.Empty] = info;
114 }
115
116 public string[] FindNextOption(string[] cmd, bool term)
117 {
118 Dictionary<string, object> current = tree;
119
120 int remaining = cmd.Length;
121
122 foreach (string s in cmd)
123 {
124 remaining--;
125
126 List<string> found = new List<string>();
127
128 foreach (string opt in current.Keys)
129 {
130 if (opt.StartsWith(s))
131 {
132 found.Add(opt);
133 }
134 }
135
136 if (found.Count == 1 && (remaining != 0 || term))
137 {
138 current = (Dictionary<string, object>)current[found[0]];
139 }
140 else if (found.Count > 0)
141 {
142 return found.ToArray();
143 }
144 else
145 {
146 break;
147// return new string[] {"<cr>"};
148 }
149 }
150
151 if (current.Count > 1)
152 {
153 List<string> choices = new List<string>();
154
155 bool addcr = false;
156 foreach (string s in current.Keys)
157 {
158 if (s == String.Empty)
159 {
160 CommandInfo ci = (CommandInfo)current[String.Empty];
161 if (ci.fn != null)
162 addcr = true;
163 }
164 else
165 choices.Add(s);
166 }
167 if (addcr)
168 choices.Add("<cr>");
169 return choices.ToArray();
170 }
171
172 if (current.ContainsKey(String.Empty))
173 return new string[] { "Command help: "+((CommandInfo)current[String.Empty]).help_text};
174
175 return new string[] { new List<string>(current.Keys)[0] };
176 }
177
178 public string[] Resolve(string[] cmd)
179 {
180 string[] result = cmd;
181 int index = -1;
182
183 Dictionary<string, object> current = tree;
184
185 foreach (string s in cmd)
186 {
187 index++;
188
189 List<string> found = new List<string>();
190
191 foreach (string opt in current.Keys)
192 {
193 if (opt.StartsWith(s))
194 {
195 found.Add(opt);
196 }
197 }
198
199 if (found.Count == 1)
200 {
201 result[index] = found[0];
202 current = (Dictionary<string, object>)current[found[0]];
203 }
204 else if (found.Count > 0)
205 {
206 return new string[0];
207 }
208 else
209 {
210 break;
211 }
212 }
213
214 if (current.ContainsKey(String.Empty))
215 {
216 CommandInfo ci = (CommandInfo)current[String.Empty];
217 if (ci.fn == null)
218 return new string[0];
219 ci.fn(ci.module, result);
220 return result;
221 }
222 return new string[0];
223 }
224 }
225
226 public class Parser
227 {
228 public static string[] Parse(string text)
229 {
230 List<string> result = new List<string>();
231
232 int index;
233
234 string[] unquoted = text.Split(new char[] {'"'});
235
236 for (index = 0 ; index < unquoted.Length ; index++)
237 {
238 if (index % 2 == 0)
239 {
240 string[] words = unquoted[index].Split(new char[] {' '});
241 foreach (string w in words)
242 {
243 if (w != String.Empty)
244 result.Add(w);
245 }
246 }
247 else
248 {
249 result.Add(unquoted[index]);
250 }
251 }
252
253 return result.ToArray();
254 }
255 }
256
38 public class ConsoleBase 257 public class ConsoleBase
39 { 258 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 259 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 260
42 private readonly object m_syncRoot = new object(); 261 private readonly object m_syncRoot = new object();
43 262
44 public conscmd_callback m_cmdParser; 263 private int y = -1;
264 private int cp = 0;
265 private int h = 1;
266 private string prompt = "# ";
267 private StringBuilder cmdline = new StringBuilder();
268 public Commands Commands = new Commands();
269 private bool echo = true;
270 private List<string> history = new List<string>();
271
272 public object ConsoleScene = null;
45 273
46 /// <summary> 274 /// <summary>
47 /// The default prompt text. 275 /// The default prompt text.
@@ -53,15 +281,19 @@ namespace OpenSim.Framework.Console
53 } 281 }
54 protected string m_defaultPrompt; 282 protected string m_defaultPrompt;
55 283
56 /// <summary> 284 public ConsoleBase(string defaultPrompt)
57 /// Constructor.
58 /// </summary>
59 /// <param name="defaultPrompt"></param>
60 /// <param name="cmdparser"></param>
61 public ConsoleBase(string defaultPrompt, conscmd_callback cmdparser)
62 { 285 {
63 DefaultPrompt = defaultPrompt; 286 DefaultPrompt = defaultPrompt;
64 m_cmdParser = cmdparser; 287
288 Commands.AddCommand("console", "help", "help", "Get command list", Help);
289 }
290
291 private void AddToHistory(string text)
292 {
293 while (history.Count >= 100)
294 history.RemoveAt(0);
295
296 history.Add(text);
65 } 297 }
66 298
67 /// <summary> 299 /// <summary>
@@ -95,8 +327,7 @@ namespace OpenSim.Framework.Console
95 /// <param name="args">WriteLine-style message arguments</param> 327 /// <param name="args">WriteLine-style message arguments</param>
96 public void Warn(string sender, string format, params object[] args) 328 public void Warn(string sender, string format, params object[] args)
97 { 329 {
98 WritePrefixLine(DeriveColor(sender), sender); 330 WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Yellow, format, args);
99 WriteNewLine(ConsoleColor.Yellow, format, args);
100 } 331 }
101 332
102 /// <summary> 333 /// <summary>
@@ -117,10 +348,8 @@ namespace OpenSim.Framework.Console
117 /// <param name="args">WriteLine-style message arguments</param> 348 /// <param name="args">WriteLine-style message arguments</param>
118 public void Notice(string sender, string format, params object[] args) 349 public void Notice(string sender, string format, params object[] args)
119 { 350 {
120 WritePrefixLine(DeriveColor(sender), sender); 351 WriteNewLine(DeriveColor(sender), sender, ConsoleColor.White, format, args);
121 WriteNewLine(ConsoleColor.White, format, args);
122 } 352 }
123
124 /// <summary> 353 /// <summary>
125 /// Sends an error to the current console output 354 /// Sends an error to the current console output
126 /// </summary> 355 /// </summary>
@@ -139,8 +368,7 @@ namespace OpenSim.Framework.Console
139 /// <param name="args">WriteLine-style message arguments</param> 368 /// <param name="args">WriteLine-style message arguments</param>
140 public void Error(string sender, string format, params object[] args) 369 public void Error(string sender, string format, params object[] args)
141 { 370 {
142 WritePrefixLine(DeriveColor(sender), sender); 371 WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Red, format, args);
143 Error(format, args);
144 } 372 }
145 373
146 /// <summary> 374 /// <summary>
@@ -161,8 +389,7 @@ namespace OpenSim.Framework.Console
161 /// <param name="args">WriteLine-style message arguments</param> 389 /// <param name="args">WriteLine-style message arguments</param>
162 public void Status(string sender, string format, params object[] args) 390 public void Status(string sender, string format, params object[] args)
163 { 391 {
164 WritePrefixLine(DeriveColor(sender), sender); 392 WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Blue, format, args);
165 WriteNewLine(ConsoleColor.Blue, format, args);
166 } 393 }
167 394
168 [Conditional("DEBUG")] 395 [Conditional("DEBUG")]
@@ -174,12 +401,60 @@ namespace OpenSim.Framework.Console
174 [Conditional("DEBUG")] 401 [Conditional("DEBUG")]
175 public void Debug(string sender, string format, params object[] args) 402 public void Debug(string sender, string format, params object[] args)
176 { 403 {
177 WritePrefixLine(DeriveColor(sender), sender); 404 WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Gray, format, args);
178 WriteNewLine(ConsoleColor.Gray, format, args); 405 }
406
407 private void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
408 {
409 lock (cmdline)
410 {
411 if (y != -1)
412 {
413 System.Console.CursorTop = y;
414 System.Console.CursorLeft = 0;
415
416 int count = cmdline.Length;
417
418 System.Console.Write(" ");
419 while (count-- > 0)
420 System.Console.Write(" ");
421
422 System.Console.CursorTop = y;
423 System.Console.CursorLeft = 0;
424 }
425 WritePrefixLine(senderColor, sender);
426 WriteConsoleLine(color, format, args);
427 if (y != -1)
428 y = System.Console.CursorTop;
429 }
179 } 430 }
180 431
181 private void WriteNewLine(ConsoleColor color, string format, params object[] args) 432 private void WriteNewLine(ConsoleColor color, string format, params object[] args)
182 { 433 {
434 lock (cmdline)
435 {
436 if (y != -1)
437 {
438 System.Console.CursorTop = y;
439 System.Console.CursorLeft = 0;
440
441 int count = cmdline.Length;
442
443 System.Console.Write(" ");
444 while (count-- > 0)
445 System.Console.Write(" ");
446
447 System.Console.CursorTop = y;
448 System.Console.CursorLeft = 0;
449 }
450 WriteConsoleLine(color, format, args);
451 if (y != -1)
452 y = System.Console.CursorTop;
453 }
454 }
455
456 private void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
457 {
183 try 458 try
184 { 459 {
185 lock (m_syncRoot) 460 lock (m_syncRoot)
@@ -240,108 +515,150 @@ namespace OpenSim.Framework.Console
240 } 515 }
241 } 516 }
242 517
243 public string ReadLine() 518 private void Help(string module, string[] cmd)
244 { 519 {
245 try 520 List<string> help = Commands.GetHelp();
246 { 521
247 string line = System.Console.ReadLine(); 522 foreach (string s in help)
523 Output(s);
524 }
248 525
249 while (line == null) 526 private void Show()
527 {
528 lock (cmdline)
529 {
530 if (y == -1 || System.Console.BufferWidth == 0)
531 return;
532
533 int xc = prompt.Length + cp;
534 int new_x = xc % System.Console.BufferWidth;
535 int new_y = y + xc / System.Console.BufferWidth;
536 int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
537 if (end_y / System.Console.BufferWidth >= h)
538 h++;
539 if (end_y >= System.Console.BufferHeight) // wrap
250 { 540 {
251 line = System.Console.ReadLine(); 541 y--;
542 new_y--;
543 System.Console.CursorLeft = 0;
544 System.Console.CursorTop = System.Console.BufferHeight-1;
545 System.Console.WriteLine(" ");
252 } 546 }
253 547
254 return line; 548 System.Console.CursorTop = y;
255 } 549 System.Console.CursorLeft = 0;
256 catch (Exception e)
257 {
258 m_log.Error("[Console]: System.Console.ReadLine exception " + e.ToString());
259 return String.Empty;
260 }
261 }
262 550
263 public int Read() 551 if (echo)
264 { 552 System.Console.Write("{0}{1}", prompt, cmdline);
265 return System.Console.Read(); 553 else
554 System.Console.Write("{0}", prompt);
555
556 System.Console.CursorLeft = new_x;
557 System.Console.CursorTop = new_y;
558 }
266 } 559 }
267 560
268 public IPAddress CmdPromptIPAddress(string prompt, string defaultvalue) 561 public void LockOutput()
269 { 562 {
270 IPAddress address; 563 System.Threading.Monitor.Enter(cmdline);
271 string addressStr; 564 try
272
273 while (true)
274 { 565 {
275 addressStr = CmdPrompt(prompt, defaultvalue); 566 if (y != -1)
276 if (IPAddress.TryParse(addressStr, out address))
277 { 567 {
278 break; 568 System.Console.CursorTop = y;
279 } 569 System.Console.CursorLeft = 0;
280 else 570
281 { 571 int count = cmdline.Length + prompt.Length;
282 m_log.Error("Illegal address. Please re-enter."); 572
573 while (count-- > 0)
574 System.Console.Write(" ");
575
576 System.Console.CursorTop = y;
577 System.Console.CursorLeft = 0;
578
283 } 579 }
284 } 580 }
285 581 catch (Exception)
286 return address; 582 {
583 }
287 } 584 }
288 585
289 public uint CmdPromptIPPort(string prompt, string defaultvalue) 586 public void UnlockOutput()
290 { 587 {
291 uint port; 588 if (y != -1)
292 string portStr; 589 {
590 y = System.Console.CursorTop;
591 Show();
592 }
593 System.Threading.Monitor.Exit(cmdline);
594 }
293 595
294 while (true) 596 public void Output(string text)
597 {
598 lock (cmdline)
295 { 599 {
296 portStr = CmdPrompt(prompt, defaultvalue); 600 if (y == -1)
297 if (uint.TryParse(portStr, out port))
298 { 601 {
299 if (port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort) 602 System.Console.WriteLine(text);
300 { 603
301 break; 604 return;
302 }
303 } 605 }
304 606
305 m_log.Error("Illegal address. Please re-enter."); 607 System.Console.CursorTop = y;
306 } 608 System.Console.CursorLeft = 0;
307 609
308 return port; 610 int count = cmdline.Length + prompt.Length;
309 }
310 611
311 // Displays a prompt and waits for the user to enter a string, then returns that string 612 while (count-- > 0)
312 // (Done with no echo and suitable for passwords - currently disabled) 613 System.Console.Write(" ");
313 public string PasswdPrompt(string prompt) 614
314 { 615 System.Console.CursorTop = y;
315 // FIXME: Needs to be better abstracted 616 System.Console.CursorLeft = 0;
316 System.Console.WriteLine(String.Format("{0}: ", prompt)); 617
317 //ConsoleColor oldfg = System.Console.ForegroundColor; 618 System.Console.WriteLine(text);
318 //System.Console.ForegroundColor = System.Console.BackgroundColor; 619
319 string temp = System.Console.ReadLine(); 620 y = System.Console.CursorTop;
320 //System.Console.ForegroundColor = oldfg; 621
321 return temp; 622 Show();
623 }
322 } 624 }
323 625
324 // Displays a command prompt and waits for the user to enter a string, then returns that string 626 private void ContextHelp()
325 public string CmdPrompt(string prompt)
326 { 627 {
327 System.Console.WriteLine(String.Format("{0}: ", prompt)); 628 string[] words = Parser.Parse(cmdline.ToString());
328 return ReadLine(); 629
630 string[] opts = Commands.FindNextOption(words, cmdline.ToString().EndsWith(" "));
631
632 if (opts[0].StartsWith("Command help:"))
633 Output(opts[0]);
634 else
635 Output(String.Format("Options: {0}", String.Join(" ", opts)));
329 } 636 }
330 637
331 // Displays a command prompt and returns a default value if the user simply presses enter 638 public void Prompt()
332 public string CmdPrompt(string prompt, string defaultresponse)
333 { 639 {
334 string temp = CmdPrompt(String.Format("{0} [{1}]", prompt, defaultresponse)); 640 string line = ReadLine(m_defaultPrompt, true, true);
335 if (temp == String.Empty) 641
336 { 642 if (line != String.Empty)
337 return defaultresponse;
338 }
339 else
340 { 643 {
341 return temp; 644 m_log.Info("Invalid command");
342 } 645 }
343 } 646 }
344 647
648 public string CmdPrompt(string p)
649 {
650 return ReadLine(String.Format("{0}: ", p), false, true);
651 }
652
653 public string CmdPrompt(string p, string def)
654 {
655 string ret = ReadLine(String.Format("{0} [{1}]: ", p, def), false, true);
656 if (ret == String.Empty)
657 ret = def;
658
659 return ret;
660 }
661
345 // Displays a command prompt and returns a default value, user may only enter 1 of 2 options 662 // Displays a command prompt and returns a default value, user may only enter 1 of 2 options
346 public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB) 663 public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB)
347 { 664 {
@@ -362,85 +679,137 @@ namespace OpenSim.Framework.Console
362 return temp; 679 return temp;
363 } 680 }
364 681
365 // Runs a command with a number of parameters 682 // Displays a prompt and waits for the user to enter a string, then returns that string
366 public Object RunCmd(string Cmd, string[] cmdparams) 683 // (Done with no echo and suitable for passwords)
367 { 684 public string PasswdPrompt(string p)
368 m_cmdParser.RunCmd(Cmd, cmdparams);
369 return null;
370 }
371
372 // Shows data about something
373 public void ShowCommands(string ShowWhat)
374 { 685 {
375 m_cmdParser.Show(new string[] { ShowWhat }); 686 return ReadLine(p, false, false);
376 } 687 }
377 688
378 public void Prompt() 689 public void RunCommand(string cmd)
379 { 690 {
380 string tempstr = CmdPrompt(m_defaultPrompt); 691 string[] parts = Parser.Parse(cmd);
381 RunCommand(tempstr); 692 Commands.Resolve(parts);
382 } 693 }
383 694
384 public void RunCommand(string cmdline) 695 public string ReadLine(string p, bool isCommand, bool e)
385 { 696 {
386 Regex Extractor = new Regex(@"(['""][^""]+['""])\s*|([^\s]+)\s*", RegexOptions.Compiled); 697 h = 1;
387 char[] delims = {' ', '"'}; 698 cp = 0;
388 MatchCollection matches = Extractor.Matches(cmdline); 699 prompt = p;
389 // Get matches 700 echo = e;
701 int historyLine = history.Count;
390 702
391 if (matches.Count == 0) 703 System.Console.CursorLeft = 0; // Needed for mono
392 return; 704 System.Console.Write(" "); // Needed for mono
393 705
394 string cmd = matches[0].Value.Trim(delims); 706 y = System.Console.CursorTop;
395 string[] cmdparams = new string[matches.Count - 1]; 707 cmdline = new StringBuilder();
396 708
397 for (int i = 1; i < matches.Count; i++) 709 while(true)
398 { 710 {
399 cmdparams[i-1] = matches[i].Value.Trim(delims); 711 Show();
400 }
401 712
402 try 713 ConsoleKeyInfo key = System.Console.ReadKey(true);
403 { 714 char c = key.KeyChar;
404 RunCmd(cmd, cmdparams);
405 }
406 catch (Exception e)
407 {
408 m_log.ErrorFormat("[Console]: Command [{0}] failed with exception {1}", cmdline, e.ToString());
409 m_log.Error(e.StackTrace);
410 }
411 }
412 715
413 public string LineInfo 716 if (!Char.IsControl(c))
414 { 717 {
415 get 718 if (cp >= 318)
416 { 719 continue;
417 string result = String.Empty;
418 720
419 string stacktrace = Environment.StackTrace; 721 if (c == '?' && isCommand)
420 List<string> lines = new List<string>(stacktrace.Split(new string[] {"at "}, StringSplitOptions.None)); 722 {
723 ContextHelp();
724 continue;
725 }
421 726
422 if (lines.Count > 4) 727 cmdline.Insert(cp, c);
728 cp++;
729 }
730 else
423 { 731 {
424 lines.RemoveRange(0, 4); 732 switch (key.Key)
733 {
734 case ConsoleKey.Backspace:
735 if (cp == 0)
736 break;
737 cmdline.Remove(cp-1, 1);
738 cp--;
425 739
426 string tmpLine = lines[0]; 740 System.Console.CursorLeft = 0;
741 System.Console.CursorTop = y;
427 742
428 int inIndex = tmpLine.IndexOf(" in "); 743 System.Console.Write("{0}{1} ", prompt, cmdline);
429 744
430 if (inIndex > -1) 745 break;
431 { 746 case ConsoleKey.End:
432 result = tmpLine.Substring(0, inIndex); 747 cp = cmdline.Length;
748 break;
749 case ConsoleKey.Home:
750 cp = 0;
751 break;
752 case ConsoleKey.UpArrow:
753 if (historyLine < 1)
754 break;
755 historyLine--;
756 LockOutput();
757 cmdline = new StringBuilder(history[historyLine]);
758 cp = cmdline.Length;
759 UnlockOutput();
760 break;
761 case ConsoleKey.DownArrow:
762 if (historyLine >= history.Count)
763 break;
764 historyLine++;
765 LockOutput();
766 if (historyLine == history.Count)
767 cmdline = new StringBuilder();
768 else
769 cmdline = new StringBuilder(history[historyLine]);
770 cp = cmdline.Length;
771 UnlockOutput();
772 break;
773 case ConsoleKey.LeftArrow:
774 if (cp > 0)
775 cp--;
776 break;
777 case ConsoleKey.RightArrow:
778 if (cp < cmdline.Length)
779 cp++;
780 break;
781 case ConsoleKey.Enter:
782 System.Console.CursorLeft = 0;
783 System.Console.CursorTop = y;
784
785 System.Console.WriteLine("{0}{1}", prompt, cmdline);
433 786
434 int lineIndex = tmpLine.IndexOf(":line "); 787 y = -1;
435 788
436 if (lineIndex > -1) 789 if (isCommand)
437 { 790 {
438 lineIndex += 6; 791 string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
439 result += ", line " + tmpLine.Substring(lineIndex, (tmpLine.Length - lineIndex) - 5); 792
793 if (cmd.Length != 0)
794 {
795 int i;
796
797 for (i=0 ; i < cmd.Length ; i++)
798 {
799 if (cmd[i].Contains(" "))
800 cmd[i] = "\"" + cmd[i] + "\"";
801 }
802 AddToHistory(String.Join(" ", cmd));
803 return String.Empty;
804 }
440 } 805 }
806
807 AddToHistory(cmdline.ToString());
808 return cmdline.ToString();
809 default:
810 break;
441 } 811 }
442 } 812 }
443 return result;
444 } 813 }
445 } 814 }
446 } 815 }
diff --git a/OpenSim/Framework/Console/ConsoleCallbacksBase.cs b/OpenSim/Framework/Console/ConsoleCallbacksBase.cs
deleted file mode 100644
index d37c47a..0000000
--- a/OpenSim/Framework/Console/ConsoleCallbacksBase.cs
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Console
29{
30 public interface conscmd_callback
31 {
32 void RunCmd(string cmd, string[] cmdparams);
33 void Show(string[] showParams);
34 }
35}
diff --git a/OpenSim/Framework/Console/OpenSimAppender.cs b/OpenSim/Framework/Console/OpenSimAppender.cs
index b07617f..6193bac 100644
--- a/OpenSim/Framework/Console/OpenSimAppender.cs
+++ b/OpenSim/Framework/Console/OpenSimAppender.cs
@@ -37,6 +37,14 @@ namespace OpenSim.Framework.Console
37 /// </summary> 37 /// </summary>
38 public class OpenSimAppender : AnsiColorTerminalAppender 38 public class OpenSimAppender : AnsiColorTerminalAppender
39 { 39 {
40 private ConsoleBase m_console = null;
41
42 public ConsoleBase Console
43 {
44 get { return m_console; }
45 set { m_console = value; }
46 }
47
40 private static readonly ConsoleColor[] Colors = { 48 private static readonly ConsoleColor[] Colors = {
41 // the dark colors don't seem to be visible on some black background terminals like putty :( 49 // the dark colors don't seem to be visible on some black background terminals like putty :(
42 //ConsoleColor.DarkBlue, 50 //ConsoleColor.DarkBlue,
@@ -55,6 +63,9 @@ namespace OpenSim.Framework.Console
55 63
56 override protected void Append(LoggingEvent le) 64 override protected void Append(LoggingEvent le)
57 { 65 {
66 if (m_console != null)
67 m_console.LockOutput();
68
58 try 69 try
59 { 70 {
60 string loggingMessage = RenderLoggingEvent(le); 71 string loggingMessage = RenderLoggingEvent(le);
@@ -96,6 +107,11 @@ namespace OpenSim.Framework.Console
96 { 107 {
97 System.Console.WriteLine("Couldn't write out log message: {0}", e.ToString()); 108 System.Console.WriteLine("Couldn't write out log message: {0}", e.ToString());
98 } 109 }
110 finally
111 {
112 if (m_console != null)
113 m_console.UnlockOutput();
114 }
99 } 115 }
100 116
101 private void WriteColorText(ConsoleColor color, string sender) 117 private void WriteColorText(ConsoleColor color, string sender)
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index ce74b46..493c626 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -27,6 +27,7 @@
27 27
28using System.Collections.Generic; 28using System.Collections.Generic;
29using OpenMetaverse; 29using OpenMetaverse;
30using OpenSim.Framework.Console;
30 31
31namespace OpenSim.Framework 32namespace OpenSim.Framework
32{ 33{
@@ -88,5 +89,7 @@ namespace OpenSim.Framework
88 89
89 T RequestModuleInterface<T>(); 90 T RequestModuleInterface<T>();
90 T[] RequestModuleInterfaces<T>(); 91 T[] RequestModuleInterfaces<T>();
92
93 void AddCommand(string module, string command, string shorthelp, string longhelp, CommandDelegate callback);
91 } 94 }
92} 95}
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 473991a..cc75df4 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -98,7 +98,45 @@ namespace OpenSim.Framework.Servers
98 /// <summary> 98 /// <summary>
99 /// Must be overriden by child classes for their own server specific startup behaviour. 99 /// Must be overriden by child classes for their own server specific startup behaviour.
100 /// </summary> 100 /// </summary>
101 protected abstract void StartupSpecific(); 101 protected virtual void StartupSpecific()
102 {
103 if (m_console != null)
104 {
105 SetConsoleLogLevel(new string[] { "ALL" });
106
107 m_console.Commands.AddCommand("base", "quit",
108 "quit",
109 "Quit the application", HandleQuit);
110
111 m_console.Commands.AddCommand("base", "shutdown",
112 "shutdown",
113 "Quit the application", HandleQuit);
114
115 m_console.Commands.AddCommand("base", "set log level",
116 "set log level <level>",
117 "Set the console logging level", HandleLogLevel);
118
119 m_console.Commands.AddCommand("base", "show info",
120 "show info",
121 "Show general information", HandleShow);
122
123 m_console.Commands.AddCommand("base", "show stats",
124 "show stats",
125 "Show statistics", HandleShow);
126
127 m_console.Commands.AddCommand("base", "show threads",
128 "show threads",
129 "Show thread status", HandleShow);
130
131 m_console.Commands.AddCommand("base", "show uptime",
132 "show uptime",
133 "Show server uptime", HandleShow);
134
135 m_console.Commands.AddCommand("base", "show version",
136 "show version",
137 "Show server version", HandleShow);
138 }
139 }
102 140
103 /// <summary> 141 /// <summary>
104 /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing 142 /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
@@ -212,6 +250,8 @@ namespace OpenSim.Framework.Servers
212 return; 250 return;
213 } 251 }
214 252
253 consoleAppender.Console = m_console;
254
215 if (setParams.Length > 0) 255 if (setParams.Length > 0)
216 { 256 {
217 Level consoleLevel = repository.LevelMap[setParams[0]]; 257 Level consoleLevel = repository.LevelMap[setParams[0]];
@@ -261,56 +301,18 @@ namespace OpenSim.Framework.Servers
261 Environment.Exit(0); 301 Environment.Exit(0);
262 } 302 }
263 303
264 /// <summary> 304 private void HandleQuit(string module, string[] args)
265 /// Runs commands issued by the server console from the operator
266 /// </summary>
267 /// <param name="command">The first argument of the parameter (the command)</param>
268 /// <param name="cmdparams">Additional arguments passed to the command</param>
269 public virtual void RunCmd(string command, string[] cmdparams)
270 { 305 {
271 switch (command) 306 Shutdown();
272 {
273 case "help":
274 ShowHelp(cmdparams);
275 Notice("");
276 break;
277
278 case "set":
279 Set(cmdparams);
280 break;
281
282 case "show":
283 if (cmdparams.Length > 0)
284 {
285 Show(cmdparams);
286 }
287 break;
288
289 case "quit":
290 case "shutdown":
291 Shutdown();
292 break;
293 }
294 } 307 }
295 308
296 /// <summary> 309 private void HandleLogLevel(string module, string[] cmd)
297 /// Set an OpenSim parameter
298 /// </summary>
299 /// <param name="setArgs">
300 /// The arguments given to the set command.
301 /// </param>
302 public virtual void Set(string[] setArgs)
303 { 310 {
304 // Temporary while we only have one command which takes at least two parameters 311 if (cmd.Length > 3)
305 if (setArgs.Length < 2)
306 return;
307
308 if (setArgs[0] == "log" && setArgs[1] == "level")
309 { 312 {
310 string[] setParams = new string[setArgs.Length - 2]; 313 string level = cmd[3];
311 Array.Copy(setArgs, 2, setParams, 0, setArgs.Length - 2);
312 314
313 SetConsoleLogLevel(setParams); 315 SetConsoleLogLevel(new string[] { level });
314 } 316 }
315 } 317 }
316 318
@@ -324,18 +326,6 @@ namespace OpenSim.Framework.Servers
324 326
325 if (helpArgs.Length == 0) 327 if (helpArgs.Length == 0)
326 { 328 {
327 List<string> helpTopics = GetHelpTopics();
328
329 if (helpTopics.Count > 0)
330 {
331 Notice(
332 "As well as the help information below, you can also type help <topic> to get more information on the following areas:");
333 Notice(string.Format(" {0}", string.Join(", ", helpTopics.ToArray())));
334 Notice("");
335 }
336
337 Notice("quit - equivalent to shutdown.");
338
339 Notice("set log level [level] - change the console logging level only. For example, off or debug."); 329 Notice("set log level [level] - change the console logging level only. For example, off or debug.");
340 Notice("show info - show server information (e.g. startup path)."); 330 Notice("show info - show server information (e.g. startup path).");
341 331
@@ -345,21 +335,20 @@ namespace OpenSim.Framework.Servers
345 Notice("show threads - list tracked threads"); 335 Notice("show threads - list tracked threads");
346 Notice("show uptime - show server startup time and uptime."); 336 Notice("show uptime - show server startup time and uptime.");
347 Notice("show version - show server version."); 337 Notice("show version - show server version.");
348 Notice("shutdown - shutdown the server.");
349 Notice(""); 338 Notice("");
350 339
351 return; 340 return;
352 } 341 }
353 } 342 }
354 343
355 /// <summary> 344 public virtual void HandleShow(string module, string[] cmd)
356 /// Outputs to the console information about the region
357 /// </summary>
358 /// <param name="showParams">
359 /// What information to display (valid arguments are "uptime", "users", ...)
360 /// </param>
361 public virtual void Show(string[] showParams)
362 { 345 {
346 List<string> args = new List<string>(cmd);
347
348 args.RemoveAt(0);
349
350 string[] showParams = args.ToArray();
351
363 switch (showParams[0]) 352 switch (showParams[0])
364 { 353 {
365 case "info": 354 case "info":