opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 bool commFailTF = false;
105 public ConfigurationMember configMember;
106 public string RegionFile = String.Empty;
107 public bool isSandbox = false;
108 public bool Persistent = true;
109  
110 private EstateSettings m_estateSettings;
111 private RegionSettings m_regionSettings;
112 // private IConfigSource m_configSource = null;
113  
114 public UUID originRegionID = UUID.Zero;
115 public string proxyUrl = "";
116 public int ProxyOffset = 0;
117 public string regionSecret = UUID.Random().ToString();
118  
119 public string osSecret;
120  
121 public UUID lastMapUUID = UUID.Zero;
122 public string lastMapRefresh = "0";
123  
124 private float m_nonphysPrimMin = 0;
125 private int m_nonphysPrimMax = 0;
126 private float m_physPrimMin = 0;
127 private int m_physPrimMax = 0;
128 private bool m_clampPrimSize = false;
129 private int m_objectCapacity = 0;
130 private int m_linksetCapacity = 0;
131 private int m_agentCapacity = 0;
132 private string m_regionType = String.Empty;
133 private RegionLightShareData m_windlight = new RegionLightShareData();
134 protected uint m_httpPort;
135 protected string m_serverURI;
136 protected string m_regionName = String.Empty;
137 protected bool Allow_Alternate_Ports;
138 public bool m_allow_alternate_ports;
139 protected string m_externalHostName;
140 protected IPEndPoint m_internalEndPoint;
141 protected uint m_remotingPort;
142 public UUID RegionID = UUID.Zero;
143 public string RemotingAddress;
144 public UUID ScopeID = UUID.Zero;
145 private UUID m_maptileStaticUUID = UUID.Zero;
146  
147 public uint WorldLocX = 0;
148 public uint WorldLocY = 0;
149 public uint WorldLocZ = 0;
150 public uint RegionSizeX = Constants.RegionSize;
151 public uint RegionSizeY = Constants.RegionSize;
152 public uint RegionSizeZ = Constants.RegionHeight;
153  
154 private Dictionary<String, String> m_otherSettings = new Dictionary<string, string>();
155  
156 // Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
157  
158 // MT: Yes. Estates can't span trust boundaries. Therefore, it can be
159 // assumed that all instances belonging to one estate are able to
160 // access the same database server. Since estate settings are lodaed
161 // from there, that should be sufficient for full remote administration
162  
163 // File based loading
164 //
165 public RegionInfo(string description, string filename, bool skipConsoleConfig, IConfigSource configSource) : this(description, filename, skipConsoleConfig, configSource, String.Empty)
166 {
167 }
168  
169 public RegionInfo(string description, string filename, bool skipConsoleConfig, IConfigSource configSource, string configName)
170 {
171 // m_configSource = configSource;
172  
173 if (filename.ToLower().EndsWith(".ini"))
174 {
175 if (!File.Exists(filename)) // New region config request
176 {
177 IniConfigSource newFile = new IniConfigSource();
178 ReadNiniConfig(newFile, configName);
179  
180 newFile.Save(filename);
181  
182 RegionFile = filename;
183  
184 return;
185 }
186  
187 IniConfigSource source = new IniConfigSource(filename);
188  
189 bool saveFile = false;
190 if (source.Configs[configName] == null)
191 saveFile = true;
192  
193 ReadNiniConfig(source, configName);
194  
195 if (configName != String.Empty && saveFile)
196 source.Save(filename);
197  
198 RegionFile = filename;
199  
200 return;
201 }
202  
203 try
204 {
205 // This will throw if it's not legal Nini XML format
206 // and thereby toss it to the legacy loader
207 //
208 IConfigSource xmlsource = new XmlConfigSource(filename);
209  
210 ReadNiniConfig(xmlsource, configName);
211  
212 RegionFile = filename;
213  
214 return;
215 }
216 catch (Exception)
217 {
218 }
219  
220 configMember =
221 new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig);
222 configMember.performConfigurationRetrieve();
223 RegionFile = filename;
224 }
225  
226 // The web loader uses this
227 //
228 public RegionInfo(string description, XmlNode xmlNode, bool skipConsoleConfig, IConfigSource configSource)
229 {
230 // m_configSource = configSource;
231 configMember =
232 new ConfigurationMember(xmlNode, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig);
233 configMember.performConfigurationRetrieve();
234 m_serverURI = string.Empty;
235 }
236  
237 public RegionInfo(uint legacyRegionLocX, uint legacyRegionLocY, IPEndPoint internalEndPoint, string externalUri)
238 {
239 RegionLocX = legacyRegionLocX;
240 RegionLocY = legacyRegionLocY;
241 RegionSizeX = Constants.RegionSize;
242 RegionSizeY = Constants.RegionSize;
243 m_internalEndPoint = internalEndPoint;
244 m_externalHostName = externalUri;
245 m_serverURI = string.Empty;
246 }
247  
248 public RegionInfo()
249 {
250 m_serverURI = string.Empty;
251 }
252  
253 public EstateSettings EstateSettings
254 {
255 get
256 {
257 if (m_estateSettings == null)
258 {
259 m_estateSettings = new EstateSettings();
260 }
261  
262 return m_estateSettings;
263 }
264  
265 set { m_estateSettings = value; }
266 }
267  
268 public RegionSettings RegionSettings
269 {
270 get
271 {
272 if (m_regionSettings == null)
273 {
274 m_regionSettings = new RegionSettings();
275 }
276  
277 return m_regionSettings;
278 }
279  
280 set { m_regionSettings = value; }
281 }
282  
283 public RegionLightShareData WindlightSettings
284 {
285 get
286 {
287 if (m_windlight == null)
288 {
289 m_windlight = new RegionLightShareData();
290 }
291  
292 return m_windlight;
293 }
294  
295 set { m_windlight = value; }
296 }
297  
298 public float NonphysPrimMin
299 {
300 get { return m_nonphysPrimMin; }
301 }
302  
303 public int NonphysPrimMax
304 {
305 get { return m_nonphysPrimMax; }
306 }
307  
308 public float PhysPrimMin
309 {
310 get { return m_physPrimMin; }
311 }
312  
313 public int PhysPrimMax
314 {
315 get { return m_physPrimMax; }
316 }
317  
318 public bool ClampPrimSize
319 {
320 get { return m_clampPrimSize; }
321 }
322  
323 public int ObjectCapacity
324 {
325 get { return m_objectCapacity; }
326 }
327  
328 public int LinksetCapacity
329 {
330 get { return m_linksetCapacity; }
331 }
332  
333 public int AgentCapacity
334 {
335 get { return m_agentCapacity; }
336 }
337  
338 public byte AccessLevel
339 {
340 get { return (byte)Util.ConvertMaturityToAccessLevel((uint)RegionSettings.Maturity); }
341 }
342  
343 public string RegionType
344 {
345 get { return m_regionType; }
346 }
347  
348 public UUID MaptileStaticUUID
349 {
350 get { return m_maptileStaticUUID; }
351 }
352  
353 /// <summary>
354 /// The port by which http communication occurs with the region (most noticeably, CAPS communication)
355 /// </summary>
356 public uint HttpPort
357 {
358 get { return m_httpPort; }
359 set { m_httpPort = value; }
360 }
361  
362 /// <summary>
363 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
364 /// </summary>
365  
366 public string ServerURI
367 {
368 get {
369 if ( m_serverURI != string.Empty ) {
370 return m_serverURI;
371 } else {
372 return "http://" + m_externalHostName + ":" + m_httpPort + "/";
373 }
374 }
375 set {
376 if ( value.EndsWith("/") ) {
377 m_serverURI = value;
378 } else {
379 m_serverURI = value + '/';
380 }
381 }
382 }
383  
384 public string RegionName
385 {
386 get { return m_regionName; }
387 set { m_regionName = value; }
388 }
389  
390 public uint RemotingPort
391 {
392 get { return m_remotingPort; }
393 set { m_remotingPort = value; }
394 }
395  
396 /// <value>
397 /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw.
398 ///
399 /// XXX Isn't this really doing too much to be a simple getter, rather than an explict method?
400 /// </value>
401 public IPEndPoint ExternalEndPoint
402 {
403 get
404 {
405 // Old one defaults to IPv6
406 //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port);
407  
408 IPAddress ia = null;
409 // If it is already an IP, don't resolve it - just return directly
410 if (IPAddress.TryParse(m_externalHostName, out ia))
411 return new IPEndPoint(ia, m_internalEndPoint.Port);
412  
413 // Reset for next check
414 ia = null;
415 try
416 {
417 foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName))
418 {
419 if (ia == null)
420 ia = Adr;
421  
422 if (Adr.AddressFamily == AddressFamily.InterNetwork)
423 {
424 ia = Adr;
425 break;
426 }
427 }
428 }
429 catch (SocketException e)
430 {
431 throw new Exception(
432 "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" +
433 e + "' attached to this exception", e);
434 }
435  
436 return new IPEndPoint(ia, m_internalEndPoint.Port);
437 }
438  
439 set { m_externalHostName = value.ToString(); }
440 }
441  
442 public string ExternalHostName
443 {
444 get { return m_externalHostName; }
445 set { m_externalHostName = value; }
446 }
447  
448 public IPEndPoint InternalEndPoint
449 {
450 get { return m_internalEndPoint; }
451 set { m_internalEndPoint = value; }
452 }
453  
454 /// <summary>
455 /// The x co-ordinate of this region in map tiles (e.g. 1000).
456 /// Coordinate is scaled as world coordinates divided by the legacy region size
457 /// and is thus is the number of legacy regions.
458 /// </summary>
459 public uint RegionLocX
460 {
461 get { return WorldLocX / Constants.RegionSize; }
462 set { WorldLocX = value * Constants.RegionSize; }
463 }
464  
465 /// <summary>
466 /// The y co-ordinate of this region in map tiles (e.g. 1000).
467 /// Coordinate is scaled as world coordinates divided by the legacy region size
468 /// and is thus is the number of legacy regions.
469 /// </summary>
470 public uint RegionLocY
471 {
472 get { return WorldLocY / Constants.RegionSize; }
473 set { WorldLocY = value * Constants.RegionSize; }
474 }
475  
476 public void SetDefaultRegionSize()
477 {
478 WorldLocX = 0;
479 WorldLocY = 0;
480 WorldLocZ = 0;
481 RegionSizeX = Constants.RegionSize;
482 RegionSizeY = Constants.RegionSize;
483 RegionSizeZ = Constants.RegionHeight;
484 }
485  
486 // A unique region handle is created from the region's world coordinates.
487 // This cannot be changed because some code expects to receive the region handle and then
488 // compute the region coordinates from it.
489 public ulong RegionHandle
490 {
491 get { return Util.UIntsToLong(WorldLocX, WorldLocY); }
492 }
493  
494 public void SetEndPoint(string ipaddr, int port)
495 {
496 IPAddress tmpIP = IPAddress.Parse(ipaddr);
497 IPEndPoint tmpEPE = new IPEndPoint(tmpIP, port);
498 m_internalEndPoint = tmpEPE;
499 }
500  
501 public string GetOtherSetting(string key)
502 {
503 string val;
504 string keylower = key.ToLower();
505 if (m_otherSettings.TryGetValue(keylower, out val))
506 return val;
507 m_log.DebugFormat("[RegionInfo] Could not locate value for parameter {0}", key);
508 return null;
509 }
510  
511 public void SetOtherSetting(string key, string value)
512 {
513 string keylower = key.ToLower();
514 m_otherSettings[keylower] = value;
515 }
516  
517 private void ReadNiniConfig(IConfigSource source, string name)
518 {
519 // bool creatingNew = false;
520  
521 if (source.Configs.Count == 0)
522 {
523 MainConsole.Instance.Output("=====================================\n");
524 MainConsole.Instance.Output("We are now going to ask a couple of questions about your region.\n");
525 MainConsole.Instance.Output("You can press 'enter' without typing anything to use the default\n");
526 MainConsole.Instance.Output("the default is displayed between [ ] brackets.\n");
527 MainConsole.Instance.Output("=====================================\n");
528  
529 if (name == String.Empty)
530 {
531 while (name.Trim() == string.Empty)
532 {
533 name = MainConsole.Instance.CmdPrompt("New region name", name);
534 if (name.Trim() == string.Empty)
535 {
536 MainConsole.Instance.Output("Cannot interactively create region with no name");
537 }
538 }
539 }
540  
541 source.AddConfig(name);
542  
543 // creatingNew = true;
544 }
545  
546 if (name == String.Empty)
547 name = source.Configs[0].Name;
548  
549 if (source.Configs[name] == null)
550 {
551 source.AddConfig(name);
552 }
553  
554 RegionName = name;
555 IConfig config = source.Configs[name];
556  
557 // Track all of the keys in this config and remove as they are processed
558 // The remaining keys will be added to generic key-value storage for
559 // whoever might need it
560 HashSet<String> allKeys = new HashSet<String>();
561 foreach (string s in config.GetKeys())
562 {
563 allKeys.Add(s);
564 }
565  
566 // RegionUUID
567 //
568 allKeys.Remove("RegionUUID");
569 string regionUUID = config.GetString("RegionUUID", string.Empty);
570 if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
571 {
572 UUID newID = UUID.Random();
573 while (RegionID == UUID.Zero)
574 {
575 regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
576 if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
577 {
578 MainConsole.Instance.Output("RegionUUID must be a valid UUID");
579 }
580 }
581 config.Set("RegionUUID", regionUUID);
582 }
583  
584 originRegionID = RegionID; // What IS this?! (Needed for RegionCombinerModule?)
585  
586 // Location
587 //
588 allKeys.Remove("Location");
589 string location = config.GetString("Location", String.Empty);
590 if (location == String.Empty)
591 {
592 location = MainConsole.Instance.CmdPrompt("Region Location", "1000,1000");
593 config.Set("Location", location);
594 }
595  
596 string[] locationElements = location.Split(new char[] {','});
597  
598 RegionLocX = Convert.ToUInt32(locationElements[0]);
599 RegionLocY = Convert.ToUInt32(locationElements[1]);
600  
601 // Region size
602 // Default to legacy region size if not specified.
603 allKeys.Remove("SizeX");
604 string configSizeX = config.GetString("SizeX", Constants.RegionSize.ToString());
605 config.Set("SizeX", configSizeX);
606 RegionSizeX = Convert.ToUInt32(configSizeX);
607 allKeys.Remove("SizeY");
608 string configSizeY = config.GetString("SizeY", Constants.RegionSize.ToString());
609 config.Set("SizeY", configSizeX);
610 RegionSizeY = Convert.ToUInt32(configSizeY);
611 allKeys.Remove("SizeZ");
612 string configSizeZ = config.GetString("SizeZ", Constants.RegionHeight.ToString());
613 config.Set("SizeZ", configSizeX);
614 RegionSizeZ = Convert.ToUInt32(configSizeZ);
615  
616 DoRegionSizeSanityChecks();
617  
618 // InternalAddress
619 //
620 IPAddress address;
621 allKeys.Remove("InternalAddress");
622 if (config.Contains("InternalAddress"))
623 {
624 address = IPAddress.Parse(config.GetString("InternalAddress", String.Empty));
625 }
626 else
627 {
628 address = IPAddress.Parse(MainConsole.Instance.CmdPrompt("Internal IP address", "0.0.0.0"));
629 config.Set("InternalAddress", address.ToString());
630 }
631  
632 // InternalPort
633 //
634 int port;
635 allKeys.Remove("InternalPort");
636 if (config.Contains("InternalPort"))
637 {
638 port = config.GetInt("InternalPort", 9000);
639 }
640 else
641 {
642 port = Convert.ToInt32(MainConsole.Instance.CmdPrompt("Internal port", "9000"));
643 config.Set("InternalPort", port);
644 }
645 m_internalEndPoint = new IPEndPoint(address, port);
646  
647 // AllowAlternatePorts
648 //
649 allKeys.Remove("AllowAlternatePorts");
650 if (config.Contains("AllowAlternatePorts"))
651 {
652 m_allow_alternate_ports = config.GetBoolean("AllowAlternatePorts", true);
653 }
654 else
655 {
656 m_allow_alternate_ports = Convert.ToBoolean(MainConsole.Instance.CmdPrompt("Allow alternate ports", "False"));
657  
658 config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString());
659 }
660  
661 // ExternalHostName
662 //
663 allKeys.Remove("ExternalHostName");
664 string externalName;
665 if (config.Contains("ExternalHostName"))
666 {
667 externalName = config.GetString("ExternalHostName", "SYSTEMIP");
668 }
669 else
670 {
671 externalName = MainConsole.Instance.CmdPrompt("External host name", "SYSTEMIP");
672 config.Set("ExternalHostName", externalName);
673 }
674 if (externalName == "SYSTEMIP")
675 {
676 m_externalHostName = Util.GetLocalHost().ToString();
677 m_log.InfoFormat(
678 "[REGIONINFO]: Resolving SYSTEMIP to {0} for external hostname of region {1}",
679 m_externalHostName, name);
680 }
681 else
682 {
683 m_externalHostName = externalName;
684 }
685  
686 // RegionType
687 m_regionType = config.GetString("RegionType", String.Empty);
688 allKeys.Remove("RegionType");
689  
690 #region Prim and map stuff
691  
692 m_nonphysPrimMin = config.GetFloat("NonPhysicalPrimMin", 0);
693 allKeys.Remove("NonPhysicalPrimMin");
694  
695 m_nonphysPrimMax = config.GetInt("NonPhysicalPrimMax", 0);
696 allKeys.Remove("NonPhysicalPrimMax");
697  
698 m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
699 allKeys.Remove("PhysicalPrimMin");
700  
701 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
702 allKeys.Remove("PhysicalPrimMax");
703  
704 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
705 allKeys.Remove("ClampPrimSize");
706  
707 m_objectCapacity = config.GetInt("MaxPrims", 15000);
708 allKeys.Remove("MaxPrims");
709  
710 m_linksetCapacity = config.GetInt("LinksetPrims", 0);
711 allKeys.Remove("LinksetPrims");
712  
713 allKeys.Remove("MaptileStaticUUID");
714 string mapTileStaticUUID = config.GetString("MaptileStaticUUID", UUID.Zero.ToString());
715 if (UUID.TryParse(mapTileStaticUUID.Trim(), out m_maptileStaticUUID))
716 {
717 config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
718 }
719  
720 #endregion
721  
722 m_agentCapacity = config.GetInt("MaxAgents", 100);
723 allKeys.Remove("MaxAgents");
724  
725 // Multi-tenancy
726 //
727 ScopeID = new UUID(config.GetString("ScopeID", UUID.Zero.ToString()));
728 allKeys.Remove("ScopeID");
729  
730 foreach (String s in allKeys)
731 {
732 SetOtherSetting(s, config.GetString(s));
733 }
734 }
735  
736 // Make sure user specified region sizes are sane.
737 // Must be multiples of legacy region size (256).
738 private void DoRegionSizeSanityChecks()
739 {
740 if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
741 {
742 // Doing non-legacy region sizes.
743 // Enforce region size to be multiples of the legacy region size (256)
744 uint partial = RegionSizeX % Constants.RegionSize;
745 if (partial != 0)
746 {
747 RegionSizeX -= partial;
748 if (RegionSizeX == 0)
749 RegionSizeX = Constants.RegionSize;
750 m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeX={3} instead of specified {4}",
751 LogHeader, Constants.RegionSize, m_regionName, RegionSizeX, RegionSizeX + partial);
752 }
753 partial = RegionSizeY % Constants.RegionSize;
754 if (partial != 0)
755 {
756 RegionSizeY -= partial;
757 if (RegionSizeY == 0)
758 RegionSizeY = Constants.RegionSize;
759 m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeY={3} instead of specified {4}",
760 LogHeader, Constants.RegionSize, m_regionName, RegionSizeY, RegionSizeY + partial);
761 }
762  
763 // Because of things in the viewer, regions MUST be square.
764 // Remove this check when viewers have been updated.
765 if (RegionSizeX != RegionSizeY)
766 {
767 uint minSize = Math.Min(RegionSizeX, RegionSizeY);
768 RegionSizeX = minSize;
769 RegionSizeY = minSize;
770 m_log.ErrorFormat("{0} Regions must be square until viewers are updated. Forcing region {1} size to <{2},{3}>",
771 LogHeader, m_regionName, RegionSizeX, RegionSizeY);
772 }
773  
774 // There is a practical limit to region size.
775 if (RegionSizeX > Constants.MaximumRegionSize || RegionSizeY > Constants.MaximumRegionSize)
776 {
777 RegionSizeX = Util.Clamp<uint>(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize);
778 RegionSizeY = Util.Clamp<uint>(RegionSizeY, Constants.RegionSize, Constants.MaximumRegionSize);
779 m_log.ErrorFormat("{0} Region dimensions must be less than {1}. Clamping {2}'s size to <{3},{4}>",
780 LogHeader, Constants.MaximumRegionSize, m_regionName, RegionSizeX, RegionSizeY);
781 }
782  
783 m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY);
784 }
785 }
786  
787 private void WriteNiniConfig(IConfigSource source)
788 {
789 IConfig config = source.Configs[RegionName];
790  
791 if (config != null)
792 source.Configs.Remove(config);
793  
794 config = source.AddConfig(RegionName);
795  
796 config.Set("RegionUUID", RegionID.ToString());
797  
798 string location = String.Format("{0},{1}", RegionLocX, RegionLocY);
799 config.Set("Location", location);
800  
801 if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
802 {
803 config.Set("SizeX", RegionSizeX);
804 config.Set("SizeY", RegionSizeY);
805 config.Set("SizeZ", RegionSizeZ);
806 }
807  
808 config.Set("InternalAddress", m_internalEndPoint.Address.ToString());
809 config.Set("InternalPort", m_internalEndPoint.Port);
810  
811 config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString());
812  
813 config.Set("ExternalHostName", m_externalHostName);
814  
815 if (m_nonphysPrimMin > 0)
816 config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
817  
818 if (m_nonphysPrimMax > 0)
819 config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
820  
821 if (m_physPrimMin > 0)
822 config.Set("PhysicalPrimMax", m_physPrimMin);
823  
824 if (m_physPrimMax > 0)
825 config.Set("PhysicalPrimMax", m_physPrimMax);
826  
827 config.Set("ClampPrimSize", m_clampPrimSize.ToString());
828  
829 if (m_objectCapacity > 0)
830 config.Set("MaxPrims", m_objectCapacity);
831  
832 if (m_linksetCapacity > 0)
833 config.Set("LinksetPrims", m_linksetCapacity);
834  
835 if (m_agentCapacity > 0)
836 config.Set("MaxAgents", m_agentCapacity);
837  
838 if (ScopeID != UUID.Zero)
839 config.Set("ScopeID", ScopeID.ToString());
840  
841 if (RegionType != String.Empty)
842 config.Set("RegionType", RegionType);
843  
844 if (m_maptileStaticUUID != UUID.Zero)
845 config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
846 }
847  
848 public bool ignoreIncomingConfiguration(string configuration_key, object configuration_result)
849 {
850 return true;
851 }
852  
853 public void SaveRegionToFile(string description, string filename)
854 {
855 if (filename.ToLower().EndsWith(".ini"))
856 {
857 IniConfigSource source = new IniConfigSource();
858 try
859 {
860 source = new IniConfigSource(filename); // Load if it exists
861 }
862 catch (Exception)
863 {
864 }
865  
866 WriteNiniConfig(source);
867  
868 source.Save(filename);
869  
870 return;
871 }
872 else if (filename.ToLower().EndsWith(".xml"))
873 {
874 configMember = new ConfigurationMember(filename, description, loadConfigurationOptionsFromMe,
875 ignoreIncomingConfiguration, false);
876 configMember.performConfigurationRetrieve();
877 RegionFile = filename;
878 }
879 else
880 throw new Exception("Invalid file type for region persistence.");
881 }
882  
883 public void loadConfigurationOptionsFromMe()
884 {
885 configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID_NULL_FREE,
886 "UUID of Region (Default is recommended, random UUID)",
887 RegionID.ToString(), true);
888 configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
889 "Region Name", RegionName, true);
890  
891 configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
892 "Grid Location (X Axis)", RegionLocX.ToString(), true);
893 configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
894 "Grid Location (Y Axis)", RegionLocY.ToString(), true);
895 configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
896 "Size of region in X dimension", RegionSizeX.ToString(), true);
897 configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
898 "Size of region in Y dimension", RegionSizeY.ToString(), true);
899 configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
900 "Size of region in Z dimension", RegionSizeZ.ToString(), true);
901  
902 //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
903 configMember.addConfigurationOption("internal_ip_address",
904 ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
905 "Internal IP Address for incoming UDP client connections",
906 m_internalEndPoint.Address.ToString(),
907 true);
908 configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
909 "Internal IP Port for incoming UDP client connections",
910 m_internalEndPoint.Port.ToString(), true);
911 configMember.addConfigurationOption("allow_alternate_ports",
912 ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
913 "Allow sim to find alternate UDP ports when ports are in use?",
914 m_allow_alternate_ports.ToString(), true);
915 configMember.addConfigurationOption("external_host_name",
916 ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
917 "External Host Name", m_externalHostName, true);
918 configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
919 "Last Map UUID", lastMapUUID.ToString(), true);
920 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
921 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
922  
923 configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
924 "Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
925  
926 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
927 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
928  
929 configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
930 "Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
931  
932 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
933 "Maximum size for physical prims", m_physPrimMax.ToString(), true);
934  
935 configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
936 "Clamp prims to max size", m_clampPrimSize.ToString(), true);
937  
938 configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
939 "Max objects this sim will hold", m_objectCapacity.ToString(), true);
940  
941 configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
942 "Max prims an object will hold", m_linksetCapacity.ToString(), true);
943  
944 configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
945 "Max avatars this sim will hold", m_agentCapacity.ToString(), true);
946  
947 configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
948 "Scope ID for this region", ScopeID.ToString(), true);
949  
950 configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
951 "Free form string describing the type of region", String.Empty, true);
952  
953 configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
954 "UUID of a texture to use as the map for this region", m_maptileStaticUUID.ToString(), true);
955 }
956  
957 public void loadConfigurationOptions()
958 {
959 configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
960 "UUID of Region (Default is recommended, random UUID)",
961 UUID.Random().ToString(), true);
962 configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
963 "Region Name", "OpenSim Test", false);
964  
965 configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
966 "Grid Location (X Axis)", "1000", false);
967 configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
968 "Grid Location (Y Axis)", "1000", false);
969 configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
970 "Size of region in X dimension", Constants.RegionSize.ToString(), false);
971 configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
972 "Size of region in Y dimension", Constants.RegionSize.ToString(), false);
973 configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
974 "Size of region in Z dimension", Constants.RegionHeight.ToString(), false);
975  
976 //m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
977 configMember.addConfigurationOption("internal_ip_address",
978 ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
979 "Internal IP Address for incoming UDP client connections", "0.0.0.0",
980 false);
981 configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
982 "Internal IP Port for incoming UDP client connections",
983 ConfigSettings.DefaultRegionHttpPort.ToString(), false);
984 configMember.addConfigurationOption("allow_alternate_ports", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
985 "Allow sim to find alternate UDP ports when ports are in use?",
986 "false", true);
987 configMember.addConfigurationOption("external_host_name",
988 ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
989 "External Host Name", "127.0.0.1", false);
990 configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
991 "Last Map UUID", lastMapUUID.ToString(), true);
992  
993 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
994 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
995  
996 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
997 "Maximum size for nonphysical prims", "0", true);
998  
999 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
1000 "Maximum size for physical prims", "0", true);
1001  
1002 configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
1003 "Clamp prims to max size", "false", true);
1004  
1005 configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
1006 "Max objects this sim will hold", "15000", true);
1007  
1008 configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
1009 "Max avatars this sim will hold", "100", true);
1010  
1011 configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
1012 "Scope ID for this region", UUID.Zero.ToString(), true);
1013  
1014 configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
1015 "Region Type", String.Empty, true);
1016  
1017 configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
1018 "UUID of a texture to use as the map for this region", String.Empty, true);
1019 }
1020  
1021 public bool handleIncomingConfiguration(string configuration_key, object configuration_result)
1022 {
1023 switch (configuration_key)
1024 {
1025 case "sim_UUID":
1026 RegionID = (UUID) configuration_result;
1027 originRegionID = (UUID) configuration_result;
1028 break;
1029 case "sim_name":
1030 RegionName = (string) configuration_result;
1031 break;
1032 case "sim_location_x":
1033 RegionLocX = (uint) configuration_result;
1034 break;
1035 case "sim_location_y":
1036 RegionLocY = (uint) configuration_result;
1037 break;
1038 case "sim_size_x":
1039 RegionSizeX = (uint) configuration_result;
1040 break;
1041 case "sim_size_y":
1042 RegionSizeY = (uint) configuration_result;
1043 break;
1044 case "sim_size_z":
1045 RegionSizeZ = (uint) configuration_result;
1046 break;
1047 case "internal_ip_address":
1048 IPAddress address = (IPAddress) configuration_result;
1049 m_internalEndPoint = new IPEndPoint(address, 0);
1050 break;
1051 case "internal_ip_port":
1052 m_internalEndPoint.Port = (int) configuration_result;
1053 break;
1054 case "allow_alternate_ports":
1055 m_allow_alternate_ports = (bool) configuration_result;
1056 break;
1057 case "external_host_name":
1058 if ((string) configuration_result != "SYSTEMIP")
1059 {
1060 m_externalHostName = (string) configuration_result;
1061 }
1062 else
1063 {
1064 m_externalHostName = Util.GetLocalHost().ToString();
1065 }
1066 break;
1067 case "lastmap_uuid":
1068 lastMapUUID = (UUID)configuration_result;
1069 break;
1070 case "lastmap_refresh":
1071 lastMapRefresh = (string)configuration_result;
1072 break;
1073 case "nonphysical_prim_max":
1074 m_nonphysPrimMax = (int)configuration_result;
1075 break;
1076 case "physical_prim_max":
1077 m_physPrimMax = (int)configuration_result;
1078 break;
1079 case "clamp_prim_size":
1080 m_clampPrimSize = (bool)configuration_result;
1081 break;
1082 case "object_capacity":
1083 m_objectCapacity = (int)configuration_result;
1084 break;
1085 case "linkset_capacity":
1086 m_linksetCapacity = (int)configuration_result;
1087 break;
1088 case "agent_capacity":
1089 m_agentCapacity = (int)configuration_result;
1090 break;
1091 case "scope_id":
1092 ScopeID = (UUID)configuration_result;
1093 break;
1094 case "region_type":
1095 m_regionType = (string)configuration_result;
1096 break;
1097 case "region_static_maptile":
1098 m_maptileStaticUUID = (UUID)configuration_result;
1099 break;
1100 }
1101  
1102 return true;
1103 }
1104  
1105 public void SaveLastMapUUID(UUID mapUUID)
1106 {
1107 lastMapUUID = mapUUID;
1108 lastMapRefresh = Util.UnixTimeSinceEpoch().ToString();
1109  
1110 if (configMember == null)
1111 return;
1112  
1113 configMember.forceSetConfigurationOption("lastmap_uuid", mapUUID.ToString());
1114 configMember.forceSetConfigurationOption("lastmap_refresh", lastMapRefresh);
1115 }
1116  
1117 public OSDMap PackRegionInfoData()
1118 {
1119 OSDMap args = new OSDMap();
1120 args["region_id"] = OSD.FromUUID(RegionID);
1121 if ((RegionName != null) && !RegionName.Equals(""))
1122 args["region_name"] = OSD.FromString(RegionName);
1123 args["external_host_name"] = OSD.FromString(ExternalHostName);
1124 args["http_port"] = OSD.FromString(HttpPort.ToString());
1125 args["server_uri"] = OSD.FromString(ServerURI);
1126  
1127 args["region_xloc"] = OSD.FromString(RegionLocX.ToString());
1128 args["region_yloc"] = OSD.FromString(RegionLocY.ToString());
1129 args["region_size_x"] = OSD.FromString(RegionSizeX.ToString());
1130 args["region_size_y"] = OSD.FromString(RegionSizeY.ToString());
1131 args["region_size_z"] = OSD.FromString(RegionSizeZ.ToString());
1132  
1133 args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString());
1134 args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString());
1135 if ((RemotingAddress != null) && !RemotingAddress.Equals(""))
1136 args["remoting_address"] = OSD.FromString(RemotingAddress);
1137 args["remoting_port"] = OSD.FromString(RemotingPort.ToString());
1138 args["allow_alt_ports"] = OSD.FromBoolean(m_allow_alternate_ports);
1139 if ((proxyUrl != null) && !proxyUrl.Equals(""))
1140 args["proxy_url"] = OSD.FromString(proxyUrl);
1141 if (RegionType != String.Empty)
1142 args["region_type"] = OSD.FromString(RegionType);
1143  
1144 return args;
1145 }
1146  
1147 public void UnpackRegionInfoData(OSDMap args)
1148 {
1149 if (args["region_id"] != null)
1150 RegionID = args["region_id"].AsUUID();
1151 if (args["region_name"] != null)
1152 RegionName = args["region_name"].AsString();
1153 if (args["external_host_name"] != null)
1154 ExternalHostName = args["external_host_name"].AsString();
1155 if (args["http_port"] != null)
1156 UInt32.TryParse(args["http_port"].AsString(), out m_httpPort);
1157 if (args["server_uri"] != null)
1158 ServerURI = args["server_uri"].AsString();
1159 if (args["region_xloc"] != null)
1160 {
1161 uint locx;
1162 UInt32.TryParse(args["region_xloc"].AsString(), out locx);
1163 RegionLocX = locx;
1164 }
1165 if (args["region_yloc"] != null)
1166 {
1167 uint locy;
1168 UInt32.TryParse(args["region_yloc"].AsString(), out locy);
1169 RegionLocY = locy;
1170 }
1171 if (args.ContainsKey("region_size_x"))
1172 RegionSizeX = (uint)args["region_size_x"].AsInteger();
1173 if (args.ContainsKey("region_size_y"))
1174 RegionSizeY = (uint)args["region_size_y"].AsInteger();
1175 if (args.ContainsKey("region_size_z"))
1176 RegionSizeZ = (uint)args["region_size_z"].AsInteger();
1177  
1178 IPAddress ip_addr = null;
1179 if (args["internal_ep_address"] != null)
1180 {
1181 IPAddress.TryParse(args["internal_ep_address"].AsString(), out ip_addr);
1182 }
1183 int port = 0;
1184 if (args["internal_ep_port"] != null)
1185 {
1186 Int32.TryParse(args["internal_ep_port"].AsString(), out port);
1187 }
1188 InternalEndPoint = new IPEndPoint(ip_addr, port);
1189 if (args["remoting_address"] != null)
1190 RemotingAddress = args["remoting_address"].AsString();
1191 if (args["remoting_port"] != null)
1192 UInt32.TryParse(args["remoting_port"].AsString(), out m_remotingPort);
1193 if (args["allow_alt_ports"] != null)
1194 m_allow_alternate_ports = args["allow_alt_ports"].AsBoolean();
1195 if (args["proxy_url"] != null)
1196 proxyUrl = args["proxy_url"].AsString();
1197 if (args["region_type"] != null)
1198 m_regionType = args["region_type"].AsString();
1199 }
1200  
1201 public static RegionInfo Create(UUID regionID, string regionName, uint regX, uint regY, string externalHostName, uint httpPort, uint simPort, uint remotingPort, string serverURI)
1202 {
1203 RegionInfo regionInfo;
1204 IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(externalHostName), (int)simPort);
1205 regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalHostName);
1206 regionInfo.RemotingPort = remotingPort;
1207 regionInfo.RemotingAddress = externalHostName;
1208 regionInfo.HttpPort = httpPort;
1209 regionInfo.RegionID = regionID;
1210 regionInfo.RegionName = regionName;
1211 regionInfo.ServerURI = serverURI;
1212 return regionInfo;
1213 }
1214 }
1215 }