diff options
author | Adam Frisby | 2008-03-30 09:03:38 +0000 |
---|---|---|
committer | Adam Frisby | 2008-03-30 09:03:38 +0000 |
commit | fadd19f3140107d7c09e7a82a97dfb490146ccb9 (patch) | |
tree | 3ce4581ef1af79d451f0b24ce50128f09482f386 /OpenSim/Region/Environment/Modules | |
parent | This update has good news and bad news, first the bad. (diff) | |
download | opensim-SC-fadd19f3140107d7c09e7a82a97dfb490146ccb9.zip opensim-SC-fadd19f3140107d7c09e7a82a97dfb490146ccb9.tar.gz opensim-SC-fadd19f3140107d7c09e7a82a97dfb490146ccb9.tar.bz2 opensim-SC-fadd19f3140107d7c09e7a82a97dfb490146ccb9.tar.xz |
**Big ass update warning**
* Renamed plugin console message, to send a message to a plugin, use either "plugin <message>", or any unrecognised message will be sent ("plugin" sends explicitly) This replaces the old "script <message>".
* Terrain commands - "terrain <command>" now works again. "Script terrain <command>" does not. Many of the commands have now been reimplemented, eg load-tile. However some have new syntax.
* New console command handler, you can now use things like "terrain help" or "terrain save help". See TerrainModule.cs for an example of how to use the new "Commander" class.
* Commander class - advanced processing of console input and also enables a script API to be generated from registered console commands.
Diffstat (limited to 'OpenSim/Region/Environment/Modules')
8 files changed, 574 insertions, 38 deletions
diff --git a/OpenSim/Region/Environment/Modules/CommanderTestModule.cs b/OpenSim/Region/Environment/Modules/CommanderTestModule.cs new file mode 100644 index 0000000..555944c --- /dev/null +++ b/OpenSim/Region/Environment/Modules/CommanderTestModule.cs | |||
@@ -0,0 +1,92 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | using Nini.Config; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Environment.Interfaces; | ||
34 | using OpenSim.Region.Environment.Scenes; | ||
35 | using OpenSim.Region.Environment.Modules.ModuleFramework; | ||
36 | |||
37 | namespace OpenSim.Region.Environment.Modules | ||
38 | { | ||
39 | public class CommanderTestModule : IRegionModule, ICommandableModule | ||
40 | { | ||
41 | Commander m_commander = new Commander("CommanderTest"); | ||
42 | Scene m_scene; | ||
43 | |||
44 | #region IRegionModule Members | ||
45 | |||
46 | public void Initialise(Scene scene, IConfigSource source) | ||
47 | { | ||
48 | m_scene = scene; | ||
49 | } | ||
50 | |||
51 | private void InterfaceHelloWorld(Object[] args) | ||
52 | { | ||
53 | Console.WriteLine("Hello World"); | ||
54 | } | ||
55 | |||
56 | public void PostInitialise() | ||
57 | { | ||
58 | Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string"); | ||
59 | testCommand.AddArgument("world", "Write world here", "string"); | ||
60 | |||
61 | m_commander.RegisterCommand("hello", testCommand); | ||
62 | |||
63 | // Register me | ||
64 | m_scene.RegisterModuleCommander("commandertest", m_commander); | ||
65 | } | ||
66 | |||
67 | public void Close() | ||
68 | { | ||
69 | } | ||
70 | |||
71 | public string Name | ||
72 | { | ||
73 | get { return "CommanderTestModule"; } | ||
74 | } | ||
75 | |||
76 | public bool IsSharedModule | ||
77 | { | ||
78 | get { return false; } | ||
79 | } | ||
80 | |||
81 | #endregion | ||
82 | |||
83 | #region ICommandableModule Members | ||
84 | |||
85 | public ICommander CommandInterface | ||
86 | { | ||
87 | get { throw new NotImplementedException(); } | ||
88 | } | ||
89 | |||
90 | #endregion | ||
91 | } | ||
92 | } | ||
diff --git a/OpenSim/Region/Environment/Modules/ModuleFramework/Commander.cs b/OpenSim/Region/Environment/Modules/ModuleFramework/Commander.cs new file mode 100644 index 0000000..a17348e --- /dev/null +++ b/OpenSim/Region/Environment/Modules/ModuleFramework/Commander.cs | |||
@@ -0,0 +1,271 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | using OpenSim.Region.Environment.Interfaces; | ||
6 | |||
7 | namespace OpenSim.Region.Environment.Modules.ModuleFramework | ||
8 | { | ||
9 | /// <summary> | ||
10 | /// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s. | ||
11 | /// Used for console commands and script API generation | ||
12 | /// </summary> | ||
13 | public class Command : ICommand | ||
14 | { | ||
15 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
16 | |||
17 | private Action<Object[]> m_command; | ||
18 | private string m_name; | ||
19 | private string m_help; | ||
20 | private List<CommandArgument> m_args = new List<CommandArgument>(); | ||
21 | |||
22 | public Command(string name, Action<Object[]> command, string help) | ||
23 | { | ||
24 | m_name = name; | ||
25 | m_command = command; | ||
26 | m_help = help; | ||
27 | } | ||
28 | |||
29 | public void AddArgument(string name, string helptext, string type) | ||
30 | { | ||
31 | m_args.Add(new CommandArgument(name, helptext, type)); | ||
32 | } | ||
33 | |||
34 | public string Name | ||
35 | { | ||
36 | get { return m_name; } | ||
37 | } | ||
38 | |||
39 | public string Help | ||
40 | { | ||
41 | get { return m_help; } | ||
42 | } | ||
43 | |||
44 | public Dictionary<string, string> Arguments | ||
45 | { | ||
46 | get | ||
47 | { | ||
48 | Dictionary<string, string> tmp = new Dictionary<string, string>(); | ||
49 | foreach (CommandArgument arg in m_args) | ||
50 | { | ||
51 | tmp.Add(arg.Name, arg.ArgumentType); | ||
52 | } | ||
53 | return tmp; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | public void ShowConsoleHelp() | ||
58 | { | ||
59 | m_log.Info("== " + Name + " =="); | ||
60 | m_log.Info(m_help); | ||
61 | m_log.Info("= Parameters ="); | ||
62 | foreach (CommandArgument arg in m_args) | ||
63 | { | ||
64 | m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")"); | ||
65 | m_log.Info("\t" + arg.HelpText); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | public void Run(Object[] args) | ||
70 | { | ||
71 | Object[] cleanArgs = new Object[m_args.Count]; | ||
72 | |||
73 | if (args.Length < cleanArgs.Length) | ||
74 | { | ||
75 | m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)"); | ||
76 | ShowConsoleHelp(); | ||
77 | return; | ||
78 | } | ||
79 | if (args.Length > cleanArgs.Length) | ||
80 | { | ||
81 | m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help."); | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | int i = 0; | ||
86 | foreach (Object arg in args) | ||
87 | { | ||
88 | if (string.IsNullOrEmpty(arg.ToString())) | ||
89 | { | ||
90 | m_log.Error("Empty arguments are not allowed"); | ||
91 | return; | ||
92 | } | ||
93 | try | ||
94 | { | ||
95 | switch (m_args[i].ArgumentType) | ||
96 | { | ||
97 | case "String": | ||
98 | m_args[i].ArgumentValue = arg.ToString(); | ||
99 | break; | ||
100 | case "Integer": | ||
101 | m_args[i].ArgumentValue = Int32.Parse(arg.ToString()); | ||
102 | break; | ||
103 | case "Double": | ||
104 | m_args[i].ArgumentValue = Double.Parse(arg.ToString()); | ||
105 | break; | ||
106 | case "Boolean": | ||
107 | m_args[i].ArgumentValue = Boolean.Parse(arg.ToString()); | ||
108 | break; | ||
109 | default: | ||
110 | m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name); | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | catch (FormatException) | ||
115 | { | ||
116 | m_log.Error("Argument number " + (i + 1) + | ||
117 | " (" + m_args[i].Name + ") must be a valid " + | ||
118 | m_args[i].ArgumentType.ToLower() + "."); | ||
119 | } | ||
120 | cleanArgs[i] = m_args[i].ArgumentValue; | ||
121 | |||
122 | i++; | ||
123 | } | ||
124 | |||
125 | m_command.Invoke(cleanArgs); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | /// <summary> | ||
130 | /// A single command argument, contains name, type and at runtime, value. | ||
131 | /// </summary> | ||
132 | public class CommandArgument | ||
133 | { | ||
134 | private string m_name; | ||
135 | private string m_help; | ||
136 | private string m_type; | ||
137 | private Object m_val; | ||
138 | |||
139 | public CommandArgument(string name, string help, string type) | ||
140 | { | ||
141 | m_name = name; | ||
142 | m_help = help; | ||
143 | m_type = type; | ||
144 | } | ||
145 | |||
146 | public string Name | ||
147 | { | ||
148 | get { return m_name; } | ||
149 | } | ||
150 | |||
151 | public string HelpText | ||
152 | { | ||
153 | get { return m_help; } | ||
154 | } | ||
155 | |||
156 | public string ArgumentType | ||
157 | { | ||
158 | get { return m_type; } | ||
159 | } | ||
160 | |||
161 | public Object ArgumentValue | ||
162 | { | ||
163 | get { return m_val; } | ||
164 | set { m_val = value; } | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /// <summary> | ||
169 | /// A class to enable modules to register console and script commands, which enforces typing and valid input. | ||
170 | /// </summary> | ||
171 | public class Commander : ICommander | ||
172 | { | ||
173 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
174 | private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>(); | ||
175 | private string m_name; | ||
176 | |||
177 | public Commander(string name) | ||
178 | { | ||
179 | m_name = name; | ||
180 | } | ||
181 | |||
182 | public void RegisterCommand(string commandName, ICommand command) | ||
183 | { | ||
184 | m_commands[commandName] = command; | ||
185 | } | ||
186 | |||
187 | void ShowConsoleHelp() | ||
188 | { | ||
189 | m_log.Info("===" + m_name + "==="); | ||
190 | foreach (ICommand com in m_commands.Values) | ||
191 | { | ||
192 | m_log.Info("* " + com.Name + " - " + com.Help); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | string EscapeRuntimeAPICommand(string command) | ||
197 | { | ||
198 | command = command.Replace('-', '_'); | ||
199 | StringBuilder tmp = new StringBuilder(command); | ||
200 | tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0]; | ||
201 | |||
202 | return tmp.ToString(); | ||
203 | } | ||
204 | |||
205 | /// <summary> | ||
206 | /// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands | ||
207 | /// </summary> | ||
208 | /// <returns>Returns C# source code to create a binding</returns> | ||
209 | public string GenerateRuntimeAPI() | ||
210 | { | ||
211 | string classSrc = "\n\tpublic class " + m_name + " {\n"; | ||
212 | foreach (ICommand com in m_commands.Values) | ||
213 | { | ||
214 | classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( "; | ||
215 | foreach (KeyValuePair<string, string> arg in com.Arguments) | ||
216 | { | ||
217 | classSrc += arg.Value + " " + Framework.Util.Md5Hash(arg.Key) + ","; | ||
218 | } | ||
219 | classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma | ||
220 | classSrc += " )\n\t{\n"; | ||
221 | classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n"; | ||
222 | int i = 0; | ||
223 | foreach (KeyValuePair<string, string> arg in com.Arguments) | ||
224 | { | ||
225 | classSrc += "\t\targs[" + i.ToString() + "] = " + Framework.Util.Md5Hash(arg.Key) + " " + ";\n"; | ||
226 | i++; | ||
227 | } | ||
228 | classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n"; | ||
229 | classSrc += "\t}\n"; | ||
230 | } | ||
231 | classSrc += "}\n"; | ||
232 | |||
233 | return classSrc; | ||
234 | } | ||
235 | |||
236 | /// <summary> | ||
237 | /// Runs a specified function with attached arguments | ||
238 | /// *** <b>DO NOT CALL DIRECTLY.</b> *** | ||
239 | /// Call ProcessConsoleCommand instead if handling human input. | ||
240 | /// </summary> | ||
241 | /// <param name="function">The function name to call</param> | ||
242 | /// <param name="args">The function parameters</param> | ||
243 | public void Run(string function, object[] args) | ||
244 | { | ||
245 | m_commands[function].Run(args); | ||
246 | } | ||
247 | |||
248 | public void ProcessConsoleCommand(string function, string[] args) | ||
249 | { | ||
250 | if (m_commands.ContainsKey(function)) | ||
251 | { | ||
252 | if (args[0] == "help") | ||
253 | { | ||
254 | m_commands[function].ShowConsoleHelp(); | ||
255 | } | ||
256 | else | ||
257 | { | ||
258 | m_commands[function].Run(args); | ||
259 | } | ||
260 | } | ||
261 | else | ||
262 | { | ||
263 | if (function != "help") | ||
264 | m_log.Error("Invalid command - No such command exists"); | ||
265 | if (function == "api") | ||
266 | m_log.Info(GenerateRuntimeAPI()); | ||
267 | ShowConsoleHelp(); | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | } | ||
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs index f2bdde7..d6430cd 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs | |||
@@ -41,6 +41,16 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders | |||
41 | throw new NotImplementedException(); | 41 | throw new NotImplementedException(); |
42 | } | 42 | } |
43 | 43 | ||
44 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) | ||
45 | { | ||
46 | throw new NotImplementedException(); | ||
47 | } | ||
48 | |||
49 | public override string ToString() | ||
50 | { | ||
51 | return "JPEG"; | ||
52 | } | ||
53 | |||
44 | private Bitmap CreateBitmapFromMap(ITerrainChannel map) | 54 | private Bitmap CreateBitmapFromMap(ITerrainChannel map) |
45 | { | 55 | { |
46 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); | 56 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); |
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs index 2d7d94f..7436dc5 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs | |||
@@ -58,6 +58,16 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders | |||
58 | return retval; | 58 | return retval; |
59 | } | 59 | } |
60 | 60 | ||
61 | public override string ToString() | ||
62 | { | ||
63 | return "LL/SL RAW"; | ||
64 | } | ||
65 | |||
66 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) | ||
67 | { | ||
68 | throw new NotImplementedException(); | ||
69 | } | ||
70 | |||
61 | public void SaveFile(string filename, ITerrainChannel map) | 71 | public void SaveFile(string filename, ITerrainChannel map) |
62 | { | 72 | { |
63 | FileInfo file = new FileInfo(filename); | 73 | FileInfo file = new FileInfo(filename); |
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs index ba430b7..fc81376 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs | |||
@@ -57,6 +57,43 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders | |||
57 | return retval; | 57 | return retval; |
58 | } | 58 | } |
59 | 59 | ||
60 | public override string ToString() | ||
61 | { | ||
62 | return "RAW32"; | ||
63 | } | ||
64 | |||
65 | public ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight) | ||
66 | { | ||
67 | TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight); | ||
68 | |||
69 | FileInfo file = new FileInfo(filename); | ||
70 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); | ||
71 | BinaryReader bs = new BinaryReader(s); | ||
72 | |||
73 | // Advance to our section of the file | ||
74 | if (fileStartY * sectionHeight > 0) | ||
75 | bs.ReadBytes(fileStartY * sectionHeight); | ||
76 | |||
77 | int x, y; | ||
78 | for (y = 0; y < retval.Height; y++) | ||
79 | { | ||
80 | // Advance the stream if we aren't at the start of the section in the file | ||
81 | if (fileStartX * sectionWidth > 0) | ||
82 | bs.ReadBytes(fileStartX * sectionHeight); | ||
83 | |||
84 | for (x = 0; x < retval.Width; x++) | ||
85 | { | ||
86 | // Read a strip and continue | ||
87 | retval[x, y] = bs.ReadSingle(); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | bs.Close(); | ||
92 | s.Close(); | ||
93 | |||
94 | return retval; | ||
95 | } | ||
96 | |||
60 | public void SaveFile(string filename, ITerrainChannel map) | 97 | public void SaveFile(string filename, ITerrainChannel map) |
61 | { | 98 | { |
62 | FileInfo file = new FileInfo(filename); | 99 | FileInfo file = new FileInfo(filename); |
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs index e136397..6a3c354 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs | |||
@@ -107,6 +107,16 @@ namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders | |||
107 | throw new NotImplementedException(); | 107 | throw new NotImplementedException(); |
108 | } | 108 | } |
109 | 109 | ||
110 | public override string ToString() | ||
111 | { | ||
112 | return "Terragen"; | ||
113 | } | ||
114 | |||
115 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) | ||
116 | { | ||
117 | throw new NotImplementedException(); | ||
118 | } | ||
119 | |||
110 | #endregion | 120 | #endregion |
111 | } | 121 | } |
112 | } | 122 | } |
diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs index 9b713f5..2c391df 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs | |||
@@ -32,6 +32,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
32 | public interface ITerrainLoader | 32 | public interface ITerrainLoader |
33 | { | 33 | { |
34 | ITerrainChannel LoadFile(string filename); | 34 | ITerrainChannel LoadFile(string filename); |
35 | ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight); | ||
35 | void SaveFile(string filename, ITerrainChannel map); | 36 | void SaveFile(string filename, ITerrainChannel map); |
36 | } | 37 | } |
37 | } | 38 | } |
diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs index 742ea5b..745118b 100644 --- a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs | |||
@@ -33,11 +33,12 @@ using Nini.Config; | |||
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | using OpenSim.Region.Environment.Modules.ModuleFramework; | ||
36 | 37 | ||
37 | 38 | ||
38 | namespace OpenSim.Region.Environment.Modules.Terrain | 39 | namespace OpenSim.Region.Environment.Modules.Terrain |
39 | { | 40 | { |
40 | public class TerrainModule : IRegionModule , ITerrainTemp | 41 | public class TerrainModule : IRegionModule , ITerrainTemp, ICommandableModule |
41 | { | 42 | { |
42 | public enum StandardTerrainEffects : byte | 43 | public enum StandardTerrainEffects : byte |
43 | { | 44 | { |
@@ -51,6 +52,8 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
51 | 52 | ||
52 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 53 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
53 | 54 | ||
55 | private Commander m_commander = new Commander("Terrain"); | ||
56 | |||
54 | private Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = | 57 | private Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = |
55 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); | 58 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); |
56 | private Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = | 59 | private Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = |
@@ -109,7 +112,44 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
109 | { | 112 | { |
110 | lock (m_scene) | 113 | lock (m_scene) |
111 | { | 114 | { |
112 | ITerrainChannel channel = loader.Value.LoadFile(filename); | 115 | try |
116 | { | ||
117 | ITerrainChannel channel = loader.Value.LoadFile(filename); | ||
118 | m_scene.Heightmap = channel; | ||
119 | m_channel = channel; | ||
120 | UpdateRevertMap(); | ||
121 | } | ||
122 | catch (NotImplementedException) | ||
123 | { | ||
124 | m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value.ToString() + " parser does not support file loading. (May be save only)"); | ||
125 | return; | ||
126 | } | ||
127 | catch (System.IO.FileNotFoundException) | ||
128 | { | ||
129 | m_log.Error("[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); | ||
130 | return; | ||
131 | } | ||
132 | } | ||
133 | m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); | ||
134 | return; | ||
135 | } | ||
136 | } | ||
137 | m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format."); | ||
138 | } | ||
139 | |||
140 | public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) | ||
141 | { | ||
142 | fileStartX -= (int)m_scene.RegionInfo.RegionLocX; | ||
143 | fileStartY -= (int)m_scene.RegionInfo.RegionLocY; | ||
144 | |||
145 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | ||
146 | { | ||
147 | if (filename.EndsWith(loader.Key)) | ||
148 | { | ||
149 | lock (m_scene) | ||
150 | { | ||
151 | ITerrainChannel channel = loader.Value.LoadFile(filename, fileStartX, fileStartY, | ||
152 | fileWidth, fileHeight, (int)Constants.RegionSize, (int)Constants.RegionSize); | ||
113 | m_scene.Heightmap = channel; | 153 | m_scene.Heightmap = channel; |
114 | m_channel = channel; | 154 | m_channel = channel; |
115 | UpdateRevertMap(); | 155 | UpdateRevertMap(); |
@@ -177,46 +217,101 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
177 | } | 217 | } |
178 | } | 218 | } |
179 | 219 | ||
180 | void EventManager_OnPluginConsole(string[] args) | 220 | #region Console Commands |
221 | |||
222 | private void InterfaceLoadFile(Object[] args) | ||
181 | { | 223 | { |
182 | if (args[0] == "terrain") | 224 | LoadFromFile((string)args[0]); |
225 | } | ||
226 | |||
227 | private void InterfaceLoadTileFile(Object[] args) | ||
228 | { | ||
229 | LoadFromFile((string)args[0], | ||
230 | (int)args[1], | ||
231 | (int)args[2], | ||
232 | (int)args[3], | ||
233 | (int)args[4]); | ||
234 | } | ||
235 | |||
236 | private void InterfaceSaveFile(Object[] args) | ||
237 | { | ||
238 | SaveToFile((string)args[0]); | ||
239 | } | ||
240 | |||
241 | private void InterfaceFillTerrain(Object[] args) | ||
242 | { | ||
243 | int x, y; | ||
244 | |||
245 | for (x = 0; x < m_channel.Width; x++) | ||
246 | for (y = 0; y < m_channel.Height; y++) | ||
247 | m_channel[x, y] = (double)args[0]; | ||
248 | SendUpdatedLayerData(); | ||
249 | } | ||
250 | |||
251 | private void InterfaceEnableExperimentalBrushes(Object[] args) | ||
252 | { | ||
253 | if ((bool)args[0]) | ||
183 | { | 254 | { |
184 | string command = args[1]; | 255 | m_painteffects[StandardTerrainEffects.Revert] = new PaintBrushes.WeatherSphere(); |
185 | string param = args[2]; | 256 | m_painteffects[StandardTerrainEffects.Flatten] = new PaintBrushes.OlsenSphere(); |
257 | m_painteffects[StandardTerrainEffects.Smooth] = new PaintBrushes.ErodeSphere(); | ||
258 | } | ||
259 | else | ||
260 | { | ||
261 | InstallDefaultEffects(); | ||
262 | } | ||
263 | } | ||
186 | 264 | ||
187 | int x, y; | 265 | private void InstallInterfaces() |
266 | { | ||
267 | // Load / Save | ||
268 | string supportedFileExtensions = ""; | ||
269 | foreach (KeyValuePair<string,ITerrainLoader> loader in m_loaders) | ||
270 | supportedFileExtensions += " " + loader.Key + " (" + loader.Value.ToString() + ")"; | ||
271 | |||
272 | Command loadFromFileCommand = new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file."); | ||
273 | loadFromFileCommand.AddArgument("filename", "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + supportedFileExtensions, "String"); | ||
274 | |||
275 | Command saveToFileCommand = new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file."); | ||
276 | saveToFileCommand.AddArgument("filename", "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " + supportedFileExtensions, "String"); | ||
277 | |||
278 | Command loadFromTileCommand = new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file."); | ||
279 | loadFromTileCommand.AddArgument("filename", "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + supportedFileExtensions, "String"); | ||
280 | loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); | ||
281 | loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); | ||
282 | loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", "Integer"); | ||
283 | loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", "Integer"); | ||
284 | |||
285 | // Terrain adjustments | ||
286 | Command fillRegionCommand = new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value."); | ||
287 | fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.", "Double"); | ||
288 | |||
289 | // Brushes | ||
290 | Command experimentalBrushesCommand = new Command("newbrushes", InterfaceEnableExperimentalBrushes, "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); | ||
291 | experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean"); | ||
292 | |||
293 | m_commander.RegisterCommand("load", loadFromFileCommand); | ||
294 | m_commander.RegisterCommand("load-tile", loadFromTileCommand); | ||
295 | m_commander.RegisterCommand("save", saveToFileCommand); | ||
296 | m_commander.RegisterCommand("fill", fillRegionCommand); | ||
297 | m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand); | ||
298 | |||
299 | // Add this to our scene so scripts can call these functions | ||
300 | //TMPm_scene.RegisterModuleCommander("Terrain", m_commander); | ||
301 | } | ||
188 | 302 | ||
189 | switch (command) | 303 | #endregion |
190 | { | 304 | |
191 | case "load": | 305 | void EventManager_OnPluginConsole(string[] args) |
192 | LoadFromFile(param); | 306 | { |
193 | SendUpdatedLayerData(); | 307 | if (args[0] == "terrain") |
194 | break; | 308 | { |
195 | case "save": | 309 | string[] tmpArgs = new string[args.Length - 2]; |
196 | SaveToFile(param); | 310 | int i = 0; |
197 | break; | 311 | for (i = 2; i < args.Length; i++) |
198 | case "fill": | 312 | tmpArgs[i - 2] = args[i]; |
199 | for (x = 0; x < m_channel.Width; x++) | 313 | |
200 | for (y = 0; y < m_channel.Height; y++) | 314 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); |
201 | m_channel[x, y] = Double.Parse(param); | ||
202 | SendUpdatedLayerData(); | ||
203 | break; | ||
204 | case "newbrushes": | ||
205 | if (Boolean.Parse(param)) | ||
206 | { | ||
207 | m_painteffects[StandardTerrainEffects.Revert] = new PaintBrushes.WeatherSphere(); | ||
208 | m_painteffects[StandardTerrainEffects.Flatten] = new PaintBrushes.OlsenSphere(); | ||
209 | m_painteffects[StandardTerrainEffects.Smooth] = new PaintBrushes.ErodeSphere(); | ||
210 | } | ||
211 | else | ||
212 | { | ||
213 | InstallDefaultEffects(); | ||
214 | } | ||
215 | break; | ||
216 | default: | ||
217 | m_log.Warn("Unknown terrain command."); | ||
218 | break; | ||
219 | } | ||
220 | } | 315 | } |
221 | } | 316 | } |
222 | 317 | ||
@@ -363,6 +458,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
363 | public void PostInitialise() | 458 | public void PostInitialise() |
364 | { | 459 | { |
365 | InstallDefaultEffects(); | 460 | InstallDefaultEffects(); |
461 | InstallInterfaces(); | ||
366 | } | 462 | } |
367 | 463 | ||
368 | public void Close() | 464 | public void Close() |
@@ -378,5 +474,14 @@ namespace OpenSim.Region.Environment.Modules.Terrain | |||
378 | { | 474 | { |
379 | get { return false; } | 475 | get { return false; } |
380 | } | 476 | } |
477 | |||
478 | #region ICommandable Members | ||
479 | |||
480 | public ICommander CommandInterface | ||
481 | { | ||
482 | get { return m_commander; } | ||
483 | } | ||
484 | |||
485 | #endregion | ||
381 | } | 486 | } |
382 | } | 487 | } |