aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Console/CommandConsole.cs22
-rw-r--r--OpenSim/Framework/RegionInfo.cs6
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs15
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs73
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs9
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs85
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs254
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs39
11 files changed, 409 insertions, 136 deletions
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs
index 2bb7de1..c5d6b78 100644
--- a/OpenSim/Framework/Console/CommandConsole.cs
+++ b/OpenSim/Framework/Console/CommandConsole.cs
@@ -188,19 +188,21 @@ namespace OpenSim.Framework.Console
188 { 188 {
189 lock (m_modulesCommands) 189 lock (m_modulesCommands)
190 { 190 {
191 if (m_modulesCommands.ContainsKey(moduleName)) 191 foreach (string key in m_modulesCommands.Keys)
192 { 192 {
193 List<CommandInfo> commands = m_modulesCommands[moduleName]; 193 // Allow topic help requests to succeed whether they are upper or lowercase.
194 var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help)); 194 if (moduleName.ToLower() == key.ToLower())
195 ourHelpText.Sort(); 195 {
196 helpText.AddRange(ourHelpText); 196 List<CommandInfo> commands = m_modulesCommands[key];
197 var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
198 ourHelpText.Sort();
199 helpText.AddRange(ourHelpText);
197 200
198 return true; 201 return true;
199 } 202 }
200 else
201 {
202 return false;
203 } 203 }
204
205 return false;
204 } 206 }
205 } 207 }
206 208
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 5ba3863..a505524 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -421,12 +421,18 @@ namespace OpenSim.Framework
421 set { m_internalEndPoint = value; } 421 set { m_internalEndPoint = value; }
422 } 422 }
423 423
424 /// <summary>
425 /// The x co-ordinate of this region in map tiles (e.g. 1000).
426 /// </summary>
424 public uint RegionLocX 427 public uint RegionLocX
425 { 428 {
426 get { return m_regionLocX.Value; } 429 get { return m_regionLocX.Value; }
427 set { m_regionLocX = value; } 430 set { m_regionLocX = value; }
428 } 431 }
429 432
433 /// <summary>
434 /// The y co-ordinate of this region in map tiles (e.g. 1000).
435 /// </summary>
430 public uint RegionLocY 436 public uint RegionLocY
431 { 437 {
432 get { return m_regionLocY.Value; } 438 get { return m_regionLocY.Value; }
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 484159c..5de3f25 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -248,15 +248,16 @@ namespace OpenSim
248 { 248 {
249 string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1); 249 string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
250 250
251 // This is a hack to allow the user to enter the help command in upper or lowercase. This will go
252 // away at some point.
253 m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
254 "help " + capitalizedTopic,
255 "Get help on plugin command '" + topic + "'",
256 HandleCommanderHelp);
251 m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic, 257 m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
252 "help " + capitalizedTopic, 258 "help " + capitalizedTopic,
253 "Get help on plugin command '" + topic + "'", 259 "Get help on plugin command '" + topic + "'",
254 HandleCommanderHelp); 260 HandleCommanderHelp);
255//
256// m_console.Commands.AddCommand("General", false, topic,
257// topic,
258// "Execute subcommand for plugin '" + topic + "'",
259// null);
260 261
261 ICommander commander = null; 262 ICommander commander = null;
262 263
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
index 21a9999..58925fd 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
@@ -132,13 +132,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
132 { 132 {
133 // We need to do this because: 133 // We need to do this because:
134 // "Saving the image to the same file it was constructed from is not allowed and throws an exception." 134 // "Saving the image to the same file it was constructed from is not allowed and throws an exception."
135 string tempName = offsetX + "_ " + offsetY + "_" + filename; 135 string tempName = Path.GetTempFileName();
136 136
137 Bitmap entireBitmap = null; 137 Bitmap entireBitmap = null;
138 Bitmap thisBitmap = null; 138 Bitmap thisBitmap = null;
139 if (File.Exists(filename)) 139 if (File.Exists(filename))
140 { 140 {
141 File.Copy(filename, tempName); 141 File.Copy(filename, tempName, true);
142 entireBitmap = new Bitmap(tempName); 142 entireBitmap = new Bitmap(tempName);
143 if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) 143 if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY)
144 { 144 {
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
152 } 152 }
153 153
154 thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); 154 thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
155 Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); 155// Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
156 for (int x = 0; x < regionSizeX; x++) 156 for (int x = 0; x < regionSizeX; x++)
157 for (int y = 0; y < regionSizeY; y++) 157 for (int y = 0; y < regionSizeY; y++)
158 entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); 158 entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));
diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
index 7237f90..d407617 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
@@ -38,6 +38,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain
38 ITerrainChannel LoadStream(Stream stream); 38 ITerrainChannel LoadStream(Stream stream);
39 void SaveFile(string filename, ITerrainChannel map); 39 void SaveFile(string filename, ITerrainChannel map);
40 void SaveStream(Stream stream, ITerrainChannel map); 40 void SaveStream(Stream stream, ITerrainChannel map);
41
42 /// <summary>
43 /// Save a number of map tiles to a single big image file.
44 /// </summary>
45 /// <remarks>
46 /// If the image file already exists then the tiles saved will replace those already in the file - other tiles
47 /// will be untouched.
48 /// </remarks>
49 /// <param name="filename">The terrain file to save</param>
50 /// <param name="offsetX">The map x co-ordinate at which to begin the save.</param>
51 /// <param name="offsetY">The may y co-ordinate at which to begin the save.</param>
52 /// <param name="fileWidth">The number of tiles to save along the X axis.</param>
53 /// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
54 /// <param name="regionSizeX">The width of a map tile.</param>
55 /// <param name="regionSizeY">The height of a map tile.</param>
41 void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY); 56 void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY);
42 } 57 }
43} \ No newline at end of file 58} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 9cd8f2b..17e9737 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -561,49 +561,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
561 } 561 }
562 562
563 /// <summary> 563 /// <summary>
564 /// Saves the terrain to a larger terrain file. 564 /// Save a number of map tiles to a single big image file.
565 /// </summary> 565 /// </summary>
566 /// <remarks>
567 /// If the image file already exists then the tiles saved will replace those already in the file - other tiles
568 /// will be untouched.
569 /// </remarks>
566 /// <param name="filename">The terrain file to save</param> 570 /// <param name="filename">The terrain file to save</param>
567 /// <param name="fileWidth">The width of the file in units</param> 571 /// <param name="fileWidth">The number of tiles to save along the X axis.</param>
568 /// <param name="fileHeight">The height of the file in units</param> 572 /// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
569 /// <param name="fileStartX">Where to begin our slice</param> 573 /// <param name="fileStartX">The map x co-ordinate at which to begin the save.</param>
570 /// <param name="fileStartY">Where to begin our slice</param> 574 /// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param>
571 public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) 575 public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
572 { 576 {
573 int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; 577 int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
574 int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; 578 int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
575 579
576 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) 580 if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight)
577 { 581 {
578 // this region is included in the tile request 582 MainConsole.Instance.OutputFormat(
579 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 583 "ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.",
584 m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY);
585
586 return;
587 }
588
589 // this region is included in the tile request
590 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
591 {
592 if (filename.EndsWith(loader.Key))
580 { 593 {
581 if (filename.EndsWith(loader.Key)) 594 lock (m_scene)
582 { 595 {
583 lock (m_scene) 596 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
584 { 597 fileWidth, fileHeight,
585 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, 598 (int)Constants.RegionSize,
586 fileWidth, fileHeight, 599 (int)Constants.RegionSize);
587 (int)Constants.RegionSize, 600
588 (int)Constants.RegionSize); 601 MainConsole.Instance.OutputFormat(
589 602 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
590 m_log.InfoFormat("[TERRAIN]: Saved terrain from {0} to {1}", m_scene.RegionInfo.RegionName, filename); 603 fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1,
591 } 604 m_scene.RegionInfo.RegionName, filename);
592
593 return;
594 } 605 }
606
607 return;
595 } 608 }
596
597 m_log.ErrorFormat(
598 "[TERRAIN]: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
599 m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
600 } 609 }
601// else 610
602// { 611 MainConsole.Instance.OutputFormat(
603// m_log.ErrorFormat( 612 "ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
604// "[TERRAIN]: Could not save terrain from {0} to {1}. {2} {3} {4} {5} {6} {7}", 613 m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
605// m_scene.RegionInfo.RegionName, filename, fileWidth, fileHeight, fileStartX, fileStartY, offsetX, offsetY);
606// }
607 } 614 }
608 615
609 /// <summary> 616 /// <summary>
@@ -1192,6 +1199,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1192 "Integer"); 1199 "Integer");
1193 saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", 1200 saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
1194 "Integer"); 1201 "Integer");
1202 saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n"
1203 + "= Example =\n"
1204 + "To save a PNG file for a set of map tiles 2 regions wide and 3 regions high from map co-ordinate (9910,10234)\n"
1205 + " # terrain save-tile ST06.png 2 3 9910 10234\n",
1206 "Integer");
1207
1195 // Terrain adjustments 1208 // Terrain adjustments
1196 Command fillRegionCommand = 1209 Command fillRegionCommand =
1197 new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); 1210 new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
index bb4c788..34a4bfc 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
@@ -26,12 +26,12 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using OpenMetaverse; 30using OpenMetaverse;
30 31
31namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
32{ 33{
33 public delegate void ScriptCommand(UUID script, string id, string module, string command, string k); 34 public delegate void ScriptCommand(UUID script, string id, string module, string command, string k);
34 public delegate object ScriptInvocation(UUID script, object[] parms);
35 35
36 /// <summary> 36 /// <summary>
37 /// Interface for communication between OpenSim modules and in-world scripts 37 /// Interface for communication between OpenSim modules and in-world scripts
@@ -46,14 +46,15 @@ namespace OpenSim.Region.Framework.Interfaces
46 /// </summary> 46 /// </summary>
47 event ScriptCommand OnScriptCommand; 47 event ScriptCommand OnScriptCommand;
48 48
49 void RegisterScriptInvocation(string name, ScriptInvocation fn, Type[] csig, Type rsig); 49 void RegisterScriptInvocation(object target, string method);
50 Delegate[] GetScriptInvocationList();
50 51
51 ScriptInvocation LookupScriptInvocation(string fname); 52 Delegate LookupScriptInvocation(string fname);
52 string LookupModInvocation(string fname); 53 string LookupModInvocation(string fname);
53 Type[] LookupTypeSignature(string fname); 54 Type[] LookupTypeSignature(string fname);
54 Type LookupReturnType(string fname); 55 Type LookupReturnType(string fname);
55 56
56 object InvokeOperation(UUID scriptId, string fname, params object[] parms); 57 object InvokeOperation(UUID hostId, UUID scriptId, string fname, params object[] parms);
57 58
58 /// <summary> 59 /// <summary>
59 /// Send a link_message event to an in-world script 60 /// Send a link_message event to an in-world script
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index a90362e..0605590 100644
--- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using Mono.Addins; 36using Mono.Addins;
37using OpenMetaverse; 37using OpenMetaverse;
38using System.Linq;
39using System.Linq.Expressions;
38 40
39namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms 41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
40{ 42{
@@ -47,15 +49,15 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
47#region ScriptInvocation 49#region ScriptInvocation
48 protected class ScriptInvocationData 50 protected class ScriptInvocationData
49 { 51 {
50 public ScriptInvocation ScriptInvocationFn { get; private set; } 52 public Delegate ScriptInvocationDelegate { get; private set; }
51 public string FunctionName { get; private set; } 53 public string FunctionName { get; private set; }
52 public Type[] TypeSignature { get; private set; } 54 public Type[] TypeSignature { get; private set; }
53 public Type ReturnType { get; private set; } 55 public Type ReturnType { get; private set; }
54 56
55 public ScriptInvocationData(string fname, ScriptInvocation fn, Type[] callsig, Type returnsig) 57 public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
56 { 58 {
57 FunctionName = fname; 59 FunctionName = fname;
58 ScriptInvocationFn = fn; 60 ScriptInvocationDelegate = fn;
59 TypeSignature = callsig; 61 TypeSignature = callsig;
60 ReturnType = returnsig; 62 ReturnType = returnsig;
61 } 63 }
@@ -126,14 +128,62 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
126 m_scriptModule.PostScriptEvent(script, "link_message", args); 128 m_scriptModule.PostScriptEvent(script, "link_message", args);
127 } 129 }
128 130
129 public void RegisterScriptInvocation(string fname, ScriptInvocation fcall, Type[] csig, Type rsig) 131 public void RegisterScriptInvocation(object target, string meth)
130 { 132 {
133 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}",meth,target.GetType().Name);
134
135
136 MethodInfo mi = target.GetType().GetMethod(meth,
137 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
138 if (mi == null)
139 {
140 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);
141 return;
142 }
143
144 Type delegateType;
145 var typeArgs = mi.GetParameters()
146 .Select(p => p.ParameterType)
147 .ToList();
148
149 if (mi.ReturnType == typeof(void))
150 {
151 delegateType = Expression.GetActionType(typeArgs.ToArray());
152 }
153 else
154 {
155 typeArgs.Add(mi.ReturnType);
156 delegateType = Expression.GetFuncType(typeArgs.ToArray());
157 }
158
159 Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi);
160
131 lock (m_scriptInvocation) 161 lock (m_scriptInvocation)
132 { 162 {
133 m_scriptInvocation[fname] = new ScriptInvocationData(fname,fcall,csig,rsig); 163 ParameterInfo[] parameters = fcall.Method.GetParameters ();
164 if (parameters.Length < 2) // Must have two UUID params
165 return;
166
167 // Hide the first two parameters
168 Type[] parmTypes = new Type[parameters.Length - 2];
169 for (int i = 2 ; i < parameters.Length ; i++)
170 parmTypes[i - 2] = parameters[i].ParameterType;
171 m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
134 } 172 }
135 } 173 }
136 174
175 public Delegate[] GetScriptInvocationList()
176 {
177 List<Delegate> ret = new List<Delegate>();
178
179 lock (m_scriptInvocation)
180 {
181 foreach (ScriptInvocationData d in m_scriptInvocation.Values)
182 ret.Add(d.ScriptInvocationDelegate);
183 }
184 return ret.ToArray();
185 }
186
137 public string LookupModInvocation(string fname) 187 public string LookupModInvocation(string fname)
138 { 188 {
139 lock (m_scriptInvocation) 189 lock (m_scriptInvocation)
@@ -147,19 +197,29 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
147 return "modInvokeI"; 197 return "modInvokeI";
148 else if (sid.ReturnType == typeof(float)) 198 else if (sid.ReturnType == typeof(float))
149 return "modInvokeF"; 199 return "modInvokeF";
200 else if (sid.ReturnType == typeof(UUID))
201 return "modInvokeK";
202 else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
203 return "modInvokeV";
204 else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
205 return "modInvokeR";
206 else if (sid.ReturnType == typeof(object[]))
207 return "modInvokeL";
208
209 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
150 } 210 }
151 } 211 }
152 212
153 return null; 213 return null;
154 } 214 }
155 215
156 public ScriptInvocation LookupScriptInvocation(string fname) 216 public Delegate LookupScriptInvocation(string fname)
157 { 217 {
158 lock (m_scriptInvocation) 218 lock (m_scriptInvocation)
159 { 219 {
160 ScriptInvocationData sid; 220 ScriptInvocationData sid;
161 if (m_scriptInvocation.TryGetValue(fname,out sid)) 221 if (m_scriptInvocation.TryGetValue(fname,out sid))
162 return sid.ScriptInvocationFn; 222 return sid.ScriptInvocationDelegate;
163 } 223 }
164 224
165 return null; 225 return null;
@@ -189,10 +249,15 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
189 return null; 249 return null;
190 } 250 }
191 251
192 public object InvokeOperation(UUID scriptid, string fname, params object[] parms) 252 public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
193 { 253 {
194 ScriptInvocation fn = LookupScriptInvocation(fname); 254 List<object> olist = new List<object>();
195 return fn(scriptid,parms); 255 olist.Add(hostid);
256 olist.Add(scriptid);
257 foreach (object o in parms)
258 olist.Add(o);
259 Delegate fn = LookupScriptInvocation(fname);
260 return fn.DynamicInvoke(olist.ToArray());
196 } 261 }
197#endregion 262#endregion
198 263
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 2942104..7c07e15 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -120,33 +120,110 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
120 /// 120 ///
121 /// </summary> 121 /// </summary>
122 /// <param name="fname">The name of the function to invoke</param> 122 /// <param name="fname">The name of the function to invoke</param>
123 /// <param name="fname">List of parameters</param> 123 /// <param name="parms">List of parameters</param>
124 /// <returns>string result of the invocation</returns> 124 /// <returns>string result of the invocation</returns>
125 public string modInvokeS(string fname, params object[] parms) 125 public void modInvokeN(string fname, params object[] parms)
126 { 126 {
127 Type returntype = m_comms.LookupReturnType(fname); 127 Type returntype = m_comms.LookupReturnType(fname);
128 if (returntype != typeof(string)) 128 if (returntype != typeof(string))
129 MODError(String.Format("return type mismatch for {0}",fname)); 129 MODError(String.Format("return type mismatch for {0}",fname));
130 130
131 return (string)modInvoke(fname,parms); 131 modInvoke(fname,parms);
132 } 132 }
133 133
134 public int modInvokeI(string fname, params object[] parms) 134 public LSL_String modInvokeS(string fname, params object[] parms)
135 {
136 Type returntype = m_comms.LookupReturnType(fname);
137 if (returntype != typeof(string))
138 MODError(String.Format("return type mismatch for {0}",fname));
139
140 string result = (string)modInvoke(fname,parms);
141 return new LSL_String(result);
142 }
143
144 public LSL_Integer modInvokeI(string fname, params object[] parms)
135 { 145 {
136 Type returntype = m_comms.LookupReturnType(fname); 146 Type returntype = m_comms.LookupReturnType(fname);
137 if (returntype != typeof(int)) 147 if (returntype != typeof(int))
138 MODError(String.Format("return type mismatch for {0}",fname)); 148 MODError(String.Format("return type mismatch for {0}",fname));
139 149
140 return (int)modInvoke(fname,parms); 150 int result = (int)modInvoke(fname,parms);
151 return new LSL_Integer(result);
141 } 152 }
142 153
143 public float modInvokeF(string fname, params object[] parms) 154 public LSL_Float modInvokeF(string fname, params object[] parms)
144 { 155 {
145 Type returntype = m_comms.LookupReturnType(fname); 156 Type returntype = m_comms.LookupReturnType(fname);
146 if (returntype != typeof(float)) 157 if (returntype != typeof(float))
147 MODError(String.Format("return type mismatch for {0}",fname)); 158 MODError(String.Format("return type mismatch for {0}",fname));
148 159
149 return (float)modInvoke(fname,parms); 160 float result = (float)modInvoke(fname,parms);
161 return new LSL_Float(result);
162 }
163
164 public LSL_Key modInvokeK(string fname, params object[] parms)
165 {
166 Type returntype = m_comms.LookupReturnType(fname);
167 if (returntype != typeof(UUID))
168 MODError(String.Format("return type mismatch for {0}",fname));
169
170 UUID result = (UUID)modInvoke(fname,parms);
171 return new LSL_Key(result.ToString());
172 }
173
174 public LSL_Vector modInvokeV(string fname, params object[] parms)
175 {
176 Type returntype = m_comms.LookupReturnType(fname);
177 if (returntype != typeof(OpenMetaverse.Vector3))
178 MODError(String.Format("return type mismatch for {0}",fname));
179
180 OpenMetaverse.Vector3 result = (OpenMetaverse.Vector3)modInvoke(fname,parms);
181 return new LSL_Vector(result.X,result.Y,result.Z);
182 }
183
184 public LSL_Rotation modInvokeR(string fname, params object[] parms)
185 {
186 Type returntype = m_comms.LookupReturnType(fname);
187 if (returntype != typeof(OpenMetaverse.Quaternion))
188 MODError(String.Format("return type mismatch for {0}",fname));
189
190 OpenMetaverse.Quaternion result = (OpenMetaverse.Quaternion)modInvoke(fname,parms);
191 return new LSL_Rotation(result.X,result.Y,result.Z,result.W);
192 }
193
194 public LSL_List modInvokeL(string fname, params object[] parms)
195 {
196 Type returntype = m_comms.LookupReturnType(fname);
197 if (returntype != typeof(object[]))
198 MODError(String.Format("return type mismatch for {0}",fname));
199
200 object[] result = (object[])modInvoke(fname,parms);
201 object[] llist = new object[result.Length];
202 for (int i = 0; i < result.Length; i++)
203 {
204 if (result[i] is string)
205 llist[i] = new LSL_String((string)result[i]);
206 else if (result[i] is int)
207 llist[i] = new LSL_Integer((int)result[i]);
208 else if (result[i] is float)
209 llist[i] = new LSL_Float((float)result[i]);
210 else if (result[i] is OpenMetaverse.Vector3)
211 {
212 OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i];
213 llist[i] = new LSL_Vector(vresult.X,vresult.Y,vresult.Z);
214 }
215 else if (result[i] is OpenMetaverse.Quaternion)
216 {
217 OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i];
218 llist[i] = new LSL_Rotation(qresult.X,qresult.Y,qresult.Z,qresult.W);
219 }
220 else
221 {
222 MODError(String.Format("unknown list element returned by {0}",fname));
223 }
224 }
225
226 return new LSL_List(llist);
150 } 227 }
151 228
152 /// <summary> 229 /// <summary>
@@ -168,63 +245,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
168 MODError(String.Format("wrong number of parameters to function {0}",fname)); 245 MODError(String.Format("wrong number of parameters to function {0}",fname));
169 246
170 object[] convertedParms = new object[parms.Length]; 247 object[] convertedParms = new object[parms.Length];
171
172 for (int i = 0; i < parms.Length; i++) 248 for (int i = 0; i < parms.Length; i++)
173 { 249 convertedParms[i] = ConvertFromLSL(parms[i],signature[i]);
174 if (parms[i] is LSL_String)
175 {
176 if (signature[i] != typeof(string))
177 MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
178 250
179 convertedParms[i] = (string)(LSL_String)parms[i]; 251 // now call the function, the contract with the function is that it will always return
180 } 252 // non-null but don't trust it completely
181 else if (parms[i] is LSL_Integer) 253 try
182 { 254 {
183 if (signature[i] != typeof(int)) 255 object result = m_comms.InvokeOperation(m_host.UUID, m_itemID, fname, convertedParms);
184 MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); 256 if (result != null)
185 257 return result;
186 convertedParms[i] = (int)(LSL_Integer)parms[i];
187 }
188 else if (parms[i] is LSL_Float)
189 {
190 if (signature[i] != typeof(float))
191 MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
192
193 convertedParms[i] = (float)(LSL_Float)parms[i];
194 }
195 else if (parms[i] is LSL_Key)
196 {
197 if (signature[i] != typeof(string))
198 MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
199
200 convertedParms[i] = (string)(LSL_Key)parms[i];
201 }
202 else if (parms[i] is LSL_Rotation)
203 {
204 if (signature[i] != typeof(string))
205 MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
206
207 convertedParms[i] = (string)(LSL_Rotation)parms[i];
208 }
209 else if (parms[i] is LSL_Vector)
210 {
211 if (signature[i] != typeof(string))
212 MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
213
214 convertedParms[i] = (string)(LSL_Vector)parms[i];
215 }
216 else
217 {
218 if (signature[i] != parms[i].GetType())
219 MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
220 258
221 convertedParms[i] = parms[i]; 259 MODError(String.Format("Invocation of {0} failed; null return value",fname));
222 } 260 }
261 catch (Exception e)
262 {
263 MODError(String.Format("Invocation of {0} failed; {1}",fname,e.Message));
223 } 264 }
224 265
225 return m_comms.InvokeOperation(m_itemID,fname,convertedParms); 266 return null;
226 } 267 }
227 268
269 /// <summary>
270 /// Send a command to functions registered on an event
271 /// </summary>
228 public string modSendCommand(string module, string command, string k) 272 public string modSendCommand(string module, string command, string k)
229 { 273 {
230 if (!m_MODFunctionsEnabled) 274 if (!m_MODFunctionsEnabled)
@@ -239,5 +283,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
239 283
240 return req.ToString(); 284 return req.ToString();
241 } 285 }
286
287 /// <summary>
288 /// </summary>
289 protected object ConvertFromLSL(object lslparm, Type type)
290 {
291 // ---------- String ----------
292 if (lslparm is LSL_String)
293 {
294 if (type == typeof(string))
295 return (string)(LSL_String)lslparm;
296
297 // Need to check for UUID since keys are often treated as strings
298 if (type == typeof(UUID))
299 return new UUID((string)(LSL_String)lslparm);
300 }
301
302 // ---------- Integer ----------
303 else if (lslparm is LSL_Integer)
304 {
305 if (type == typeof(int))
306 return (int)(LSL_Integer)lslparm;
307 }
308
309 // ---------- Float ----------
310 else if (lslparm is LSL_Float)
311 {
312 if (type == typeof(float))
313 return (float)(LSL_Float)lslparm;
314 }
315
316 // ---------- Key ----------
317 else if (lslparm is LSL_Key)
318 {
319 if (type == typeof(UUID))
320 return new UUID((LSL_Key)lslparm);
321 }
322
323 // ---------- Rotation ----------
324 else if (lslparm is LSL_Rotation)
325 {
326 if (type == typeof(OpenMetaverse.Quaternion))
327 {
328 LSL_Rotation rot = (LSL_Rotation)lslparm;
329 return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
330 }
331 }
332
333 // ---------- Vector ----------
334 else if (lslparm is LSL_Vector)
335 {
336 if (type == typeof(OpenMetaverse.Vector3))
337 {
338 LSL_Vector vect = (LSL_Vector)lslparm;
339 return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
340 }
341 }
342
343 // ---------- List ----------
344 else if (lslparm is LSL_List)
345 {
346 if (type == typeof(object[]))
347 {
348 object[] plist = (lslparm as LSL_List).Data;
349 object[] result = new object[plist.Length];
350 for (int i = 0; i < plist.Length; i++)
351 {
352 if (plist[i] is LSL_String)
353 result[i] = (string)(LSL_String)plist[i];
354 else if (plist[i] is LSL_Integer)
355 result[i] = (int)(LSL_Integer)plist[i];
356 else if (plist[i] is LSL_Float)
357 result[i] = (float)(LSL_Float)plist[i];
358 else if (plist[i] is LSL_Key)
359 result[i] = new UUID((LSL_Key)plist[i]);
360 else if (plist[i] is LSL_Rotation)
361 {
362 LSL_Rotation rot = (LSL_Rotation)plist[i];
363 result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
364 }
365 else if (plist[i] is LSL_Vector)
366 {
367 LSL_Vector vect = (LSL_Vector)plist[i];
368 result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
369 }
370 else
371 MODError("unknown LSL list element type");
372 }
373
374 return result;
375 }
376 }
377
378 MODError(String.Format("parameter type mismatch; expecting {0}",type.Name));
379 return null;
380 }
381
242 } 382 }
243} 383}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
index 756a59f..aa78aaa 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
@@ -28,26 +28,27 @@
28using System.Collections; 28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces; 29using OpenSim.Region.ScriptEngine.Interfaces;
30 30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 31using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 32using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 33using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 36using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 37using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38 38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{ 40{
41 public interface IMOD_Api 41 public interface IMOD_Api
42 { 42 {
43 // Invocation functions 43 // Invocation functions
44 string modInvokeS(string fname, params object[] parms); 44 void modInvokeN(string fname, params object[] parms);
45 int modInvokeI(string fname, params object[] parms); 45 LSL_String modInvokeS(string fname, params object[] parms);
46 float modInvokeF(string fname, params object[] parms); 46 LSL_Integer modInvokeI(string fname, params object[] parms);
47 // vector modInvokeV(string fname, params object[] parms); 47 LSL_Float modInvokeF(string fname, params object[] parms);
48 // rotation modInvokeV(string fname, params object[] parms); 48 LSL_Key modInvokeK(string fname, params object[] parms);
49 // key modInvokeK(string fname, params object[] parms); 49 LSL_Vector modInvokeV(string fname, params object[] parms);
50 // list modInvokeL(string fname, params object[] parms); 50 LSL_Rotation modInvokeR(string fname, params object[] parms);
51 LSL_List modInvokeL(string fname, params object[] parms);
51 52
52 //Module functions 53 //Module functions
53 string modSendCommand(string modules, string command, string k); 54 string modSendCommand(string modules, string command, string k);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
index 04b7f14..1c47138 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
@@ -39,10 +39,14 @@ using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 42
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 43using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 44using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
45using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
46using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
47using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
48using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
49using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
46 50
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase 51namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{ 52{
@@ -58,21 +62,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
58 m_MOD_Functions = (IMOD_Api)api; 62 m_MOD_Functions = (IMOD_Api)api;
59 } 63 }
60 64
61 public string modInvokeS(string fname, params object[] parms) 65 public void modInvokeN(string fname, params object[] parms)
66 {
67 m_MOD_Functions.modInvokeN(fname, parms);
68 }
69
70 public LSL_String modInvokeS(string fname, params object[] parms)
62 { 71 {
63 return m_MOD_Functions.modInvokeS(fname, parms); 72 return m_MOD_Functions.modInvokeS(fname, parms);
64 } 73 }
65 74
66 public int modInvokeI(string fname, params object[] parms) 75 public LSL_Integer modInvokeI(string fname, params object[] parms)
67 { 76 {
68 return m_MOD_Functions.modInvokeI(fname, parms); 77 return m_MOD_Functions.modInvokeI(fname, parms);
69 } 78 }
70 79
71 public float modInvokeF(string fname, params object[] parms) 80 public LSL_Float modInvokeF(string fname, params object[] parms)
72 { 81 {
73 return m_MOD_Functions.modInvokeF(fname, parms); 82 return m_MOD_Functions.modInvokeF(fname, parms);
74 } 83 }
75 84
85 public LSL_Key modInvokeK(string fname, params object[] parms)
86 {
87 return m_MOD_Functions.modInvokeK(fname, parms);
88 }
89
90 public LSL_Vector modInvokeV(string fname, params object[] parms)
91 {
92 return m_MOD_Functions.modInvokeV(fname, parms);
93 }
94
95 public LSL_Rotation modInvokeR(string fname, params object[] parms)
96 {
97 return m_MOD_Functions.modInvokeR(fname, parms);
98 }
99
100 public LSL_List modInvokeL(string fname, params object[] parms)
101 {
102 return m_MOD_Functions.modInvokeL(fname, parms);
103 }
104
76 public string modSendCommand(string module, string command, string k) 105 public string modSendCommand(string module, string command, string k)
77 { 106 {
78 return m_MOD_Functions.modSendCommand(module, command, k); 107 return m_MOD_Functions.modSendCommand(module, command, k);