clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections.Generic;
30 using System.Net;
31 using System.Net.Sockets;
32 using System.Reflection;
33 using System.Xml;
34 using System.IO;
35 using log4net;
36 using Nini.Config;
37 using OpenMetaverse;
38 using OpenMetaverse.StructuredData;
39 //using OpenSim.Framework.Console;
40  
41 namespace OpenSim.Framework
42 {
43 public class RegionLightShareData : ICloneable
44 {
45 public bool valid = false;
46 public UUID regionID = UUID.Zero;
47 public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f);
48 public float waterFogDensityExponent = 4.0f;
49 public float underwaterFogModifier = 0.25f;
50 public Vector3 reflectionWaveletScale = new Vector3(2.0f,2.0f,2.0f);
51 public float fresnelScale = 0.40f;
52 public float fresnelOffset = 0.50f;
53 public float refractScaleAbove = 0.03f;
54 public float refractScaleBelow = 0.20f;
55 public float blurMultiplier = 0.040f;
56 public Vector2 bigWaveDirection = new Vector2(1.05f,-0.42f);
57 public Vector2 littleWaveDirection = new Vector2(1.11f,-1.16f);
58 public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4");
59 public Vector4 horizon = new Vector4(0.25f, 0.25f, 0.32f, 0.32f);
60 public float hazeHorizon = 0.19f;
61 public Vector4 blueDensity = new Vector4(0.12f, 0.22f, 0.38f, 0.38f);
62 public float hazeDensity = 0.70f;
63 public float densityMultiplier = 0.18f;
64 public float distanceMultiplier = 0.8f;
65 public UInt16 maxAltitude = 1605;
66 public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f);
67 public float sunMoonPosition = 0.317f;
68 public Vector4 ambient = new Vector4(0.35f,0.35f,0.35f,0.35f);
69 public float eastAngle = 0.0f;
70 public float sunGlowFocus = 0.10f;
71 public float sunGlowSize = 1.75f;
72 public float sceneGamma = 1.0f;
73 public float starBrightness = 0.0f;
74 public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f);
75 public Vector3 cloudXYDensity = new Vector3(1.00f, 0.53f, 1.00f);
76 public float cloudCoverage = 0.27f;
77 public float cloudScale = 0.42f;
78 public Vector3 cloudDetailXYDensity = new Vector3(1.00f, 0.53f, 0.12f);
79 public float cloudScrollX = 0.20f;
80 public bool cloudScrollXLock = false;
81 public float cloudScrollY = 0.01f;
82 public bool cloudScrollYLock = false;
83 public bool drawClassicClouds = true;
84  
85 public delegate void SaveDelegate(RegionLightShareData wl);
86 public event SaveDelegate OnSave;
87 public void Save()
88 {
89 if (OnSave != null)
90 OnSave(this);
91 }
92 public object Clone()
93 {
94 return this.MemberwiseClone(); // call clone method
95 }
96  
97 }
98  
99 public class RegionInfo
100 {
101 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
102 private static readonly string LogHeader = "[REGION INFO]";
103  
104 public string RegionFile = String.Empty;
105 public bool isSandbox = false;
106 public bool Persistent = true;
107  
108 private EstateSettings m_estateSettings;
109 private RegionSettings m_regionSettings;
110 // private IConfigSource m_configSource = null;
111  
112 public UUID originRegionID = UUID.Zero;
113 public string proxyUrl = "";
114 public int ProxyOffset = 0;
115 public string regionSecret = UUID.Random().ToString();
116  
117 public string osSecret;
118  
119 public UUID lastMapUUID = UUID.Zero;
120 public string lastMapRefresh = "0";
121  
122 private float m_nonphysPrimMin = 0;
123 private int m_nonphysPrimMax = 0;
124 private float m_physPrimMin = 0;
125 private int m_physPrimMax = 0;
126 private bool m_clampPrimSize = false;
127 private int m_objectCapacity = 0;
128 private int m_maxPrimsPerUser = -1;
129 private int m_linksetCapacity = 0;
130 private int m_agentCapacity = 0;
131 private string m_regionType = String.Empty;
132 private RegionLightShareData m_windlight = new RegionLightShareData();
133 protected uint m_httpPort;
134 protected string m_serverURI;
135 protected string m_regionName = String.Empty;
136 protected bool Allow_Alternate_Ports;
137 public bool m_allow_alternate_ports;
138 protected string m_externalHostName;
139 protected IPEndPoint m_internalEndPoint;
140 protected uint m_remotingPort;
141 public UUID RegionID = UUID.Zero;
142 public string RemotingAddress;
143 public UUID ScopeID = UUID.Zero;
144 private UUID m_maptileStaticUUID = UUID.Zero;
145  
146 public uint WorldLocX = 0;
147 public uint WorldLocY = 0;
148 public uint WorldLocZ = 0;
149  
150 /// <summary>
151 /// X dimension of the region.
152 /// </summary>
153 /// <remarks>
154 /// If this is a varregion then the default size set here will be replaced when we load the region config.
155 /// </remarks>
156 public uint RegionSizeX = Constants.RegionSize;
157  
158 /// <summary>
159 /// X dimension of the region.
160 /// </summary>
161 /// <remarks>
162 /// If this is a varregion then the default size set here will be replaced when we load the region config.
163 /// </remarks>
164 public uint RegionSizeY = Constants.RegionSize;
165  
166 /// <summary>
167 /// Z dimension of the region.
168 /// </summary>
169 /// <remarks>
170 /// XXX: Unknown if this accounts for regions with negative Z.
171 /// </remarks>
172 public uint RegionSizeZ = Constants.RegionHeight;
173  
174 private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>();
175  
176 // Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
177  
178 // MT: Yes. Estates can't span trust boundaries. Therefore, it can be
179 // assumed that all instances belonging to one estate are able to
180 // access the same database server. Since estate settings are lodaed
181 // from there, that should be sufficient for full remote administration
182  
183 // File based loading
184 //
185 public RegionInfo(string description, string filename, bool skipConsoleConfig, IConfigSource configSource) : this(description, filename, skipConsoleConfig, configSource, String.Empty)
186 {
187 }
188  
189 public RegionInfo(string description, string filename, bool skipConsoleConfig, IConfigSource configSource, string configName)
190 {
191 // m_configSource = configSource;
192  
193 if (filename.ToLower().EndsWith(".ini"))
194 {
195 if (!File.Exists(filename)) // New region config request
196 {
197 IniConfigSource newFile = new IniConfigSource();
198 ReadNiniConfig(newFile, configName);
199  
200 newFile.Save(filename);
201  
202 RegionFile = filename;
203  
204 return;
205 }
206  
207 IniConfigSource source = new IniConfigSource(filename);
208  
209 bool saveFile = false;
210 if (source.Configs[configName] == null)
211 saveFile = true;
212  
213 ReadNiniConfig(source, configName);
214  
215 if (configName != String.Empty && saveFile)
216 source.Save(filename);
217  
218 RegionFile = filename;
219  
220 return;
221 }
222  
223 try
224 {
225 // This will throw if it's not legal Nini XML format
226 //
227 IConfigSource xmlsource = new XmlConfigSource(filename);
228  
229 ReadNiniConfig(xmlsource, configName);
230  
231 RegionFile = filename;
232  
233 return;
234 }
235 catch (Exception)
236 {
237 }
238 }
239  
240 // The web loader uses this
241 //
242 public RegionInfo(string description, XmlNode xmlNode, bool skipConsoleConfig, IConfigSource configSource)
243 {
244 XmlElement elem = (XmlElement)xmlNode;
245 string name = elem.GetAttribute("Name");
246 string xmlstr = "<Nini>" + xmlNode.OuterXml + "</Nini>";
247 XmlConfigSource source = new XmlConfigSource(XmlReader.Create(new StringReader(xmlstr)));
248 ReadNiniConfig(source, name);
249  
250 m_serverURI = string.Empty;
251 }
252  
253 public RegionInfo(uint legacyRegionLocX, uint legacyRegionLocY, IPEndPoint internalEndPoint, string externalUri)
254 {
255 RegionLocX = legacyRegionLocX;
256 RegionLocY = legacyRegionLocY;
257 RegionSizeX = Constants.RegionSize;
258 RegionSizeY = Constants.RegionSize;
259 m_internalEndPoint = internalEndPoint;
260 m_externalHostName = externalUri;
261 m_serverURI = string.Empty;
262 }
263  
264 public RegionInfo()
265 {
266 m_serverURI = string.Empty;
267 }
268  
269 public EstateSettings EstateSettings
270 {
271 get
272 {
273 if (m_estateSettings == null)
274 {
275 m_estateSettings = new EstateSettings();
276 }
277  
278 return m_estateSettings;
279 }
280  
281 set { m_estateSettings = value; }
282 }
283  
284 public RegionSettings RegionSettings
285 {
286 get
287 {
288 if (m_regionSettings == null)
289 {
290 m_regionSettings = new RegionSettings();
291 }
292  
293 return m_regionSettings;
294 }
295  
296 set { m_regionSettings = value; }
297 }
298  
299 public RegionLightShareData WindlightSettings
300 {
301 get
302 {
303 if (m_windlight == null)
304 {
305 m_windlight = new RegionLightShareData();
306 }
307  
308 return m_windlight;
309 }
310  
311 set { m_windlight = value; }
312 }
313  
314 public float NonphysPrimMin
315 {
316 get { return m_nonphysPrimMin; }
317 }
318  
319 public int NonphysPrimMax
320 {
321 get { return m_nonphysPrimMax; }
322 }
323  
324 public float PhysPrimMin
325 {
326 get { return m_physPrimMin; }
327 }
328  
329 public int PhysPrimMax
330 {
331 get { return m_physPrimMax; }
332 }
333  
334 public bool ClampPrimSize
335 {
336 get { return m_clampPrimSize; }
337 }
338  
339 public int ObjectCapacity
340 {
341 get { return m_objectCapacity; }
342 }
343  
344 public int MaxPrimsPerUser
345 {
346 get { return m_maxPrimsPerUser; }
347 }
348  
349 public int LinksetCapacity
350 {
351 get { return m_linksetCapacity; }
352 }
353  
354 public int AgentCapacity
355 {
356 get { return m_agentCapacity; }
357 }
358  
359 public byte AccessLevel
360 {
361 get { return (byte)Util.ConvertMaturityToAccessLevel((uint)RegionSettings.Maturity); }
362 }
363  
364 public string RegionType
365 {
366 get { return m_regionType; }
367 }
368  
369 public UUID MaptileStaticUUID
370 {
371 get { return m_maptileStaticUUID; }
372 }
373  
374 public string MaptileStaticFile { get; private set; }
375  
376 /// <summary>
377 /// The port by which http communication occurs with the region (most noticeably, CAPS communication)
378 /// </summary>
379 public uint HttpPort
380 {
381 get { return m_httpPort; }
382 set { m_httpPort = value; }
383 }
384  
385 /// <summary>
386 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
387 /// </summary>
388  
389 public string ServerURI
390 {
391 get {
392 if ( m_serverURI != string.Empty ) {
393 return m_serverURI;
394 } else {
395 return "http://" + m_externalHostName + ":" + m_httpPort + "/";
396 }
397 }
398 set {
399 if ( value.EndsWith("/") ) {
400 m_serverURI = value;
401 } else {
402 m_serverURI = value + '/';
403 }
404 }
405 }
406  
407 public string RegionName
408 {
409 get { return m_regionName; }
410 set { m_regionName = value; }
411 }
412  
413 public uint RemotingPort
414 {
415 get { return m_remotingPort; }
416 set { m_remotingPort = value; }
417 }
418  
419 /// <value>
420 /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw.
421 ///
422 /// XXX Isn't this really doing too much to be a simple getter, rather than an explict method?
423 /// </value>
424 public IPEndPoint ExternalEndPoint
425 {
426 get
427 {
428 // Old one defaults to IPv6
429 //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port);
430  
431 IPAddress ia = null;
432 // If it is already an IP, don't resolve it - just return directly
433 if (IPAddress.TryParse(m_externalHostName, out ia))
434 return new IPEndPoint(ia, m_internalEndPoint.Port);
435  
436 // Reset for next check
437 ia = null;
438 try
439 {
440 foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName))
441 {
442 if (ia == null)
443 ia = Adr;
444  
445 if (Adr.AddressFamily == AddressFamily.InterNetwork)
446 {
447 ia = Adr;
448 break;
449 }
450 }
451 }
452 catch (SocketException e)
453 {
454 throw new Exception(
455 "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" +
456 e + "' attached to this exception", e);
457 }
458  
459 return new IPEndPoint(ia, m_internalEndPoint.Port);
460 }
461  
462 set { m_externalHostName = value.ToString(); }
463 }
464  
465 public string ExternalHostName
466 {
467 get { return m_externalHostName; }
468 set { m_externalHostName = value; }
469 }
470  
471 public IPEndPoint InternalEndPoint
472 {
473 get { return m_internalEndPoint; }
474 set { m_internalEndPoint = value; }
475 }
476  
477 /// <summary>
478 /// The x co-ordinate of this region in map tiles (e.g. 1000).
479 /// Coordinate is scaled as world coordinates divided by the legacy region size
480 /// and is thus is the number of legacy regions.
481 /// </summary>
482 public uint RegionLocX
483 {
484 get { return WorldLocX / Constants.RegionSize; }
485 set { WorldLocX = value * Constants.RegionSize; }
486 }
487  
488 /// <summary>
489 /// The y co-ordinate of this region in map tiles (e.g. 1000).
490 /// Coordinate is scaled as world coordinates divided by the legacy region size
491 /// and is thus is the number of legacy regions.
492 /// </summary>
493 public uint RegionLocY
494 {
495 get { return WorldLocY / Constants.RegionSize; }
496 set { WorldLocY = value * Constants.RegionSize; }
497 }
498  
499 public void SetDefaultRegionSize()
500 {
501 WorldLocX = 0;
502 WorldLocY = 0;
503 WorldLocZ = 0;
504 RegionSizeX = Constants.RegionSize;
505 RegionSizeY = Constants.RegionSize;
506 RegionSizeZ = Constants.RegionHeight;
507 }
508  
509 // A unique region handle is created from the region's world coordinates.
510 // This cannot be changed because some code expects to receive the region handle and then
511 // compute the region coordinates from it.
512 public ulong RegionHandle
513 {
514 get { return Util.UIntsToLong(WorldLocX, WorldLocY); }
515 }
516  
517 public void SetEndPoint(string ipaddr, int port)
518 {
519 IPAddress tmpIP = IPAddress.Parse(ipaddr);
520 IPEndPoint tmpEPE = new IPEndPoint(tmpIP, port);
521 m_internalEndPoint = tmpEPE;
522 }
523  
524 public string GetSetting(string key)
525 {
526 string val;
527 string keylower = key.ToLower();
528 if (m_extraSettings.TryGetValue(keylower, out val))
529 return val;
530 m_log.DebugFormat("[RegionInfo] Could not locate value for parameter {0}", key);
531 return null;
532 }
533  
534 private void SetExtraSetting(string key, string value)
535 {
536 string keylower = key.ToLower();
537 m_extraSettings[keylower] = value;
538 }
539  
540 private void ReadNiniConfig(IConfigSource source, string name)
541 {
542 // bool creatingNew = false;
543  
544 if (source.Configs.Count == 0)
545 {
546 MainConsole.Instance.Output("=====================================\n");
547 MainConsole.Instance.Output("We are now going to ask a couple of questions about your region.\n");
548 MainConsole.Instance.Output("You can press 'enter' without typing anything to use the default\n");
549 MainConsole.Instance.Output("the default is displayed between [ ] brackets.\n");
550 MainConsole.Instance.Output("=====================================\n");
551  
552 if (name == String.Empty)
553 {
554 while (name.Trim() == string.Empty)
555 {
556 name = MainConsole.Instance.CmdPrompt("New region name", name);
557 if (name.Trim() == string.Empty)
558 {
559 MainConsole.Instance.Output("Cannot interactively create region with no name");
560 }
561 }
562 }
563  
564 source.AddConfig(name);
565  
566 // creatingNew = true;
567 }
568  
569 if (name == String.Empty)
570 name = source.Configs[0].Name;
571  
572 if (source.Configs[name] == null)
573 {
574 source.AddConfig(name);
575 }
576  
577 RegionName = name;
578 IConfig config = source.Configs[name];
579  
580 // Track all of the keys in this config and remove as they are processed
581 // The remaining keys will be added to generic key-value storage for
582 // whoever might need it
583 HashSet<String> allKeys = new HashSet<String>();
584 foreach (string s in config.GetKeys())
585 {
586 allKeys.Add(s);
587 }
588  
589 // RegionUUID
590 //
591 allKeys.Remove("RegionUUID");
592 string regionUUID = config.GetString("RegionUUID", string.Empty);
593 if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
594 {
595 UUID newID = UUID.Random();
596 while (RegionID == UUID.Zero)
597 {
598 regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
599 if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
600 {
601 MainConsole.Instance.Output("RegionUUID must be a valid UUID");
602 }
603 }
604 config.Set("RegionUUID", regionUUID);
605 }
606  
607 originRegionID = RegionID; // What IS this?! (Needed for RegionCombinerModule?)
608  
609 // Location
610 //
611 allKeys.Remove("Location");
612 string location = config.GetString("Location", String.Empty);
613 if (location == String.Empty)
614 {
615 location = MainConsole.Instance.CmdPrompt("Region Location", "1000,1000");
616 config.Set("Location", location);
617 }
618  
619 string[] locationElements = location.Split(new char[] {','});
620  
621 RegionLocX = Convert.ToUInt32(locationElements[0]);
622 RegionLocY = Convert.ToUInt32(locationElements[1]);
623  
624 // Region size
625 // Default to legacy region size if not specified.
626 allKeys.Remove("SizeX");
627 string configSizeX = config.GetString("SizeX", Constants.RegionSize.ToString());
628 config.Set("SizeX", configSizeX);
629 RegionSizeX = Convert.ToUInt32(configSizeX);
630 allKeys.Remove("SizeY");
631 string configSizeY = config.GetString("SizeY", Constants.RegionSize.ToString());
632 config.Set("SizeY", configSizeX);
633 RegionSizeY = Convert.ToUInt32(configSizeY);
634 allKeys.Remove("SizeZ");
635 string configSizeZ = config.GetString("SizeZ", Constants.RegionHeight.ToString());
636 config.Set("SizeZ", configSizeX);
637 RegionSizeZ = Convert.ToUInt32(configSizeZ);
638  
639 DoRegionSizeSanityChecks();
640  
641 // InternalAddress
642 //
643 IPAddress address;
644 allKeys.Remove("InternalAddress");
645 if (config.Contains("InternalAddress"))
646 {
647 address = IPAddress.Parse(config.GetString("InternalAddress", String.Empty));
648 }
649 else
650 {
651 address = IPAddress.Parse(MainConsole.Instance.CmdPrompt("Internal IP address", "0.0.0.0"));
652 config.Set("InternalAddress", address.ToString());
653 }
654  
655 // InternalPort
656 //
657 int port;
658 allKeys.Remove("InternalPort");
659 if (config.Contains("InternalPort"))
660 {
661 port = config.GetInt("InternalPort", 9000);
662 }
663 else
664 {
665 port = Convert.ToInt32(MainConsole.Instance.CmdPrompt("Internal port", "9000"));
666 config.Set("InternalPort", port);
667 }
668 m_internalEndPoint = new IPEndPoint(address, port);
669  
670 // AllowAlternatePorts
671 //
672 allKeys.Remove("AllowAlternatePorts");
673 if (config.Contains("AllowAlternatePorts"))
674 {
675 m_allow_alternate_ports = config.GetBoolean("AllowAlternatePorts", true);
676 }
677 else
678 {
679 m_allow_alternate_ports = Convert.ToBoolean(MainConsole.Instance.CmdPrompt("Allow alternate ports", "False"));
680  
681 config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString());
682 }
683  
684 // ExternalHostName
685 //
686 allKeys.Remove("ExternalHostName");
687 string externalName;
688 if (config.Contains("ExternalHostName"))
689 {
690 externalName = config.GetString("ExternalHostName", "SYSTEMIP");
691 }
692 else
693 {
694 externalName = MainConsole.Instance.CmdPrompt("External host name", "SYSTEMIP");
695 config.Set("ExternalHostName", externalName);
696 }
697 if (externalName == "SYSTEMIP")
698 {
699 m_externalHostName = Util.GetLocalHost().ToString();
700 m_log.InfoFormat(
701 "[REGIONINFO]: Resolving SYSTEMIP to {0} for external hostname of region {1}",
702 m_externalHostName, name);
703 }
704 else
705 {
706 m_externalHostName = externalName;
707 }
708  
709 // RegionType
710 m_regionType = config.GetString("RegionType", String.Empty);
711 allKeys.Remove("RegionType");
712  
713 #region Prim and map stuff
714  
715 m_nonphysPrimMin = config.GetFloat("NonPhysicalPrimMin", 0);
716 allKeys.Remove("NonPhysicalPrimMin");
717  
718 m_nonphysPrimMax = config.GetInt("NonPhysicalPrimMax", 0);
719 allKeys.Remove("NonPhysicalPrimMax");
720  
721 m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
722 allKeys.Remove("PhysicalPrimMin");
723  
724 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
725 allKeys.Remove("PhysicalPrimMax");
726  
727 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
728 allKeys.Remove("ClampPrimSize");
729  
730 m_objectCapacity = config.GetInt("MaxPrims", 15000);
731 allKeys.Remove("MaxPrims");
732  
733 m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1);
734 allKeys.Remove("MaxPrimsPerUser");
735  
736 m_linksetCapacity = config.GetInt("LinksetPrims", 0);
737 allKeys.Remove("LinksetPrims");
738  
739 allKeys.Remove("MaptileStaticUUID");
740 string mapTileStaticUUID = config.GetString("MaptileStaticUUID", UUID.Zero.ToString());
741 if (UUID.TryParse(mapTileStaticUUID.Trim(), out m_maptileStaticUUID))
742 {
743 config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
744 }
745  
746 MaptileStaticFile = config.GetString("MaptileStaticFile", String.Empty);
747 allKeys.Remove("MaptileStaticFile");
748  
749 #endregion
750  
751 m_agentCapacity = config.GetInt("MaxAgents", 100);
752 allKeys.Remove("MaxAgents");
753  
754 // Multi-tenancy
755 //
756 ScopeID = new UUID(config.GetString("ScopeID", UUID.Zero.ToString()));
757 allKeys.Remove("ScopeID");
758  
759 foreach (String s in allKeys)
760 {
761 SetExtraSetting(s, config.GetString(s));
762 }
763 }
764  
765 // Make sure user specified region sizes are sane.
766 // Must be multiples of legacy region size (256).
767 private void DoRegionSizeSanityChecks()
768 {
769 if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
770 {
771 // Doing non-legacy region sizes.
772 // Enforce region size to be multiples of the legacy region size (256)
773 uint partial = RegionSizeX % Constants.RegionSize;
774 if (partial != 0)
775 {
776 RegionSizeX -= partial;
777 if (RegionSizeX == 0)
778 RegionSizeX = Constants.RegionSize;
779 m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeX={3} instead of specified {4}",
780 LogHeader, Constants.RegionSize, m_regionName, RegionSizeX, RegionSizeX + partial);
781 }
782 partial = RegionSizeY % Constants.RegionSize;
783 if (partial != 0)
784 {
785 RegionSizeY -= partial;
786 if (RegionSizeY == 0)
787 RegionSizeY = Constants.RegionSize;
788 m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeY={3} instead of specified {4}",
789 LogHeader, Constants.RegionSize, m_regionName, RegionSizeY, RegionSizeY + partial);
790 }
791  
792 // Because of things in the viewer, regions MUST be square.
793 // Remove this check when viewers have been updated.
794 if (RegionSizeX != RegionSizeY)
795 {
796 uint minSize = Math.Min(RegionSizeX, RegionSizeY);
797 RegionSizeX = minSize;
798 RegionSizeY = minSize;
799 m_log.ErrorFormat("{0} Regions must be square until viewers are updated. Forcing region {1} size to <{2},{3}>",
800 LogHeader, m_regionName, RegionSizeX, RegionSizeY);
801 }
802  
803 // There is a practical limit to region size.
804 if (RegionSizeX > Constants.MaximumRegionSize || RegionSizeY > Constants.MaximumRegionSize)
805 {
806 RegionSizeX = Util.Clamp<uint>(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize);
807 RegionSizeY = Util.Clamp<uint>(RegionSizeY, Constants.RegionSize, Constants.MaximumRegionSize);
808 m_log.ErrorFormat("{0} Region dimensions must be less than {1}. Clamping {2}'s size to <{3},{4}>",
809 LogHeader, Constants.MaximumRegionSize, m_regionName, RegionSizeX, RegionSizeY);
810 }
811  
812 m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY);
813 }
814 }
815  
816 private void WriteNiniConfig(IConfigSource source)
817 {
818 IConfig config = source.Configs[RegionName];
819  
820 if (config != null)
821 source.Configs.Remove(config);
822  
823 config = source.AddConfig(RegionName);
824  
825 config.Set("RegionUUID", RegionID.ToString());
826  
827 string location = String.Format("{0},{1}", RegionLocX, RegionLocY);
828 config.Set("Location", location);
829  
830 if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
831 {
832 config.Set("SizeX", RegionSizeX);
833 config.Set("SizeY", RegionSizeY);
834 config.Set("SizeZ", RegionSizeZ);
835 }
836  
837 config.Set("InternalAddress", m_internalEndPoint.Address.ToString());
838 config.Set("InternalPort", m_internalEndPoint.Port);
839  
840 config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString());
841  
842 config.Set("ExternalHostName", m_externalHostName);
843  
844 if (m_nonphysPrimMin > 0)
845 config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
846  
847 if (m_nonphysPrimMax > 0)
848 config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
849  
850 if (m_physPrimMin > 0)
851 config.Set("PhysicalPrimMax", m_physPrimMin);
852  
853 if (m_physPrimMax > 0)
854 config.Set("PhysicalPrimMax", m_physPrimMax);
855  
856 config.Set("ClampPrimSize", m_clampPrimSize.ToString());
857  
858 if (m_objectCapacity > 0)
859 config.Set("MaxPrims", m_objectCapacity);
860  
861 if (m_maxPrimsPerUser > -1)
862 config.Set("MaxPrimsPerUser", m_maxPrimsPerUser);
863  
864 if (m_linksetCapacity > 0)
865 config.Set("LinksetPrims", m_linksetCapacity);
866  
867 if (m_agentCapacity > 0)
868 config.Set("MaxAgents", m_agentCapacity);
869  
870 if (ScopeID != UUID.Zero)
871 config.Set("ScopeID", ScopeID.ToString());
872  
873 if (RegionType != String.Empty)
874 config.Set("RegionType", RegionType);
875  
876 if (m_maptileStaticUUID != UUID.Zero)
877 config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
878  
879 if (MaptileStaticFile != String.Empty)
880 config.Set("MaptileStaticFile", MaptileStaticFile);
881 }
882  
883 public void SaveRegionToFile(string description, string filename)
884 {
885 if (filename.ToLower().EndsWith(".ini"))
886 {
887 IniConfigSource source = new IniConfigSource();
888 try
889 {
890 source = new IniConfigSource(filename); // Load if it exists
891 }
892 catch (Exception)
893 {
894 }
895  
896 WriteNiniConfig(source);
897  
898 source.Save(filename);
899  
900 return;
901 }
902 else
903 throw new Exception("Invalid file type for region persistence.");
904 }
905  
906 public void SaveLastMapUUID(UUID mapUUID)
907 {
908 lastMapUUID = mapUUID;
909 lastMapRefresh = Util.UnixTimeSinceEpoch().ToString();
910 }
911  
912 public OSDMap PackRegionInfoData()
913 {
914 OSDMap args = new OSDMap();
915 args["region_id"] = OSD.FromUUID(RegionID);
916 if ((RegionName != null) && !RegionName.Equals(""))
917 args["region_name"] = OSD.FromString(RegionName);
918 args["external_host_name"] = OSD.FromString(ExternalHostName);
919 args["http_port"] = OSD.FromString(HttpPort.ToString());
920 args["server_uri"] = OSD.FromString(ServerURI);
921  
922 args["region_xloc"] = OSD.FromString(RegionLocX.ToString());
923 args["region_yloc"] = OSD.FromString(RegionLocY.ToString());
924 args["region_size_x"] = OSD.FromString(RegionSizeX.ToString());
925 args["region_size_y"] = OSD.FromString(RegionSizeY.ToString());
926 args["region_size_z"] = OSD.FromString(RegionSizeZ.ToString());
927  
928 args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString());
929 args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString());
930 if ((RemotingAddress != null) && !RemotingAddress.Equals(""))
931 args["remoting_address"] = OSD.FromString(RemotingAddress);
932 args["remoting_port"] = OSD.FromString(RemotingPort.ToString());
933 args["allow_alt_ports"] = OSD.FromBoolean(m_allow_alternate_ports);
934 if ((proxyUrl != null) && !proxyUrl.Equals(""))
935 args["proxy_url"] = OSD.FromString(proxyUrl);
936 if (RegionType != String.Empty)
937 args["region_type"] = OSD.FromString(RegionType);
938  
939 return args;
940 }
941  
942 public void UnpackRegionInfoData(OSDMap args)
943 {
944 if (args["region_id"] != null)
945 RegionID = args["region_id"].AsUUID();
946 if (args["region_name"] != null)
947 RegionName = args["region_name"].AsString();
948 if (args["external_host_name"] != null)
949 ExternalHostName = args["external_host_name"].AsString();
950 if (args["http_port"] != null)
951 UInt32.TryParse(args["http_port"].AsString(), out m_httpPort);
952 if (args["server_uri"] != null)
953 ServerURI = args["server_uri"].AsString();
954 if (args["region_xloc"] != null)
955 {
956 uint locx;
957 UInt32.TryParse(args["region_xloc"].AsString(), out locx);
958 RegionLocX = locx;
959 }
960 if (args["region_yloc"] != null)
961 {
962 uint locy;
963 UInt32.TryParse(args["region_yloc"].AsString(), out locy);
964 RegionLocY = locy;
965 }
966 if (args.ContainsKey("region_size_x"))
967 RegionSizeX = (uint)args["region_size_x"].AsInteger();
968 if (args.ContainsKey("region_size_y"))
969 RegionSizeY = (uint)args["region_size_y"].AsInteger();
970 if (args.ContainsKey("region_size_z"))
971 RegionSizeZ = (uint)args["region_size_z"].AsInteger();
972  
973 IPAddress ip_addr = null;
974 if (args["internal_ep_address"] != null)
975 {
976 IPAddress.TryParse(args["internal_ep_address"].AsString(), out ip_addr);
977 }
978 int port = 0;
979 if (args["internal_ep_port"] != null)
980 {
981 Int32.TryParse(args["internal_ep_port"].AsString(), out port);
982 }
983 InternalEndPoint = new IPEndPoint(ip_addr, port);
984 if (args["remoting_address"] != null)
985 RemotingAddress = args["remoting_address"].AsString();
986 if (args["remoting_port"] != null)
987 UInt32.TryParse(args["remoting_port"].AsString(), out m_remotingPort);
988 if (args["allow_alt_ports"] != null)
989 m_allow_alternate_ports = args["allow_alt_ports"].AsBoolean();
990 if (args["proxy_url"] != null)
991 proxyUrl = args["proxy_url"].AsString();
992 if (args["region_type"] != null)
993 m_regionType = args["region_type"].AsString();
994 }
995  
996 public static RegionInfo Create(UUID regionID, string regionName, uint regX, uint regY, string externalHostName, uint httpPort, uint simPort, uint remotingPort, string serverURI)
997 {
998 RegionInfo regionInfo;
999 IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(externalHostName), (int)simPort);
1000 regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalHostName);
1001 regionInfo.RemotingPort = remotingPort;
1002 regionInfo.RemotingAddress = externalHostName;
1003 regionInfo.HttpPort = httpPort;
1004 regionInfo.RegionID = regionID;
1005 regionInfo.RegionName = regionName;
1006 regionInfo.ServerURI = serverURI;
1007 return regionInfo;
1008 }
1009 }
1010 }