diff options
Diffstat (limited to 'OpenSim')
8 files changed, 308 insertions, 110 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6df55a6..7c5aee7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -1242,14 +1242,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1242 | try | 1242 | try |
1243 | { | 1243 | { |
1244 | // Send LayerData in typerwriter pattern | 1244 | // Send LayerData in typerwriter pattern |
1245 | //for (int y = 0; y < 16; y++) | ||
1246 | //{ | ||
1247 | // for (int x = 0; x < 16; x++) | ||
1248 | // { | ||
1249 | // SendLayerData(x, y, map); | ||
1250 | // } | ||
1251 | //} | ||
1245 | 1252 | ||
1246 | for (int y = 0; y < 16; y++) | 1253 | // Send LayerData in a spiral pattern. Fun! |
1247 | { | 1254 | SendLayerTopRight(map, 0, 0, map.SizeX / Constants.TerrainPatchSize - 1, map.SizeY / Constants.TerrainPatchSize - 1); |
1248 | for (int x = 0; x < 16; x++) | ||
1249 | { | ||
1250 | SendLayerData(x, y, map); | ||
1251 | } | ||
1252 | } | ||
1253 | } | 1255 | } |
1254 | catch (Exception e) | 1256 | catch (Exception e) |
1255 | { | 1257 | { |
@@ -1257,6 +1259,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1257 | } | 1259 | } |
1258 | } | 1260 | } |
1259 | 1261 | ||
1262 | private void SendLayerTopRight(TerrainData map, int x1, int y1, int x2, int y2) | ||
1263 | { | ||
1264 | // Row | ||
1265 | for (int i = x1; i <= x2; i++) | ||
1266 | SendLayerData(i, y1, map); | ||
1267 | |||
1268 | // Column | ||
1269 | for (int j = y1 + 1; j <= y2; j++) | ||
1270 | SendLayerData(x2, j, map); | ||
1271 | |||
1272 | if (x2 - x1 > 0 && y2 - y1 > 0) | ||
1273 | SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2); | ||
1274 | } | ||
1275 | |||
1276 | void SendLayerBottomLeft(TerrainData map, int x1, int y1, int x2, int y2) | ||
1277 | { | ||
1278 | // Row in reverse | ||
1279 | for (int i = x2; i >= x1; i--) | ||
1280 | SendLayerData(i, y2, map); | ||
1281 | |||
1282 | // Column in reverse | ||
1283 | for (int j = y2 - 1; j >= y1; j--) | ||
1284 | SendLayerData(x1, j, map); | ||
1285 | |||
1286 | if (x2 - x1 > 0 && y2 - y1 > 0) | ||
1287 | SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1); | ||
1288 | } | ||
1289 | |||
1290 | |||
1260 | // Legacy form of invocation that passes around a bare data array. | 1291 | // Legacy form of invocation that passes around a bare data array. |
1261 | // Just ignore what was passed and use the real terrain info that is part of the scene. | 1292 | // Just ignore what was passed and use the real terrain info that is part of the scene. |
1262 | // As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI, | 1293 | // As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI, |
@@ -1359,7 +1390,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1359 | 1390 | ||
1360 | private void SendTheLayerPacket(LayerDataPacket layerpack) | 1391 | private void SendTheLayerPacket(LayerDataPacket layerpack) |
1361 | { | 1392 | { |
1362 | OutPacket(layerpack, ThrottleOutPacketType.Land); | 1393 | OutPacket(layerpack, ThrottleOutPacketType.Land); |
1363 | } | 1394 | } |
1364 | 1395 | ||
1365 | /// <summary> | 1396 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs index be1fb24..59994e4 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs | |||
@@ -57,6 +57,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
57 | 57 | ||
58 | public LLRAW() | 58 | public LLRAW() |
59 | { | 59 | { |
60 | } | ||
61 | |||
62 | private void BuildLookupHeightTable() | ||
63 | { | ||
60 | LookupHeightTable = new HeightmapLookupValue[256 * 256]; | 64 | LookupHeightTable = new HeightmapLookupValue[256 * 256]; |
61 | 65 | ||
62 | for (int i = 0; i < 256; i++) | 66 | for (int i = 0; i < 256; i++) |
@@ -186,6 +190,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
186 | 190 | ||
187 | public void SaveStream(Stream s, ITerrainChannel map) | 191 | public void SaveStream(Stream s, ITerrainChannel map) |
188 | { | 192 | { |
193 | if (LookupHeightTable == null) | ||
194 | BuildLookupHeightTable(); | ||
195 | |||
189 | using (BinaryWriter binStream = new BinaryWriter(s)) | 196 | using (BinaryWriter binStream = new BinaryWriter(s)) |
190 | { | 197 | { |
191 | // Output the calculated raw | 198 | // Output the calculated raw |
@@ -241,6 +248,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
241 | } | 248 | } |
242 | } | 249 | } |
243 | } | 250 | } |
251 | LookupHeightTable = null; | ||
244 | } | 252 | } |
245 | 253 | ||
246 | public string FileExtension | 254 | public string FileExtension |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModifier.cs index 7ebd08e..c6e992f 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModifier.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModifier.cs | |||
@@ -370,9 +370,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
370 | } | 370 | } |
371 | return mask; | 371 | return mask; |
372 | } | 372 | } |
373 | |||
374 | |||
375 | } | 373 | } |
376 | |||
377 | } | 374 | } |
378 | 375 | ||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 22723fc..2f4618d 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -29,6 +29,7 @@ using System.Collections.Generic; | |||
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Threading; | ||
32 | 33 | ||
33 | using log4net; | 34 | using log4net; |
34 | using Nini.Config; | 35 | using Nini.Config; |
@@ -36,7 +37,6 @@ using Nini.Config; | |||
36 | using OpenMetaverse; | 37 | using OpenMetaverse; |
37 | using Mono.Addins; | 38 | using Mono.Addins; |
38 | 39 | ||
39 | using OpenSim.Data; | ||
40 | using OpenSim.Framework; | 40 | using OpenSim.Framework; |
41 | using OpenSim.Framework.Console; | 41 | using OpenSim.Framework.Console; |
42 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; | 42 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; |
@@ -86,7 +86,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
86 | private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); | 86 | private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); |
87 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = | 87 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = |
88 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); | 88 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); |
89 | 89 | private Dictionary<string, ITerrainModifier> m_modifyOperations = | |
90 | new Dictionary<string, ITerrainModifier>(); | ||
90 | private Dictionary<string, ITerrainEffect> m_plugineffects; | 91 | private Dictionary<string, ITerrainEffect> m_plugineffects; |
91 | private ITerrainChannel m_channel; | 92 | private ITerrainChannel m_channel; |
92 | private ITerrainChannel m_baked; | 93 | private ITerrainChannel m_baked; |
@@ -106,6 +107,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
106 | private bool[,] updated; // for each patch, whether it needs to be sent to this client | 107 | private bool[,] updated; // for each patch, whether it needs to be sent to this client |
107 | private int updateCount; // number of patches that need to be sent | 108 | private int updateCount; // number of patches that need to be sent |
108 | public ScenePresence Presence; // a reference to the client to send to | 109 | public ScenePresence Presence; // a reference to the client to send to |
110 | public bool sendAll; | ||
111 | public int sendAllcurrentX; | ||
112 | public int sendAllcurrentY; | ||
113 | |||
109 | 114 | ||
110 | public PatchUpdates(TerrainData terrData, ScenePresence pPresence) | 115 | public PatchUpdates(TerrainData terrData, ScenePresence pPresence) |
111 | { | 116 | { |
@@ -149,6 +154,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
149 | updated[xx, yy] = state; | 154 | updated[xx, yy] = state; |
150 | if (state) | 155 | if (state) |
151 | updateCount = updated.GetLength(0) * updated.GetLength(1); | 156 | updateCount = updated.GetLength(0) * updated.GetLength(1); |
157 | sendAllcurrentX = 0; | ||
158 | sendAllcurrentY = 0; | ||
159 | sendAll = true; | ||
152 | } | 160 | } |
153 | 161 | ||
154 | // Logically OR's the terrain data's patch taint map into this client's update map. | 162 | // Logically OR's the terrain data's patch taint map into this client's update map. |
@@ -210,7 +218,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
210 | if (terrainConfig != null) | 218 | if (terrainConfig != null) |
211 | { | 219 | { |
212 | m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); | 220 | m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); |
213 | m_sendTerrainUpdatesByViewDistance = terrainConfig.GetBoolean("SendTerrainUpdatesByViewDistance", m_sendTerrainUpdatesByViewDistance); | 221 | m_sendTerrainUpdatesByViewDistance = |
222 | terrainConfig.GetBoolean( | ||
223 | "SendTerrainUpdatesByViewDistance",m_sendTerrainUpdatesByViewDistance); | ||
214 | } | 224 | } |
215 | } | 225 | } |
216 | 226 | ||
@@ -523,21 +533,29 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
523 | // ITerrainModule.PushTerrain() | 533 | // ITerrainModule.PushTerrain() |
524 | public void PushTerrain(IClientAPI pClient) | 534 | public void PushTerrain(IClientAPI pClient) |
525 | { | 535 | { |
526 | ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); | 536 | if (m_sendTerrainUpdatesByViewDistance) |
527 | if (presence != null) | ||
528 | { | 537 | { |
529 | lock (m_perClientPatchUpdates) | 538 | ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); |
539 | if (presence != null) | ||
530 | { | 540 | { |
531 | PatchUpdates pups; | 541 | lock (m_perClientPatchUpdates) |
532 | if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups)) | ||
533 | { | 542 | { |
534 | // There is a ScenePresence without a send patch map. Create one. | 543 | PatchUpdates pups; |
535 | pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence); | 544 | if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups)) |
536 | m_perClientPatchUpdates.Add(presence.UUID, pups); | 545 | { |
546 | // There is a ScenePresence without a send patch map. Create one. | ||
547 | pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence); | ||
548 | m_perClientPatchUpdates.Add(presence.UUID, pups); | ||
549 | } | ||
550 | pups.SetAll(true); | ||
537 | } | 551 | } |
538 | pups.SetAll(true); | ||
539 | } | 552 | } |
540 | } | 553 | } |
554 | else | ||
555 | { | ||
556 | // The traditional way is to call into the protocol stack to send them all. | ||
557 | pClient.SendLayerData(new float[10]); | ||
558 | } | ||
541 | } | 559 | } |
542 | 560 | ||
543 | #region Plugin Loading Methods | 561 | #region Plugin Loading Methods |
@@ -643,7 +661,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
643 | m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_baked); | 661 | m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_baked); |
644 | 662 | ||
645 | // Terrain Modifier operations | 663 | // Terrain Modifier operations |
646 | /* | 664 | |
647 | m_modifyOperations["min"] = new MinModifier(this); | 665 | m_modifyOperations["min"] = new MinModifier(this); |
648 | m_modifyOperations["max"] = new MaxModifier(this); | 666 | m_modifyOperations["max"] = new MaxModifier(this); |
649 | m_modifyOperations["raise"] = new RaiseModifier(this); | 667 | m_modifyOperations["raise"] = new RaiseModifier(this); |
@@ -651,7 +669,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
651 | m_modifyOperations["fill"] = new FillModifier(this); | 669 | m_modifyOperations["fill"] = new FillModifier(this); |
652 | m_modifyOperations["smooth"] = new SmoothModifier(this); | 670 | m_modifyOperations["smooth"] = new SmoothModifier(this); |
653 | m_modifyOperations["noise"] = new NoiseModifier(this); | 671 | m_modifyOperations["noise"] = new NoiseModifier(this); |
654 | */ | 672 | |
655 | // Filesystem load/save loaders | 673 | // Filesystem load/save loaders |
656 | m_loaders[".r32"] = new RAW32(); | 674 | m_loaders[".r32"] = new RAW32(); |
657 | m_loaders[".f32"] = m_loaders[".r32"]; | 675 | m_loaders[".f32"] = m_loaders[".r32"]; |
@@ -948,19 +966,37 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
948 | /// <param name="y">The patch corner to send</param> | 966 | /// <param name="y">The patch corner to send</param> |
949 | private void SendToClients(TerrainData terrData, int x, int y) | 967 | private void SendToClients(TerrainData terrData, int x, int y) |
950 | { | 968 | { |
951 | // Add that this patch needs to be sent to the accounting for each client. | 969 | if (m_sendTerrainUpdatesByViewDistance) |
952 | lock (m_perClientPatchUpdates) | ||
953 | { | 970 | { |
954 | m_scene.ForEachScenePresence(presence => | 971 | // Add that this patch needs to be sent to the accounting for each client. |
955 | { | 972 | lock (m_perClientPatchUpdates) |
956 | PatchUpdates thisClientUpdates; | 973 | { |
957 | if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates)) | 974 | m_scene.ForEachScenePresence(presence => |
958 | { | 975 | { |
959 | // There is a ScenePresence without a send patch map. Create one. | 976 | PatchUpdates thisClientUpdates; |
960 | thisClientUpdates = new PatchUpdates(terrData, presence); | 977 | if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates)) |
961 | m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates); | 978 | { |
979 | // There is a ScenePresence without a send patch map. Create one. | ||
980 | thisClientUpdates = new PatchUpdates(terrData, presence); | ||
981 | m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates); | ||
982 | } | ||
983 | thisClientUpdates.SetByXY(x, y, true); | ||
962 | } | 984 | } |
963 | thisClientUpdates.SetByXY(x, y, true); | 985 | ); |
986 | } | ||
987 | } | ||
988 | else | ||
989 | { | ||
990 | // Legacy update sending where the update is sent out as soon as noticed | ||
991 | // We know the actual terrain data that is passed is ignored so this passes a dummy heightmap. | ||
992 | //float[] heightMap = terrData.GetFloatsSerialized(); | ||
993 | float[] heightMap = new float[10]; | ||
994 | m_scene.ForEachClient( | ||
995 | delegate (IClientAPI controller) | ||
996 | { | ||
997 | controller.SendLayerData(x / Constants.TerrainPatchSize, | ||
998 | y / Constants.TerrainPatchSize, | ||
999 | heightMap); | ||
964 | } | 1000 | } |
965 | ); | 1001 | ); |
966 | } | 1002 | } |
@@ -998,35 +1034,107 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
998 | 1034 | ||
999 | if (pups.HasUpdates()) | 1035 | if (pups.HasUpdates()) |
1000 | { | 1036 | { |
1001 | // There is something that could be sent to this client. | 1037 | if (m_sendTerrainUpdatesByViewDistance) |
1002 | List<PatchesToSend> toSend = GetModifiedPatchesInViewDistance(pups); | ||
1003 | if (toSend.Count > 0) | ||
1004 | { | 1038 | { |
1005 | // m_log.DebugFormat("{0} CheckSendingPatchesToClient: sending {1} patches to {2} in region {3}", | 1039 | // There is something that could be sent to this client. |
1006 | // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); | 1040 | List<PatchesToSend> toSend = GetModifiedPatchesInViewDistance(pups); |
1007 | // Sort the patches to send by the distance from the presence | 1041 | if (toSend.Count > 0) |
1008 | toSend.Sort(); | ||
1009 | /* | ||
1010 | foreach (PatchesToSend pts in toSend) | ||
1011 | { | 1042 | { |
1012 | pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); | 1043 | // m_log.DebugFormat("{0} CheckSendingPatchesToClient: sending {1} patches to {2} in region {3}", |
1013 | // presence.ControllingClient.SendLayerData(xs.ToArray(), ys.ToArray(), null, TerrainPatch.LayerType.Land); | 1044 | // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); |
1045 | // Sort the patches to send by the distance from the presence | ||
1046 | toSend.Sort(); | ||
1047 | /* | ||
1048 | foreach (PatchesToSend pts in toSend) | ||
1049 | { | ||
1050 | pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); | ||
1051 | // presence.ControllingClient.SendLayerData(xs.ToArray(), ys.ToArray(), null, TerrainPatch.LayerType.Land); | ||
1052 | } | ||
1053 | */ | ||
1054 | |||
1055 | int[] xPieces = new int[toSend.Count]; | ||
1056 | int[] yPieces = new int[toSend.Count]; | ||
1057 | float[] patchPieces = new float[toSend.Count * 2]; | ||
1058 | int pieceIndex = 0; | ||
1059 | foreach (PatchesToSend pts in toSend) | ||
1060 | { | ||
1061 | patchPieces[pieceIndex++] = pts.PatchX; | ||
1062 | patchPieces[pieceIndex++] = pts.PatchY; | ||
1063 | } | ||
1064 | pups.Presence.ControllingClient.SendLayerData(-toSend.Count, 0, patchPieces); | ||
1014 | } | 1065 | } |
1015 | */ | 1066 | if (pups.sendAll && toSend.Count < 1024) |
1067 | SendAllModifiedPatchs(pups); | ||
1068 | } | ||
1069 | else | ||
1070 | SendAllModifiedPatchs(pups); | ||
1071 | } | ||
1072 | } | ||
1073 | } | ||
1074 | } | ||
1075 | private void SendAllModifiedPatchs(PatchUpdates pups) | ||
1076 | { | ||
1077 | if (!pups.sendAll) // sanity | ||
1078 | return; | ||
1016 | 1079 | ||
1017 | int[] xPieces = new int[toSend.Count]; | 1080 | int limitX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize; |
1018 | int[] yPieces = new int[toSend.Count]; | 1081 | int limitY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize; |
1019 | float[] patchPieces = new float[toSend.Count * 2]; | 1082 | |
1020 | int pieceIndex = 0; | 1083 | if (pups.sendAllcurrentX > limitX || pups.sendAllcurrentY > limitY) |
1021 | foreach (PatchesToSend pts in toSend) | 1084 | { |
1022 | { | 1085 | pups.sendAll = false; |
1023 | patchPieces[pieceIndex++] = pts.PatchX; | 1086 | pups.sendAllcurrentX = 0; |
1024 | patchPieces[pieceIndex++] = pts.PatchY; | 1087 | pups.sendAllcurrentY = 0; |
1025 | } | 1088 | return; |
1026 | pups.Presence.ControllingClient.SendLayerData(-toSend.Count, 0, patchPieces); | 1089 | } |
1090 | |||
1091 | int npatchs = 0; | ||
1092 | List<PatchesToSend> patchs = new List<PatchesToSend>(); | ||
1093 | int x = pups.sendAllcurrentX; | ||
1094 | int y = pups.sendAllcurrentY; | ||
1095 | // send it in the order viewer draws it | ||
1096 | // even if not best for memory scan | ||
1097 | for (; y < limitY; y++) | ||
1098 | { | ||
1099 | for (; x < limitX; x++) | ||
1100 | { | ||
1101 | if (pups.GetByPatch(x, y)) | ||
1102 | { | ||
1103 | pups.SetByPatch(x, y, false); | ||
1104 | patchs.Add(new PatchesToSend(x, y, 0)); | ||
1105 | if (++npatchs >= 512) | ||
1106 | { | ||
1107 | pups.sendAllcurrentX = x + 1; | ||
1108 | pups.sendAllcurrentY = y; | ||
1109 | break; | ||
1027 | } | 1110 | } |
1028 | } | 1111 | } |
1029 | } | 1112 | } |
1113 | if (npatchs >= 512) | ||
1114 | break; | ||
1115 | x = 0; | ||
1116 | } | ||
1117 | |||
1118 | if (x >= limitX && y >= limitY) | ||
1119 | { | ||
1120 | pups.sendAll = false; | ||
1121 | pups.sendAllcurrentX = 0; | ||
1122 | pups.sendAllcurrentY = 0; | ||
1123 | } | ||
1124 | |||
1125 | npatchs = patchs.Count; | ||
1126 | if (npatchs > 0) | ||
1127 | { | ||
1128 | int[] xPieces = new int[npatchs]; | ||
1129 | int[] yPieces = new int[npatchs]; | ||
1130 | float[] patchPieces = new float[npatchs * 2]; | ||
1131 | int pieceIndex = 0; | ||
1132 | foreach (PatchesToSend pts in patchs) | ||
1133 | { | ||
1134 | patchPieces[pieceIndex++] = pts.PatchX; | ||
1135 | patchPieces[pieceIndex++] = pts.PatchY; | ||
1136 | } | ||
1137 | pups.Presence.ControllingClient.SendLayerData(-npatchs, 0, patchPieces); | ||
1030 | } | 1138 | } |
1031 | } | 1139 | } |
1032 | 1140 | ||
@@ -1099,7 +1207,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1099 | int distsq; | 1207 | int distsq; |
1100 | 1208 | ||
1101 | DrawDistance *= DrawDistance; | 1209 | DrawDistance *= DrawDistance; |
1102 | 1210 | ||
1103 | for (int x = startX; x < endX; x++) | 1211 | for (int x = startX; x < endX; x++) |
1104 | { | 1212 | { |
1105 | for (int y = startY; y < endY; y++) | 1213 | for (int y = startY; y < endY; y++) |
@@ -1113,7 +1221,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1113 | { | 1221 | { |
1114 | pups.SetByPatch(x, y, false); | 1222 | pups.SetByPatch(x, y, false); |
1115 | ret.Add(new PatchesToSend(x, y, (float)distsq)); | 1223 | ret.Add(new PatchesToSend(x, y, (float)distsq)); |
1116 | if (npatchs++ > 65536) | 1224 | if (npatchs++ > 1024) |
1117 | { | 1225 | { |
1118 | y = endY; | 1226 | y = endY; |
1119 | x = endX; | 1227 | x = endX; |
@@ -1123,7 +1231,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1123 | } | 1231 | } |
1124 | } | 1232 | } |
1125 | return ret; | 1233 | return ret; |
1126 | } | 1234 | } |
1127 | 1235 | ||
1128 | private void client_OnModifyTerrain(UUID user, float height, float seconds, byte size, byte action, | 1236 | private void client_OnModifyTerrain(UUID user, float height, float seconds, byte size, byte action, |
1129 | float north, float west, float south, float east, UUID agentId) | 1237 | float north, float west, float south, float east, UUID agentId) |
@@ -1414,7 +1522,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1414 | } | 1522 | } |
1415 | 1523 | ||
1416 | } | 1524 | } |
1417 | |||
1418 | } | 1525 | } |
1419 | 1526 | ||
1420 | private void InterfaceElevateTerrain(Object[] args) | 1527 | private void InterfaceElevateTerrain(Object[] args) |
@@ -1707,7 +1814,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1707 | 1814 | ||
1708 | public void ModifyCommand(string module, string[] cmd) | 1815 | public void ModifyCommand(string module, string[] cmd) |
1709 | { | 1816 | { |
1710 | /* | ||
1711 | string result; | 1817 | string result; |
1712 | Scene scene = SceneManager.Instance.CurrentScene; | 1818 | Scene scene = SceneManager.Instance.CurrentScene; |
1713 | if ((scene != null) && (scene != m_scene)) | 1819 | if ((scene != null) && (scene != m_scene)) |
@@ -1747,7 +1853,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1747 | { | 1853 | { |
1748 | MainConsole.Instance.Output(result); | 1854 | MainConsole.Instance.Output(result); |
1749 | } | 1855 | } |
1750 | */ | ||
1751 | } | 1856 | } |
1752 | 1857 | ||
1753 | #endregion | 1858 | #endregion |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 05edd20..1b90af4 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1939,6 +1939,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1939 | /// <param name="ticks">Elapsed Stopwatch ticks</param> | 1939 | /// <param name="ticks">Elapsed Stopwatch ticks</param> |
1940 | public void AddScriptExecutionTime(long ticks) | 1940 | public void AddScriptExecutionTime(long ticks) |
1941 | { | 1941 | { |
1942 | StatsReporter.addScriptEvents(1); | ||
1942 | Interlocked.Add(ref m_scriptExecutionTime, ticks); | 1943 | Interlocked.Add(ref m_scriptExecutionTime, ticks); |
1943 | } | 1944 | } |
1944 | 1945 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 66cf14f..de3c3d6 100755 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | |||
@@ -230,6 +230,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
230 | private int m_pendingUploads = 0; // FIXME: Not currently filled in | 230 | private int m_pendingUploads = 0; // FIXME: Not currently filled in |
231 | private int m_activeScripts; | 231 | private int m_activeScripts; |
232 | private int m_scriptLinesPerSecond; | 232 | private int m_scriptLinesPerSecond; |
233 | private int m_scriptEventsPerSecond; | ||
233 | 234 | ||
234 | private int m_objectCapacity = 45000; | 235 | private int m_objectCapacity = 45000; |
235 | 236 | ||
@@ -496,8 +497,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
496 | sb[27].StatID = (uint)Stats.PhysicsLodTasks; | 497 | sb[27].StatID = (uint)Stats.PhysicsLodTasks; |
497 | sb[27].StatValue = 0; | 498 | sb[27].StatValue = 0; |
498 | 499 | ||
499 | sb[28].StatID = (uint)Stats.ScriptEps; // we should have this | 500 | sb[28].StatID = (uint)Stats.ScriptEps; // we actuall have this, but not messing array order AGAIN |
500 | sb[28].StatValue = 0; | 501 | sb[28].StatValue = m_scriptEventsPerSecond * updateFactor; |
501 | 502 | ||
502 | sb[29].StatID = (uint)Stats.SimAIStepTimeMS; | 503 | sb[29].StatID = (uint)Stats.SimAIStepTimeMS; |
503 | sb[29].StatValue = 0; | 504 | sb[29].StatValue = 0; |
@@ -620,6 +621,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
620 | //m_outPacketsPerSecond = 0; | 621 | //m_outPacketsPerSecond = 0; |
621 | m_unAckedBytes = 0; | 622 | m_unAckedBytes = 0; |
622 | m_scriptLinesPerSecond = 0; | 623 | m_scriptLinesPerSecond = 0; |
624 | m_scriptEventsPerSecond = 0; | ||
623 | 625 | ||
624 | m_frameMS = 0; | 626 | m_frameMS = 0; |
625 | m_agentMS = 0; | 627 | m_agentMS = 0; |
@@ -756,6 +758,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
756 | m_scriptLinesPerSecond += count; | 758 | m_scriptLinesPerSecond += count; |
757 | } | 759 | } |
758 | 760 | ||
761 | public void addScriptEvents(int count) | ||
762 | { | ||
763 | m_scriptEventsPerSecond += count; | ||
764 | } | ||
765 | |||
759 | public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes) | 766 | public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes) |
760 | { | 767 | { |
761 | AddInPackets(inPackets); | 768 | AddInPackets(inPackets); |
diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs index 5e48de6..54a2033 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs | |||
@@ -1691,6 +1691,9 @@ Console.WriteLine(" JointCreateFixed"); | |||
1691 | float fy = 0; | 1691 | float fy = 0; |
1692 | float fz = 0; | 1692 | float fz = 0; |
1693 | 1693 | ||
1694 | if (outofBounds) | ||
1695 | return; | ||
1696 | |||
1694 | if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. | 1697 | if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. |
1695 | { | 1698 | { |
1696 | if (m_vehicle.Type != Vehicle.TYPE_NONE) | 1699 | if (m_vehicle.Type != Vehicle.TYPE_NONE) |
@@ -2664,16 +2667,38 @@ Console.WriteLine(" JointCreateFixed"); | |||
2664 | 2667 | ||
2665 | public override void CrossingFailure() | 2668 | public override void CrossingFailure() |
2666 | { | 2669 | { |
2667 | m_crossingfailures++; | 2670 | /* |
2668 | if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) | 2671 | m_crossingfailures++; |
2669 | { | 2672 | if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) |
2670 | base.RaiseOutOfBounds(_position); | 2673 | { |
2671 | return; | 2674 | base.RaiseOutOfBounds(_position); |
2672 | } | 2675 | return; |
2673 | else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) | 2676 | } |
2677 | else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) | ||
2678 | { | ||
2679 | m_log.Warn("[PHYSICS]: Too many crossing failures for: " + Name); | ||
2680 | } | ||
2681 | */ | ||
2682 | _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); | ||
2683 | _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); | ||
2684 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); | ||
2685 | |||
2686 | m_lastposition = _position; | ||
2687 | _velocity.X = 0; | ||
2688 | _velocity.Y = 0; | ||
2689 | _velocity.Z = 0; | ||
2690 | |||
2691 | m_lastVelocity = _velocity; | ||
2692 | |||
2693 | if (Body != IntPtr.Zero) | ||
2674 | { | 2694 | { |
2675 | m_log.Warn("[PHYSICS]: Too many crossing failures for: " + Name); | 2695 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it |
2696 | d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); | ||
2676 | } | 2697 | } |
2698 | |||
2699 | outofBounds = false; | ||
2700 | base.RequestPhysicsterseUpdate(); | ||
2701 | |||
2677 | } | 2702 | } |
2678 | 2703 | ||
2679 | public override float Buoyancy | 2704 | public override float Buoyancy |
@@ -2712,6 +2737,8 @@ Console.WriteLine(" JointCreateFixed"); | |||
2712 | internal void UpdatePositionAndVelocity() | 2737 | internal void UpdatePositionAndVelocity() |
2713 | { | 2738 | { |
2714 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 2739 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! |
2740 | if (outofBounds) | ||
2741 | return; | ||
2715 | if (_parent == null) | 2742 | if (_parent == null) |
2716 | { | 2743 | { |
2717 | Vector3 pv = Vector3.Zero; | 2744 | Vector3 pv = Vector3.Zero; |
@@ -2728,12 +2755,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
2728 | Vector3 l_position = Vector3.Zero; | 2755 | Vector3 l_position = Vector3.Zero; |
2729 | Quaternion l_orientation = Quaternion.Identity; | 2756 | Quaternion l_orientation = Quaternion.Identity; |
2730 | 2757 | ||
2731 | // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) | ||
2732 | //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2733 | //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2734 | //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2735 | //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } | ||
2736 | |||
2737 | m_lastposition = _position; | 2758 | m_lastposition = _position; |
2738 | m_lastorientation = _orientation; | 2759 | m_lastorientation = _orientation; |
2739 | 2760 | ||
@@ -2745,26 +2766,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
2745 | l_orientation.Z = ori.Z; | 2766 | l_orientation.Z = ori.Z; |
2746 | l_orientation.W = ori.W; | 2767 | l_orientation.W = ori.W; |
2747 | 2768 | ||
2748 | if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) | ||
2749 | { | ||
2750 | //base.RaiseOutOfBounds(l_position); | ||
2751 | |||
2752 | if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) | ||
2753 | { | ||
2754 | _position = l_position; | ||
2755 | //_parent_scene.remActivePrim(this); | ||
2756 | if (_parent == null) | ||
2757 | base.RequestPhysicsterseUpdate(); | ||
2758 | return; | ||
2759 | } | ||
2760 | else | ||
2761 | { | ||
2762 | if (_parent == null) | ||
2763 | base.RaiseOutOfBounds(l_position); | ||
2764 | return; | ||
2765 | } | ||
2766 | } | ||
2767 | |||
2768 | if (l_position.Z < 0) | 2769 | if (l_position.Z < 0) |
2769 | { | 2770 | { |
2770 | // This is so prim that get lost underground don't fall forever and suck up | 2771 | // This is so prim that get lost underground don't fall forever and suck up |
@@ -2774,8 +2775,6 @@ Console.WriteLine(" JointCreateFixed"); | |||
2774 | // It's a hack and will generate a console message if it fails. | 2775 | // It's a hack and will generate a console message if it fails. |
2775 | 2776 | ||
2776 | //IsPhysical = false; | 2777 | //IsPhysical = false; |
2777 | if (_parent == null) | ||
2778 | base.RaiseOutOfBounds(_position); | ||
2779 | 2778 | ||
2780 | _acceleration.X = 0; | 2779 | _acceleration.X = 0; |
2781 | _acceleration.Y = 0; | 2780 | _acceleration.Y = 0; |
@@ -2789,16 +2788,64 @@ Console.WriteLine(" JointCreateFixed"); | |||
2789 | m_rotationalVelocity.Z = 0; | 2788 | m_rotationalVelocity.Z = 0; |
2790 | 2789 | ||
2791 | if (_parent == null) | 2790 | if (_parent == null) |
2791 | base.RaiseOutOfBounds(_position); | ||
2792 | |||
2793 | if (_parent == null) | ||
2792 | base.RequestPhysicsterseUpdate(); | 2794 | base.RequestPhysicsterseUpdate(); |
2793 | 2795 | ||
2794 | m_throttleUpdates = false; | 2796 | m_throttleUpdates = false; |
2795 | throttleCounter = 0; | 2797 | throttleCounter = 0; |
2796 | _zeroFlag = true; | 2798 | _zeroFlag = true; |
2797 | //outofBounds = true; | 2799 | //outofBounds = true; |
2800 | return; | ||
2798 | } | 2801 | } |
2799 | 2802 | ||
2803 | if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) | ||
2804 | { | ||
2805 | //base.RaiseOutOfBounds(l_position); | ||
2806 | /* | ||
2807 | if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) | ||
2808 | { | ||
2809 | _position = l_position; | ||
2810 | //_parent_scene.remActivePrim(this); | ||
2811 | if (_parent == null) | ||
2812 | base.RequestPhysicsterseUpdate(); | ||
2813 | return; | ||
2814 | } | ||
2815 | else | ||
2816 | { | ||
2817 | if (_parent == null) | ||
2818 | base.RaiseOutOfBounds(l_position); | ||
2819 | return; | ||
2820 | } | ||
2821 | */ | ||
2822 | outofBounds = true; | ||
2823 | // part near the border on outside | ||
2824 | if (l_position.X < 0) | ||
2825 | Util.Clamp(l_position.X, -0.1f, -2f); | ||
2826 | else | ||
2827 | Util.Clamp(l_position.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f); | ||
2828 | if (l_position.Y < 0) | ||
2829 | Util.Clamp(l_position.Y, -0.1f, -2f); | ||
2830 | else | ||
2831 | Util.Clamp(l_position.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f); | ||
2832 | |||
2833 | d.BodySetPosition(Body, l_position.X, l_position.Y, l_position.Z); | ||
2834 | |||
2835 | // stop it | ||
2836 | d.BodySetAngularVel(Body, 0, 0, 0); | ||
2837 | d.BodySetLinearVel(Body, 0, 0, 0); | ||
2838 | disableBodySoft(); | ||
2839 | |||
2840 | // tell framework to fix it | ||
2841 | if (_parent == null) | ||
2842 | base.RequestPhysicsterseUpdate(); | ||
2843 | return; | ||
2844 | } | ||
2845 | |||
2846 | |||
2800 | //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); | 2847 | //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); |
2801 | //Console.WriteLine("Adiff " + Name + " = " + Adiff); | 2848 | //Console.WriteLine("Adiff " + Name + " = " + Adiff); |
2802 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) | 2849 | if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) |
2803 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) | 2850 | && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) |
2804 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) | 2851 | && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 2633f30..1d15d61 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -30,7 +30,6 @@ using System.Collections; | |||
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Globalization; | 31 | using System.Globalization; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Diagnostics; //for [DebuggerNonUserCode] | ||
34 | using System.Reflection; | 33 | using System.Reflection; |
35 | using System.Runtime.Remoting; | 34 | using System.Runtime.Remoting; |
36 | using System.Runtime.Remoting.Lifetime; | 35 | using System.Runtime.Remoting.Lifetime; |
@@ -52,7 +51,8 @@ using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; | |||
52 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 51 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
53 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | 52 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; |
54 | using OpenSim.Region.ScriptEngine.Interfaces; | 53 | using OpenSim.Region.ScriptEngine.Interfaces; |
55 | using System.Diagnostics; | 54 | |
55 | using System.Diagnostics; //for [DebuggerNonUserCode] | ||
56 | 56 | ||
57 | namespace OpenSim.Region.ScriptEngine.Shared.Instance | 57 | namespace OpenSim.Region.ScriptEngine.Shared.Instance |
58 | { | 58 | { |
@@ -187,13 +187,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
187 | 187 | ||
188 | public UUID ItemID { get; private set; } | 188 | public UUID ItemID { get; private set; } |
189 | 189 | ||
190 | public UUID ObjectID { get; private set; } | 190 | public UUID ObjectID { get { return Part.UUID; } } |
191 | 191 | ||
192 | public uint LocalID { get; private set; } | 192 | public uint LocalID { get { return Part.LocalId; } } |
193 | 193 | ||
194 | public UUID RootObjectID { get; private set; } | 194 | public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } |
195 | 195 | ||
196 | public uint RootLocalID { get; private set; } | 196 | public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } |
197 | 197 | ||
198 | public UUID AssetID { get; private set; } | 198 | public UUID AssetID { get; private set; } |
199 | 199 | ||
@@ -252,7 +252,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
252 | ItemID = ScriptTask.ItemID; | 252 | ItemID = ScriptTask.ItemID; |
253 | AssetID = ScriptTask.AssetID; | 253 | AssetID = ScriptTask.AssetID; |
254 | } | 254 | } |
255 | LocalID = part.LocalId; | ||
256 | 255 | ||
257 | PrimName = part.ParentGroup.Name; | 256 | PrimName = part.ParentGroup.Name; |
258 | StartParam = startParam; | 257 | StartParam = startParam; |
@@ -1070,7 +1069,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
1070 | 1069 | ||
1071 | public Dictionary<string, object> GetVars() | 1070 | public Dictionary<string, object> GetVars() |
1072 | { | 1071 | { |
1073 | return m_Script.GetVars(); | 1072 | if (m_Script != null) |
1073 | return m_Script.GetVars(); | ||
1074 | else | ||
1075 | return new Dictionary<string, object>(); | ||
1074 | } | 1076 | } |
1075 | 1077 | ||
1076 | public void SetVars(Dictionary<string, object> vars) | 1078 | public void SetVars(Dictionary<string, object> vars) |