aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Framework/Commander.cs
diff options
context:
space:
mode:
authorAdam Frisby2008-04-30 21:22:29 +0000
committerAdam Frisby2008-04-30 21:22:29 +0000
commit4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6 (patch)
tree49dde0575502e89aeed428b4190c68306e929b69 /OpenSim/Region/Environment/Modules/Framework/Commander.cs
parent* Previous commit managed to miss some files despite me hitting 'Select all'. (diff)
downloadopensim-SC-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.zip
opensim-SC-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.tar.gz
opensim-SC-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.tar.bz2
opensim-SC-4a8c1e4393ac64c84b03aeb16bacb9ddd0a2fae6.tar.xz
* Commiting a bunch of missed files.
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Framework/Commander.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Framework/Commander.cs308
1 files changed, 308 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Framework/Commander.cs b/OpenSim/Region/Environment/Modules/Framework/Commander.cs
new file mode 100644
index 0000000..6cf8298
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Framework/Commander.cs
@@ -0,0 +1,308 @@
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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces;
35
36namespace OpenSim.Region.Environment.Modules.Framework
37{
38 /// <summary>
39 /// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s.
40 /// Used for console commands and script API generation
41 /// </summary>
42 public class Command : ICommand
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private List<CommandArgument> m_args = new List<CommandArgument>();
46
47 private Action<object[]> m_command;
48 private string m_help;
49 private string m_name;
50
51 public Command(string name, Action<Object[]> command, string help)
52 {
53 m_name = name;
54 m_command = command;
55 m_help = help;
56 }
57
58 #region ICommand Members
59
60 public void AddArgument(string name, string helptext, string type)
61 {
62 m_args.Add(new CommandArgument(name, helptext, type));
63 }
64
65 public string Name
66 {
67 get { return m_name; }
68 }
69
70 public string Help
71 {
72 get { return m_help; }
73 }
74
75 public Dictionary<string, string> Arguments
76 {
77 get
78 {
79 Dictionary<string, string> tmp = new Dictionary<string, string>();
80 foreach (CommandArgument arg in m_args)
81 {
82 tmp.Add(arg.Name, arg.ArgumentType);
83 }
84 return tmp;
85 }
86 }
87
88 public void ShowConsoleHelp()
89 {
90 m_log.Info("== " + Name + " ==");
91 m_log.Info(m_help);
92 m_log.Info("= Parameters =");
93 foreach (CommandArgument arg in m_args)
94 {
95 m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")");
96 m_log.Info("\t" + arg.HelpText);
97 }
98 }
99
100 public void Run(Object[] args)
101 {
102 Object[] cleanArgs = new Object[m_args.Count];
103
104 if (args.Length < cleanArgs.Length)
105 {
106 m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)");
107 ShowConsoleHelp();
108 return;
109 }
110 if (args.Length > cleanArgs.Length)
111 {
112 m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help.");
113 return;
114 }
115
116 int i = 0;
117 foreach (Object arg in args)
118 {
119 if (string.IsNullOrEmpty(arg.ToString()))
120 {
121 m_log.Error("Empty arguments are not allowed");
122 return;
123 }
124 try
125 {
126 switch (m_args[i].ArgumentType)
127 {
128 case "String":
129 m_args[i].ArgumentValue = arg.ToString();
130 break;
131 case "Integer":
132 m_args[i].ArgumentValue = Int32.Parse(arg.ToString());
133 break;
134 case "Double":
135 m_args[i].ArgumentValue = Double.Parse(arg.ToString());
136 break;
137 case "Boolean":
138 m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
139 break;
140 default:
141 m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
142 break;
143 }
144 }
145 catch (FormatException)
146 {
147 m_log.Error("Argument number " + (i + 1) +
148 " (" + m_args[i].Name + ") must be a valid " +
149 m_args[i].ArgumentType.ToLower() + ".");
150 }
151 cleanArgs[i] = m_args[i].ArgumentValue;
152
153 i++;
154 }
155
156 m_command.Invoke(cleanArgs);
157 }
158
159 #endregion
160 }
161
162 /// <summary>
163 /// A single command argument, contains name, type and at runtime, value.
164 /// </summary>
165 public class CommandArgument
166 {
167 private string m_help;
168 private string m_name;
169 private string m_type;
170 private Object m_val;
171
172 public CommandArgument(string name, string help, string type)
173 {
174 m_name = name;
175 m_help = help;
176 m_type = type;
177 }
178
179 public string Name
180 {
181 get { return m_name; }
182 }
183
184 public string HelpText
185 {
186 get { return m_help; }
187 }
188
189 public string ArgumentType
190 {
191 get { return m_type; }
192 }
193
194 public Object ArgumentValue
195 {
196 get { return m_val; }
197 set { m_val = value; }
198 }
199 }
200
201 /// <summary>
202 /// A class to enable modules to register console and script commands, which enforces typing and valid input.
203 /// </summary>
204 public class Commander : ICommander
205 {
206 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
207 private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>();
208 private string m_name;
209
210 public Commander(string name)
211 {
212 m_name = name;
213 }
214
215 #region ICommander Members
216
217 public void RegisterCommand(string commandName, ICommand command)
218 {
219 m_commands[commandName] = command;
220 }
221
222 /// <summary>
223 /// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands
224 /// </summary>
225 /// <returns>Returns C# source code to create a binding</returns>
226 public string GenerateRuntimeAPI()
227 {
228 string classSrc = "\n\tpublic class " + m_name + " {\n";
229 foreach (ICommand com in m_commands.Values)
230 {
231 classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( ";
232 foreach (KeyValuePair<string, string> arg in com.Arguments)
233 {
234 classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ",";
235 }
236 classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma
237 classSrc += " )\n\t{\n";
238 classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n";
239 int i = 0;
240 foreach (KeyValuePair<string, string> arg in com.Arguments)
241 {
242 classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n";
243 i++;
244 }
245 classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n";
246 classSrc += "\t}\n";
247 }
248 classSrc += "}\n";
249
250 return classSrc;
251 }
252
253 /// <summary>
254 /// Runs a specified function with attached arguments
255 /// *** <b>DO NOT CALL DIRECTLY.</b> ***
256 /// Call ProcessConsoleCommand instead if handling human input.
257 /// </summary>
258 /// <param name="function">The function name to call</param>
259 /// <param name="args">The function parameters</param>
260 public void Run(string function, object[] args)
261 {
262 m_commands[function].Run(args);
263 }
264
265 public void ProcessConsoleCommand(string function, string[] args)
266 {
267 if (m_commands.ContainsKey(function))
268 {
269 if (args.Length > 0 && args[0] == "help")
270 {
271 m_commands[function].ShowConsoleHelp();
272 }
273 else
274 {
275 m_commands[function].Run(args);
276 }
277 }
278 else
279 {
280 if (function != "help")
281 m_log.Error("Invalid command - No such command exists");
282 if (function == "api")
283 m_log.Info(GenerateRuntimeAPI());
284 ShowConsoleHelp();
285 }
286 }
287
288 #endregion
289
290 private void ShowConsoleHelp()
291 {
292 m_log.Info("===" + m_name + "===");
293 foreach (ICommand com in m_commands.Values)
294 {
295 m_log.Info("* " + com.Name + " - " + com.Help);
296 }
297 }
298
299 private string EscapeRuntimeAPICommand(string command)
300 {
301 command = command.Replace('-', '_');
302 StringBuilder tmp = new StringBuilder(command);
303 tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0];
304
305 return tmp.ToString();
306 }
307 }
308} \ No newline at end of file