aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorTom2011-01-29 12:46:47 -0800
committerTom2011-01-29 12:46:47 -0800
commita2d51f0ff42dd4f390d2320436febdba40449164 (patch)
treeeb3c0f561f90af1c44f7814e3e8ea6fd14675bdf /OpenSim/Region/CoreModules
parentIgnore duplicate llHTTPResponse calls to the same request. Prevents response ... (diff)
parentAdapt to CM (diff)
downloadopensim-SC-a2d51f0ff42dd4f390d2320436febdba40449164.zip
opensim-SC-a2d51f0ff42dd4f390d2320436febdba40449164.tar.gz
opensim-SC-a2d51f0ff42dd4f390d2320436febdba40449164.tar.bz2
opensim-SC-a2d51f0ff42dd4f390d2320436febdba40449164.tar.xz
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs35
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs406
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs239
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs10
8 files changed, 647 insertions, 59 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs
index 542af25..4a42c93 100644
--- a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets
54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private Scene m_scene; 56 private Scene m_scene;
57 private IAssetService m_assetService; 57// private IAssetService m_assetService;
58 private bool m_dumpAssetsToFile = false; 58 private bool m_dumpAssetsToFile = false;
59 59
60 #region IRegionModuleBase Members 60 #region IRegionModuleBase Members
@@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets
85 public void RegionLoaded(Scene scene) 85 public void RegionLoaded(Scene scene)
86 { 86 {
87 87
88 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 88// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
89 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 89 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
90 } 90 }
91 91
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index cfa4109..43de2ab 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -14,6 +14,7 @@
14 <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" /> 14 <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />
15 <RegionModule id="HGInventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.HGInventoryAccessModule" /> 15 <RegionModule id="HGInventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.HGInventoryAccessModule" />
16 <RegionModule id="LandManagementModule" type="OpenSim.Region.CoreModules.World.Land.LandManagementModule" /> 16 <RegionModule id="LandManagementModule" type="OpenSim.Region.CoreModules.World.Land.LandManagementModule" />
17 <RegionModule id="PrimCountModule" type="OpenSim.Region.CoreModules.World.Land.PrimCountModule" />
17 <RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" /> 18 <RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" />
18 <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" /> 19 <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" />
19 <RegionModule id="CapabilitiesModule" type="OpenSim.Region.CoreModules.Agent.Capabilities.CapabilitiesModule" /> 20 <RegionModule id="CapabilitiesModule" type="OpenSim.Region.CoreModules.Agent.Capabilities.CapabilitiesModule" />
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
index 05042f4..cbe2eaa 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
@@ -38,9 +38,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
38 { 38 {
39 private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours! 39 private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours!
40 40
41 private static readonly ILog m_log = 41// private static readonly ILog m_log =
42 LogManager.GetLogger( 42// LogManager.GetLogger(
43 MethodBase.GetCurrentMethod().DeclaringType); 43// MethodBase.GetCurrentMethod().DeclaringType);
44
44 private ExpiringCache<UUID, UserAccount> m_UUIDCache; 45 private ExpiringCache<UUID, UserAccount> m_UUIDCache;
45 private ExpiringCache<string, UUID> m_NameCache; 46 private ExpiringCache<string, UUID> m_NameCache;
46 47
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index e7ebab3..3653842 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -569,37 +569,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
569 569
570 try 570 try
571 { 571 {
572 MemoryStream terrainStream = new MemoryStream(terrainData);
573 terr.LoadFromStream(filename, terrainStream);
574 terrainStream.Close();
572 575
573 string localfilename = "terrain.raw"; 576 FileInfo x = new FileInfo(filename);
574 577 remoteClient.SendAlertMessage("Your terrain was loaded as a " + x.Extension + " file. It may take a few moments to appear.");
575 if (terrainData.Length == 851968)
576 {
577 localfilename = Path.Combine(Util.dataDir(),"terrain.raw"); // It's a .LLRAW
578 }
579
580 if (terrainData.Length == 196662) // 24-bit 256x256 Bitmap
581 localfilename = Path.Combine(Util.dataDir(), "terrain.bmp");
582
583 if (terrainData.Length == 256 * 256 * 4) // It's a .R32
584 localfilename = Path.Combine(Util.dataDir(), "terrain.r32");
585
586 if (terrainData.Length == 256 * 256 * 8) // It's a .R64
587 localfilename = Path.Combine(Util.dataDir(), "terrain.r64");
588
589 if (File.Exists(localfilename))
590 {
591 File.Delete(localfilename);
592 }
593
594 FileStream input = new FileStream(localfilename, FileMode.CreateNew);
595 input.Write(terrainData, 0, terrainData.Length);
596 input.Close();
597
598 FileInfo x = new FileInfo(localfilename);
599
600 terr.LoadFromFile(localfilename);
601 remoteClient.SendAlertMessage("Your terrain was loaded as a ." + x.Extension + " file. It may take a few moments to appear.");
602
603 } 578 }
604 catch (IOException e) 579 catch (IOException e)
605 { 580 {
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
new file mode 100644
index 0000000..2d1979f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -0,0 +1,406 @@
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 OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Diagnostics;
32using System.Reflection;
33using log4net;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40
41namespace OpenSim.Region.CoreModules.World.Land
42{
43 public class ParcelCounts
44 {
45 public int Owner = 0;
46 public int Group = 0;
47 public int Others = 0;
48 public Dictionary <UUID, int> Users =
49 new Dictionary <UUID, int>();
50 }
51
52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule
53 {
54 private static readonly ILog m_log =
55 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 private Scene m_Scene;
58 private Dictionary<UUID, PrimCounts> m_PrimCounts =
59 new Dictionary<UUID, PrimCounts>();
60 private Dictionary<UUID, UUID> m_OwnerMap =
61 new Dictionary<UUID, UUID>();
62 private Dictionary<UUID, int> m_SimwideCounts =
63 new Dictionary<UUID, int>();
64 private Dictionary<UUID, ParcelCounts> m_ParcelCounts =
65 new Dictionary<UUID, ParcelCounts>();
66
67 // For now, a simple simwide taint to get this up. Later parcel based
68 // taint to allow recounting a parcel if only ownership has changed
69 // without recounting the whole sim.
70 private bool m_Tainted = true;
71 private Object m_TaintLock = new Object();
72
73 public Type ReplaceableInterface
74 {
75 get { return null; }
76 }
77
78 public void Initialise(IConfigSource source)
79 {
80 }
81
82 public void AddRegion(Scene scene)
83 {
84 m_Scene = scene;
85
86 m_Scene.EventManager.OnParcelPrimCountAdd +=
87 OnParcelPrimCountAdd;
88 m_Scene.EventManager.OnObjectBeingRemovedFromScene +=
89 OnObjectBeingRemovedFromScene;
90 m_Scene.EventManager.OnParcelPrimCountTainted +=
91 OnParcelPrimCountTainted;
92 }
93
94 public void RegionLoaded(Scene scene)
95 {
96 }
97
98 public void RemoveRegion(Scene scene)
99 {
100 }
101
102 public void Close()
103 {
104 }
105
106 public string Name
107 {
108 get { return "PrimCountModule"; }
109 }
110
111 private void OnParcelPrimCountAdd(SceneObjectGroup obj)
112 {
113 // If we're tainted already, don't bother to add. The next
114 // access will cause a recount anyway
115 lock (m_TaintLock)
116 {
117 if (!m_Tainted)
118 AddObject(obj);
119 }
120 }
121
122 private void OnObjectBeingRemovedFromScene(SceneObjectGroup obj)
123 {
124 // Don't bother to update tainted counts
125 lock (m_TaintLock)
126 {
127 if (!m_Tainted)
128 RemoveObject(obj);
129 }
130 }
131
132 private void OnParcelPrimCountTainted()
133 {
134 lock (m_TaintLock)
135 m_Tainted = true;
136 }
137
138 public void TaintPrimCount(ILandObject land)
139 {
140 lock (m_TaintLock)
141 m_Tainted = true;
142 }
143
144 public void TaintPrimCount(int x, int y)
145 {
146 lock (m_TaintLock)
147 m_Tainted = true;
148 }
149
150 public void TaintPrimCount()
151 {
152 lock (m_TaintLock)
153 m_Tainted = true;
154 }
155
156 // NOTE: Call under Taint Lock
157 private void AddObject(SceneObjectGroup obj)
158 {
159 if (obj.IsAttachment)
160 return;
161 if (((obj.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0))
162 return;
163
164 Vector3 pos = obj.AbsolutePosition;
165 ILandObject landObject = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
166 LandData landData = landObject.LandData;
167
168 ParcelCounts parcelCounts;
169 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
170 {
171 UUID landOwner = landData.OwnerID;
172 int partCount = obj.GetPartCount();
173
174 m_SimwideCounts[landOwner] += partCount;
175 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
176 parcelCounts.Users[obj.OwnerID] += partCount;
177 else
178 parcelCounts.Users[obj.OwnerID] = partCount;
179
180 if (landData.IsGroupOwned)
181 {
182 if (obj.OwnerID == landData.GroupID)
183 parcelCounts.Owner += partCount;
184 else if (obj.GroupID == landData.GroupID)
185 parcelCounts.Group += partCount;
186 else
187 parcelCounts.Others += partCount;
188 }
189 else
190 {
191 if (obj.OwnerID == landData.OwnerID)
192 parcelCounts.Owner += partCount;
193 else if (obj.GroupID == landData.GroupID)
194 parcelCounts.Group += partCount;
195 else
196 parcelCounts.Others += partCount;
197 }
198 }
199 }
200
201 // NOTE: Call under Taint Lock
202 private void RemoveObject(SceneObjectGroup obj)
203 {
204 }
205
206 public IPrimCounts GetPrimCounts(UUID parcelID)
207 {
208 PrimCounts primCounts;
209
210 lock (m_PrimCounts)
211 {
212 if (m_PrimCounts.TryGetValue(parcelID, out primCounts))
213 return primCounts;
214
215 primCounts = new PrimCounts(parcelID, this);
216 m_PrimCounts[parcelID] = primCounts;
217 }
218 return primCounts;
219 }
220
221 public int GetOwnerCount(UUID parcelID)
222 {
223 lock (m_TaintLock)
224 {
225 if (m_Tainted)
226 Recount();
227
228 ParcelCounts counts;
229 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
230 return counts.Owner;
231 }
232 return 0;
233 }
234
235 public int GetGroupCount(UUID parcelID)
236 {
237 lock (m_TaintLock)
238 {
239 if (m_Tainted)
240 Recount();
241
242 ParcelCounts counts;
243 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
244 return counts.Group;
245 }
246 return 0;
247 }
248
249 public int GetOthersCount(UUID parcelID)
250 {
251 lock (m_TaintLock)
252 {
253 if (m_Tainted)
254 Recount();
255
256 ParcelCounts counts;
257 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
258 return counts.Others;
259 }
260 return 0;
261 }
262
263 public int GetSimulatorCount(UUID parcelID)
264 {
265 lock (m_TaintLock)
266 {
267 if (m_Tainted)
268 Recount();
269
270 UUID owner;
271 if (m_OwnerMap.TryGetValue(parcelID, out owner))
272 {
273 int val;
274 if (m_SimwideCounts.TryGetValue(owner, out val))
275 return val;
276 }
277 }
278 return 0;
279 }
280
281 public int GetUserCount(UUID parcelID, UUID userID)
282 {
283 lock (m_TaintLock)
284 {
285 if (m_Tainted)
286 Recount();
287
288 ParcelCounts counts;
289 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
290 {
291 int val;
292 if (counts.Users.TryGetValue(userID, out val))
293 return val;
294 }
295 }
296 return 0;
297 }
298
299 // NOTE: This method MUST be called while holding the taint lock!
300 private void Recount()
301 {
302 m_OwnerMap.Clear();
303 m_SimwideCounts.Clear();
304 m_ParcelCounts.Clear();
305
306 List<ILandObject> land = m_Scene.LandChannel.AllParcels();
307
308 foreach (ILandObject l in land)
309 {
310 LandData landData = l.LandData;
311
312 m_OwnerMap[landData.GlobalID] = landData.OwnerID;
313 m_SimwideCounts[landData.OwnerID] = 0;
314 m_ParcelCounts[landData.GlobalID] = new ParcelCounts();
315 }
316
317 m_Scene.ForEachSOG(AddObject);
318
319 List<UUID> primcountKeys = new List<UUID>(m_PrimCounts.Keys);
320 foreach (UUID k in primcountKeys)
321 {
322 if (!m_OwnerMap.ContainsKey(k))
323 m_PrimCounts.Remove(k);
324 }
325 m_Tainted = false;
326 }
327 }
328
329 public class PrimCounts : IPrimCounts
330 {
331 private PrimCountModule m_Parent;
332 private UUID m_ParcelID;
333 private UserPrimCounts m_UserPrimCounts;
334
335 public PrimCounts (UUID parcelID, PrimCountModule parent)
336 {
337 m_ParcelID = parcelID;
338 m_Parent = parent;
339
340 m_UserPrimCounts = new UserPrimCounts(this);
341 }
342
343 public int Owner
344 {
345 get
346 {
347 return m_Parent.GetOwnerCount(m_ParcelID);
348 }
349 }
350
351 public int Group
352 {
353 get
354 {
355 return m_Parent.GetGroupCount(m_ParcelID);
356 }
357 }
358
359 public int Others
360 {
361 get
362 {
363 return m_Parent.GetOthersCount(m_ParcelID);
364 }
365 }
366
367 public int Simulator
368 {
369 get
370 {
371 return m_Parent.GetSimulatorCount(m_ParcelID);
372 }
373 }
374
375 public IUserPrimCounts Users
376 {
377 get
378 {
379 return m_UserPrimCounts;
380 }
381 }
382
383 public int GetUserCount(UUID userID)
384 {
385 return m_Parent.GetUserCount(m_ParcelID, userID);
386 }
387 }
388
389 public class UserPrimCounts : IUserPrimCounts
390 {
391 private PrimCounts m_Parent;
392
393 public UserPrimCounts(PrimCounts parent)
394 {
395 m_Parent = parent;
396 }
397
398 public int this[UUID userID]
399 {
400 get
401 {
402 return m_Parent.GetUserCount(userID);
403 }
404 }
405 }
406}
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index 2e82e7e..19ee7f5 100644
--- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -47,8 +47,8 @@ namespace OpenSim.Region.CoreModules.World.Region
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")] 47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")]
48 public class RestartModule : INonSharedRegionModule, IRestartModule 48 public class RestartModule : INonSharedRegionModule, IRestartModule
49 { 49 {
50 private static readonly ILog m_log = 50// private static readonly ILog m_log =
51 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 protected Scene m_Scene; 53 protected Scene m_Scene;
54 protected Timer m_CountdownTimer = null; 54 protected Timer m_CountdownTimer = null;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
index 3ee20ae..2919897 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Text; 30using System.Text;
31using OpenSim.Region.Framework.Interfaces; 31using OpenSim.Region.Framework.Interfaces;
32using OpenSim.Region.Framework.Scenes; 32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Framework;
33 34
34namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders 35namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
35{ 36{
@@ -53,17 +54,120 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
53 return retval; 54 return retval;
54 } 55 }
55 56
57 public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight)
58 {
59 TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight);
60
61 FileInfo file = new FileInfo(filename);
62 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
63 BinaryReader bs = new BinaryReader(s);
64
65 bool eof = false;
66
67 int fileXPoints = 0;
68 int fileYPoints = 0;
69
70 // Terragen file
71 while (eof == false)
72 {
73 string tmp = Encoding.ASCII.GetString(bs.ReadBytes(4));
74 switch (tmp)
75 {
76 case "SIZE":
77 fileXPoints = bs.ReadInt16() + 1;
78 fileYPoints = fileXPoints;
79 bs.ReadInt16();
80 break;
81 case "XPTS":
82 fileXPoints = bs.ReadInt16();
83 bs.ReadInt16();
84 break;
85 case "YPTS":
86 fileYPoints = bs.ReadInt16();
87 bs.ReadInt16();
88 break;
89 case "ALTW":
90 eof = true;
91 Int16 heightScale = bs.ReadInt16();
92 Int16 baseHeight = bs.ReadInt16();
93
94 int currFileYOffset = 0;
95
96 // if our region isn't on the first X section of the areas to be landscaped, then
97 // advance to our section of the file
98 while (currFileYOffset < offsetY)
99 {
100 // read a whole strip of regions
101 int heightsToRead = sectionHeight * fileXPoints;
102 bs.ReadBytes(heightsToRead * 2); // because the shorts are 2 bytes in the file
103 currFileYOffset++;
104 }
105
106 for (int y = 0; y < sectionHeight; y++)
107 {
108 int currFileXOffset = 0;
109
110 // if our region isn't the first X section of the areas to be landscaped, then
111 // advance the stream to the X start pos of our section in the file
112 // i.e. eat X upto where we start
113 while (currFileXOffset < offsetX)
114 {
115 bs.ReadBytes(sectionWidth * 2); // 2 bytes = short
116 currFileXOffset++;
117 }
118
119 // got to our X offset, so write our regions X line
120 for (int x = 0; x < sectionWidth; x++)
121 {
122 // Read a strip and continue
123 retval[x, y] = baseHeight + bs.ReadInt16() * (double)heightScale / 65536.0;
124 }
125 // record that we wrote it
126 currFileXOffset++;
127
128 // if our region isn't the last X section of the areas to be landscaped, then
129 // advance the stream to the end of this Y column
130 while (currFileXOffset < fileWidth)
131 {
132 // eat the next regions x line
133 bs.ReadBytes(sectionWidth * 2); // 2 bytes = short
134 currFileXOffset++;
135 }
136 //eat the last additional point
137 bs.ReadInt16();
138 }
139
140
141 break;
142 default:
143 bs.ReadInt32();
144 break;
145 }
146 }
147
148 bs.Close();
149 s.Close();
150
151 return retval;
152 }
153
56 public ITerrainChannel LoadStream(Stream s) 154 public ITerrainChannel LoadStream(Stream s)
57 { 155 {
58 TerrainChannel retval = new TerrainChannel(); 156
157 int w = (int)Constants.RegionSize;
158 int h = (int)Constants.RegionSize;
159
160 TerrainChannel retval = new TerrainChannel(w, h);
59 161
60 BinaryReader bs = new BinaryReader(s); 162 BinaryReader bs = new BinaryReader(s);
61 163
62 bool eof = false; 164 bool eof = false;
63 if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") 165 if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
64 { 166 {
65 int w = 256; 167
66 int h = 256; 168 int fileWidth = w;
169 int fileHeight = h;
170
67 171
68 // Terragen file 172 // Terragen file
69 while (eof == false) 173 while (eof == false)
@@ -73,30 +177,27 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
73 { 177 {
74 case "SIZE": 178 case "SIZE":
75 int sztmp = bs.ReadInt16() + 1; 179 int sztmp = bs.ReadInt16() + 1;
76 w = sztmp; 180 fileWidth = sztmp;
77 h = sztmp; 181 fileHeight = sztmp;
78 bs.ReadInt16(); 182 bs.ReadInt16();
79 break; 183 break;
80 case "XPTS": 184 case "XPTS":
81 w = bs.ReadInt16(); 185 fileWidth = bs.ReadInt16();
82 bs.ReadInt16(); 186 bs.ReadInt16();
83 break; 187 break;
84 case "YPTS": 188 case "YPTS":
85 h = bs.ReadInt16(); 189 fileHeight = bs.ReadInt16();
86 bs.ReadInt16(); 190 bs.ReadInt16();
87 break; 191 break;
88 case "ALTW": 192 case "ALTW":
89 eof = true; 193 eof = true;
90 Int16 heightScale = bs.ReadInt16(); 194 Int16 heightScale = bs.ReadInt16();
91 Int16 baseHeight = bs.ReadInt16(); 195 Int16 baseHeight = bs.ReadInt16();
92 retval = new TerrainChannel(w, h); 196 for (int y = 0; y < h; y++)
93 int x;
94 for (x = 0; x < w; x++)
95 { 197 {
96 int y; 198 for (int x = 0; x < w; x++)
97 for (y = 0; y < h; y++)
98 { 199 {
99 retval[x, y] = baseHeight + bs.ReadInt16() * (double) heightScale / 65536.0; 200 retval[x, y] = baseHeight + bs.ReadInt16() * (double)heightScale / 65536.0;
100 } 201 }
101 } 202 }
102 break; 203 break;
@@ -114,12 +215,92 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
114 215
115 public void SaveFile(string filename, ITerrainChannel map) 216 public void SaveFile(string filename, ITerrainChannel map)
116 { 217 {
117 throw new NotImplementedException(); 218 FileInfo file = new FileInfo(filename);
219 FileStream s = file.Open(FileMode.Create, FileAccess.Write);
220 SaveStream(s, map);
221
222 s.Close();
118 } 223 }
119 224
120 public void SaveStream(Stream stream, ITerrainChannel map) 225 public void SaveStream(Stream stream, ITerrainChannel map)
121 { 226 {
122 throw new NotImplementedException(); 227 BinaryWriter bs = new BinaryWriter(stream);
228
229 //find the max and min heights on the map
230 double heightMax = map[0,0];
231 double heightMin = map[0,0];
232
233 for (int y = 0; y < map.Height; y++)
234 {
235 for (int x = 0; x < map.Width; x++)
236 {
237 double current = map[x,y];
238 if (heightMax < current)
239 heightMax = current;
240 if (heightMin > current)
241 heightMin = current;
242 }
243 }
244
245 double baseHeight = Math.Floor( (heightMax + heightMin) / 2d );
246
247 double horizontalScale = Math.Ceiling((heightMax - heightMin));
248
249 // if we are completely flat add 1cm range to avoid NaN divisions
250 if (horizontalScale < 0.01d)
251 horizontalScale = 0.01d;
252
253 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
254
255 bs.Write(enc.GetBytes("TERRAGENTERRAIN "));
256
257 bs.Write(enc.GetBytes("SIZE"));
258 bs.Write(Convert.ToInt16(Constants.RegionSize));
259 bs.Write(Convert.ToInt16(0)); // necessary padding
260
261 //The XPTS and YPTS chunks are not needed for square regions
262 //but L3DT won't load the terrain file properly without them.
263 bs.Write(enc.GetBytes("XPTS"));
264 bs.Write(Convert.ToInt16(Constants.RegionSize));
265 bs.Write(Convert.ToInt16(0)); // necessary padding
266
267 bs.Write(enc.GetBytes("YPTS"));
268 bs.Write(Convert.ToInt16(Constants.RegionSize));
269 bs.Write(Convert.ToInt16(0)); // necessary padding
270
271 bs.Write(enc.GetBytes("SCAL"));
272 bs.Write(ToLittleEndian(1f)); //we're going to say that 1 terrain unit is 1 metre
273 bs.Write(ToLittleEndian(1f));
274 bs.Write(ToLittleEndian(1f));
275
276 // as we are square and not projected on a sphere then the other
277 // header blocks are not required
278
279 // now write the elevation data
280 bs.Write(enc.GetBytes("ALTW"));
281 bs.Write(Convert.ToInt16(horizontalScale)); // range between max and min
282 bs.Write(Convert.ToInt16(baseHeight)); // base height or mid point
283
284 for (int y = 0; y < map.Height; y++)
285 {
286 for (int x = 0; x < map.Width; x++)
287 {
288 float elevation = (float)((map[x,y] - baseHeight) * 65536 ) / (float)horizontalScale; // see LoadStream for inverse
289
290 // clamp rounding issues
291 if (elevation > Int16.MaxValue)
292 elevation = Int16.MaxValue;
293 else if (elevation < Int16.MinValue)
294 elevation = Int16.MinValue;
295
296 bs.Write(Convert.ToInt16(elevation));
297 }
298 }
299
300 //This is only necessary for older versions of Terragen.
301 bs.Write(enc.GetBytes("EOF "));
302
303 bs.Close();
123 } 304 }
124 305
125 public string FileExtension 306 public string FileExtension
@@ -127,16 +308,34 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
127 get { return ".ter"; } 308 get { return ".ter"; }
128 } 309 }
129 310
130 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
131 {
132 throw new NotImplementedException();
133 }
134
135 #endregion 311 #endregion
136 312
137 public override string ToString() 313 public override string ToString()
138 { 314 {
139 return "Terragen"; 315 return "Terragen";
140 } 316 }
317
318 /// <summary>
319 /// terragen SCAL floats need to be written intel ordered regardless of
320 /// big or little endian system
321 /// </summary>
322 /// <param name="number"></param>
323 /// <returns></returns>
324 private byte[] ToLittleEndian( float number)
325 {
326 byte[] retVal = BitConverter.GetBytes(number);
327 if (BitConverter.IsLittleEndian == false)
328 {
329 byte[] tmp = new byte[4];
330 for (int i = 0; i < 4; i++)
331 {
332 tmp[i] = retVal[3 - i];
333 }
334 retVal = tmp;
335
336 }
337 return retVal ;
338 }
339
141 } 340 }
142} 341}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 4611352..9d968e7 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -131,7 +131,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
131 m_scene.EventManager.OnNewClient += EventManager_OnNewClient; 131 m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
132 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; 132 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
133 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; 133 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
134 InstallInterfaces();
135 } 134 }
136 135
137 InstallDefaultEffects(); 136 InstallDefaultEffects();
@@ -140,6 +139,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
140 139
141 public void RegionLoaded(Scene scene) 140 public void RegionLoaded(Scene scene)
142 { 141 {
142 //Do this here to give file loaders time to initialize and
143 //register their supported file extensions and file formats.
144 InstallInterfaces();
143 } 145 }
144 146
145 public void RemoveRegion(Scene scene) 147 public void RemoveRegion(Scene scene)
@@ -1084,8 +1086,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1084 { 1086 {
1085 // Load / Save 1087 // Load / Save
1086 string supportedFileExtensions = ""; 1088 string supportedFileExtensions = "";
1089 string supportedFilesSeparator = "";
1087 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 1090 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
1088 supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")"; 1091 {
1092 supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")";
1093 supportedFilesSeparator = ", ";
1094 }
1089 1095
1090 Command loadFromFileCommand = 1096 Command loadFromFileCommand =
1091 new Command("load", CommandIntentions.COMMAND_HAZARDOUS, InterfaceLoadFile, "Loads a terrain from a specified file."); 1097 new Command("load", CommandIntentions.COMMAND_HAZARDOUS, InterfaceLoadFile, "Loads a terrain from a specified file.");