aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/AssetPermissions.cs84
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs3
-rw-r--r--OpenSim/Framework/Cache.cs83
-rw-r--r--OpenSim/Framework/Client/IClientChat.cs7
-rw-r--r--OpenSim/Framework/Console/ConsoleUtil.cs228
-rw-r--r--OpenSim/Framework/Constants.cs1
-rw-r--r--OpenSim/Framework/EstateSettings.cs10
-rw-r--r--OpenSim/Framework/GridInstantMessage.cs9
-rw-r--r--OpenSim/Framework/IClientAPI.cs46
-rw-r--r--OpenSim/Framework/InventoryFolderBase.cs18
-rw-r--r--OpenSim/Framework/LandData.cs385
-rw-r--r--OpenSim/Framework/Monitoring/BaseStatsCollector.cs23
-rw-r--r--OpenSim/Framework/Monitoring/MemoryWatchdog.cs10
-rw-r--r--OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs19
-rw-r--r--OpenSim/Framework/Monitoring/StatsManager.cs360
-rw-r--r--OpenSim/Framework/Monitoring/Watchdog.cs35
-rw-r--r--OpenSim/Framework/Pool.cs91
-rw-r--r--OpenSim/Framework/RegionFlags.cs53
-rw-r--r--OpenSim/Framework/RegionInfo.cs72
-rw-r--r--OpenSim/Framework/Serialization/ArchiveConstants.cs5
-rw-r--r--OpenSim/Framework/Serialization/External/OspResolver.cs14
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs43
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs274
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs22
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs148
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs2
-rw-r--r--OpenSim/Framework/TaskInventoryDictionary.cs4
-rw-r--r--OpenSim/Framework/TaskInventoryItem.cs19
-rw-r--r--OpenSim/Framework/Util.cs51
-rw-r--r--OpenSim/Framework/WebUtil.cs81
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs (renamed from OpenSim/Framework/PacketPool.cs)97
31 files changed, 1891 insertions, 406 deletions
diff --git a/OpenSim/Framework/AssetPermissions.cs b/OpenSim/Framework/AssetPermissions.cs
new file mode 100644
index 0000000..4a905c2
--- /dev/null
+++ b/OpenSim/Framework/AssetPermissions.cs
@@ -0,0 +1,84 @@
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4
5using Nini.Config;
6using log4net;
7
8using OpenMetaverse;
9
10namespace OpenSim.Framework
11{
12 public class AssetPermissions
13 {
14 private static readonly ILog m_log =
15 LogManager.GetLogger(
16 MethodBase.GetCurrentMethod().DeclaringType);
17
18 private bool[] m_DisallowExport, m_DisallowImport;
19 private string[] m_AssetTypeNames;
20
21 public AssetPermissions(IConfig config)
22 {
23 Type enumType = typeof(AssetType);
24 m_AssetTypeNames = Enum.GetNames(enumType);
25 for (int i = 0; i < m_AssetTypeNames.Length; i++)
26 m_AssetTypeNames[i] = m_AssetTypeNames[i].ToLower();
27 int n = Enum.GetValues(enumType).Length;
28 m_DisallowExport = new bool[n];
29 m_DisallowImport = new bool[n];
30
31 LoadPermsFromConfig(config, "DisallowExport", m_DisallowExport);
32 LoadPermsFromConfig(config, "DisallowImport", m_DisallowImport);
33
34 }
35
36 private void LoadPermsFromConfig(IConfig assetConfig, string variable, bool[] bitArray)
37 {
38 if (assetConfig == null)
39 return;
40
41 string perms = assetConfig.GetString(variable, String.Empty);
42 string[] parts = perms.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
43 foreach (string s in parts)
44 {
45 int index = Array.IndexOf(m_AssetTypeNames, s.Trim().ToLower());
46 if (index >= 0)
47 bitArray[index] = true;
48 else
49 m_log.WarnFormat("[Asset Permissions]: Invalid AssetType {0}", s);
50 }
51
52 }
53
54 public bool AllowedExport(sbyte type)
55 {
56 string assetTypeName = ((AssetType)type).ToString();
57
58 int index = Array.IndexOf(m_AssetTypeNames, assetTypeName.ToLower());
59 if (index >= 0 && m_DisallowExport[index])
60 {
61 m_log.DebugFormat("[Asset Permissions]: Export denied: configuration does not allow export of AssetType {0}", assetTypeName);
62 return false;
63 }
64
65 return true;
66 }
67
68 public bool AllowedImport(sbyte type)
69 {
70 string assetTypeName = ((AssetType)type).ToString();
71
72 int index = Array.IndexOf(m_AssetTypeNames, assetTypeName.ToLower());
73 if (index >= 0 && m_DisallowImport[index])
74 {
75 m_log.DebugFormat("[Asset Permissions]: Import denied: configuration does not allow import of AssetType {0}", assetTypeName);
76 return false;
77 }
78
79 return true;
80 }
81
82
83 }
84}
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index c5d9641..1638541 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -358,6 +358,9 @@ namespace OpenSim.Framework
358 SetVisualParams(visualParams); 358 SetVisualParams(visualParams);
359 } 359 }
360 360
361 /// <summary>
362 /// Set avatar height by a calculation based on their visual parameters.
363 /// </summary>
361 public virtual void SetHeight() 364 public virtual void SetHeight()
362 { 365 {
363 // Start with shortest possible female avatar height 366 // Start with shortest possible female avatar height
diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs
index 79e20fc..31cab4a 100644
--- a/OpenSim/Framework/Cache.cs
+++ b/OpenSim/Framework/Cache.cs
@@ -199,7 +199,14 @@ namespace OpenSim.Framework
199 // 199 //
200 public class Cache 200 public class Cache
201 { 201 {
202 /// <summary>
203 /// Must only be accessed under lock.
204 /// </summary>
202 private List<CacheItemBase> m_Index = new List<CacheItemBase>(); 205 private List<CacheItemBase> m_Index = new List<CacheItemBase>();
206
207 /// <summary>
208 /// Must only be accessed under m_Index lock.
209 /// </summary>
203 private Dictionary<string, CacheItemBase> m_Lookup = 210 private Dictionary<string, CacheItemBase> m_Lookup =
204 new Dictionary<string, CacheItemBase>(); 211 new Dictionary<string, CacheItemBase>();
205 212
@@ -320,19 +327,19 @@ namespace OpenSim.Framework
320 { 327 {
321 if (m_Lookup.ContainsKey(index)) 328 if (m_Lookup.ContainsKey(index))
322 item = m_Lookup[index]; 329 item = m_Lookup[index];
323 }
324 330
325 if (item == null) 331 if (item == null)
326 { 332 {
333 Expire(true);
334 return null;
335 }
336
337 item.hits++;
338 item.lastUsed = DateTime.Now;
339
327 Expire(true); 340 Expire(true);
328 return null;
329 } 341 }
330 342
331 item.hits++;
332 item.lastUsed = DateTime.Now;
333
334 Expire(true);
335
336 return item; 343 return item;
337 } 344 }
338 345
@@ -385,7 +392,10 @@ namespace OpenSim.Framework
385 // 392 //
386 public Object Find(Predicate<CacheItemBase> d) 393 public Object Find(Predicate<CacheItemBase> d)
387 { 394 {
388 CacheItemBase item = m_Index.Find(d); 395 CacheItemBase item;
396
397 lock (m_Index)
398 item = m_Index.Find(d);
389 399
390 if (item == null) 400 if (item == null)
391 return null; 401 return null;
@@ -419,12 +429,12 @@ namespace OpenSim.Framework
419 public virtual void Store(string index, Object data, Type container, 429 public virtual void Store(string index, Object data, Type container,
420 Object[] parameters) 430 Object[] parameters)
421 { 431 {
422 Expire(false);
423
424 CacheItemBase item; 432 CacheItemBase item;
425 433
426 lock (m_Index) 434 lock (m_Index)
427 { 435 {
436 Expire(false);
437
428 if (m_Index.Contains(new CacheItemBase(index))) 438 if (m_Index.Contains(new CacheItemBase(index)))
429 { 439 {
430 if ((m_Flags & CacheFlags.AllowUpdate) != 0) 440 if ((m_Flags & CacheFlags.AllowUpdate) != 0)
@@ -450,9 +460,17 @@ namespace OpenSim.Framework
450 m_Index.Add(item); 460 m_Index.Add(item);
451 m_Lookup[index] = item; 461 m_Lookup[index] = item;
452 } 462 }
463
453 item.Store(data); 464 item.Store(data);
454 } 465 }
455 466
467 /// <summary>
468 /// Expire items as appropriate.
469 /// </summary>
470 /// <remarks>
471 /// Callers must lock m_Index.
472 /// </remarks>
473 /// <param name='getting'></param>
456 protected virtual void Expire(bool getting) 474 protected virtual void Expire(bool getting)
457 { 475 {
458 if (getting && (m_Strategy == CacheStrategy.Aggressive)) 476 if (getting && (m_Strategy == CacheStrategy.Aggressive))
@@ -475,12 +493,10 @@ namespace OpenSim.Framework
475 493
476 switch (m_Strategy) 494 switch (m_Strategy)
477 { 495 {
478 case CacheStrategy.Aggressive: 496 case CacheStrategy.Aggressive:
479 if (Count < Size) 497 if (Count < Size)
480 return; 498 return;
481 499
482 lock (m_Index)
483 {
484 m_Index.Sort(new SortLRU()); 500 m_Index.Sort(new SortLRU());
485 m_Index.Reverse(); 501 m_Index.Reverse();
486 502
@@ -490,7 +506,7 @@ namespace OpenSim.Framework
490 506
491 ExpireDelegate doExpire = OnExpire; 507 ExpireDelegate doExpire = OnExpire;
492 508
493 if (doExpire != null) 509 if (doExpire != null)
494 { 510 {
495 List<CacheItemBase> candidates = 511 List<CacheItemBase> candidates =
496 m_Index.GetRange(target, Count - target); 512 m_Index.GetRange(target, Count - target);
@@ -513,27 +529,34 @@ namespace OpenSim.Framework
513 foreach (CacheItemBase item in m_Index) 529 foreach (CacheItemBase item in m_Index)
514 m_Lookup[item.uuid] = item; 530 m_Lookup[item.uuid] = item;
515 } 531 }
516 } 532
517 break; 533 break;
518 default: 534
519 break; 535 default:
536 break;
520 } 537 }
521 } 538 }
522 539
523 public void Invalidate(string uuid) 540 public void Invalidate(string uuid)
524 { 541 {
525 if (!m_Lookup.ContainsKey(uuid)) 542 lock (m_Index)
526 return; 543 {
544 if (!m_Lookup.ContainsKey(uuid))
545 return;
527 546
528 CacheItemBase item = m_Lookup[uuid]; 547 CacheItemBase item = m_Lookup[uuid];
529 m_Lookup.Remove(uuid); 548 m_Lookup.Remove(uuid);
530 m_Index.Remove(item); 549 m_Index.Remove(item);
550 }
531 } 551 }
532 552
533 public void Clear() 553 public void Clear()
534 { 554 {
535 m_Index.Clear(); 555 lock (m_Index)
536 m_Lookup.Clear(); 556 {
557 m_Index.Clear();
558 m_Lookup.Clear();
559 }
537 } 560 }
538 } 561 }
539} 562} \ No newline at end of file
diff --git a/OpenSim/Framework/Client/IClientChat.cs b/OpenSim/Framework/Client/IClientChat.cs
index 078ea9b..86b1faa 100644
--- a/OpenSim/Framework/Client/IClientChat.cs
+++ b/OpenSim/Framework/Client/IClientChat.cs
@@ -33,7 +33,8 @@ namespace OpenSim.Framework.Client
33 { 33 {
34 event ChatMessage OnChatFromClient; 34 event ChatMessage OnChatFromClient;
35 35
36 void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, 36 void SendChatMessage(
37 byte audible); 37 string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source,
38 byte audible);
38 } 39 }
39} 40} \ No newline at end of file
diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs
new file mode 100644
index 0000000..16a63e0
--- /dev/null
+++ b/OpenSim/Framework/Console/ConsoleUtil.cs
@@ -0,0 +1,228 @@
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.Generic;
30using System.IO;
31using System.Linq;
32using System.Reflection;
33using log4net;
34using OpenMetaverse;
35
36namespace OpenSim.Framework.Console
37{
38 public class ConsoleUtil
39 {
40 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
42 public const int LocalIdNotFound = 0;
43
44 /// <summary>
45 /// Used by modules to display stock co-ordinate help, though possibly this should be under some general section
46 /// rather than in each help summary.
47 /// </summary>
48 public const string CoordHelp
49 = @"Each component of the coord is comma separated. There must be no spaces between the commas.
50 If you don't care about the z component you can simply omit it.
51 If you don't care about the x or y components then you can leave them blank (though a comma is still required)
52 If you want to specify the maxmimum value of a component then you can use ~ instead of a number
53 If you want to specify the minimum value of a component then you can use -~ instead of a number
54 e.g.
55 delete object pos 20,20,20 to 40,40,40
56 delete object pos 20,20 to 40,40
57 delete object pos ,20,20 to ,40,40
58 delete object pos ,,30 to ,,~
59 delete object pos ,,-~ to ,,30";
60
61 public const string MinRawConsoleVectorValue = "-~";
62 public const string MaxRawConsoleVectorValue = "~";
63
64 public const string VectorSeparator = ",";
65 public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray();
66
67 /// <summary>
68 /// Check if the given file path exists.
69 /// </summary>
70 /// <remarks>If not, warning is printed to the given console.</remarks>
71 /// <returns>true if the file does not exist, false otherwise.</returns>
72 /// <param name='console'></param>
73 /// <param name='path'></param>
74 public static bool CheckFileDoesNotExist(ICommandConsole console, string path)
75 {
76 if (File.Exists(path))
77 {
78 console.OutputFormat("File {0} already exists. Please move or remove it.", path);
79 return false;
80 }
81
82 return true;
83 }
84
85 /// <summary>
86 /// Try to parse a console UUID from the console.
87 /// </summary>
88 /// <remarks>
89 /// Will complain to the console if parsing fails.
90 /// </remarks>
91 /// <returns></returns>
92 /// <param name='console'>If null then no complaint is printed.</param>
93 /// <param name='rawUuid'></param>
94 /// <param name='uuid'></param>
95 public static bool TryParseConsoleUuid(ICommandConsole console, string rawUuid, out UUID uuid)
96 {
97 if (!UUID.TryParse(rawUuid, out uuid))
98 {
99 if (console != null)
100 console.OutputFormat("{0} is not a valid uuid", rawUuid);
101
102 return false;
103 }
104
105 return true;
106 }
107
108 public static bool TryParseConsoleLocalId(ICommandConsole console, string rawLocalId, out uint localId)
109 {
110 if (!uint.TryParse(rawLocalId, out localId))
111 {
112 if (console != null)
113 console.OutputFormat("{0} is not a valid local id", localId);
114
115 return false;
116 }
117
118 if (localId == 0)
119 {
120 if (console != null)
121 console.OutputFormat("{0} is not a valid local id - it must be greater than 0", localId);
122
123 return false;
124 }
125
126 return true;
127 }
128
129 /// <summary>
130 /// Tries to parse the input as either a UUID or a local ID.
131 /// </summary>
132 /// <returns>true if parsing succeeded, false otherwise.</returns>
133 /// <param name='console'></param>
134 /// <param name='rawId'></param>
135 /// <param name='uuid'></param>
136 /// <param name='localId'>
137 /// Will be set to ConsoleUtil.LocalIdNotFound if parsing result was a UUID or no parse succeeded.
138 /// </param>
139 public static bool TryParseConsoleId(ICommandConsole console, string rawId, out UUID uuid, out uint localId)
140 {
141 if (TryParseConsoleUuid(null, rawId, out uuid))
142 {
143 localId = LocalIdNotFound;
144 return true;
145 }
146
147 if (TryParseConsoleLocalId(null, rawId, out localId))
148 {
149 return true;
150 }
151
152 if (console != null)
153 console.OutputFormat("{0} is not a valid UUID or local id", rawId);
154
155 return false;
156 }
157
158 /// <summary>
159 /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
160 /// </summary>
161 /// <param name='rawConsoleVector'>/param>
162 /// <param name='vector'></param>
163 /// <returns></returns>
164 public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
165 {
166 return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector);
167 }
168
169 /// <summary>
170 /// Convert a maximum vector input from the console to an OpenMetaverse.Vector3
171 /// </summary>
172 /// <param name='rawConsoleVector'>/param>
173 /// <param name='vector'></param>
174 /// <returns></returns>
175 public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector)
176 {
177 return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector);
178 }
179
180 /// <summary>
181 /// Convert a vector input from the console to an OpenMetaverse.Vector3
182 /// </summary>
183 /// <param name='rawConsoleVector'>
184 /// A string in the form <x>,<y>,<z> where there is no space between values.
185 /// Any component can be missing (e.g. ,,40). blankComponentFunc is invoked to replace the blank with a suitable value
186 /// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40,30 or 40)
187 /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
188 /// Other than that, component values must be numeric.
189 /// </param>
190 /// <param name='blankComponentFunc'></param>
191 /// <param name='vector'></param>
192 /// <returns></returns>
193 public static bool TryParseConsoleVector(
194 string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector)
195 {
196 List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
197
198 if (components.Count < 1 || components.Count > 3)
199 {
200 vector = Vector3.Zero;
201 return false;
202 }
203
204 for (int i = components.Count; i < 3; i++)
205 components.Add("");
206
207 List<string> semiDigestedComponents
208 = components.ConvertAll<string>(
209 c =>
210 {
211 if (c == "")
212 return blankComponentFunc.Invoke(c);
213 else if (c == MaxRawConsoleVectorValue)
214 return float.MaxValue.ToString();
215 else if (c == MinRawConsoleVectorValue)
216 return float.MinValue.ToString();
217 else
218 return c;
219 });
220
221 string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
222
223 // m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
224
225 return Vector3.TryParse(semiDigestedConsoleVector, out vector);
226 }
227 }
228} \ No newline at end of file
diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs
index 1b1aaf2..a2eb5ee 100644
--- a/OpenSim/Framework/Constants.cs
+++ b/OpenSim/Framework/Constants.cs
@@ -31,6 +31,7 @@ namespace OpenSim.Framework
31 public class Constants 31 public class Constants
32 { 32 {
33 public const uint RegionSize = 256; 33 public const uint RegionSize = 256;
34 public const uint RegionHeight = 4096;
34 public const byte TerrainPatchSize = 16; 35 public const byte TerrainPatchSize = 16;
35 public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f"; 36 public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f";
36 37
diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs
index 9020761..e03750b 100644
--- a/OpenSim/Framework/EstateSettings.cs
+++ b/OpenSim/Framework/EstateSettings.cs
@@ -419,11 +419,11 @@ namespace OpenSim.Framework
419 419
420 public void SetFromFlags(ulong regionFlags) 420 public void SetFromFlags(ulong regionFlags)
421 { 421 {
422 ResetHomeOnTeleport = ((regionFlags & (ulong)RegionFlags.ResetHomeOnTeleport) == (ulong)RegionFlags.ResetHomeOnTeleport); 422 ResetHomeOnTeleport = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.ResetHomeOnTeleport) == (ulong)OpenMetaverse.RegionFlags.ResetHomeOnTeleport);
423 BlockDwell = ((regionFlags & (ulong)RegionFlags.BlockDwell) == (ulong)RegionFlags.BlockDwell); 423 BlockDwell = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.BlockDwell) == (ulong)OpenMetaverse.RegionFlags.BlockDwell);
424 AllowLandmark = ((regionFlags & (ulong)RegionFlags.AllowLandmark) == (ulong)RegionFlags.AllowLandmark); 424 AllowLandmark = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.AllowLandmark) == (ulong)OpenMetaverse.RegionFlags.AllowLandmark);
425 AllowParcelChanges = ((regionFlags & (ulong)RegionFlags.AllowParcelChanges) == (ulong)RegionFlags.AllowParcelChanges); 425 AllowParcelChanges = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.AllowParcelChanges) == (ulong)OpenMetaverse.RegionFlags.AllowParcelChanges);
426 AllowSetHome = ((regionFlags & (ulong)RegionFlags.AllowSetHome) == (ulong)RegionFlags.AllowSetHome); 426 AllowSetHome = ((regionFlags & (ulong)OpenMetaverse.RegionFlags.AllowSetHome) == (ulong)OpenMetaverse.RegionFlags.AllowSetHome);
427 } 427 }
428 428
429 public bool GroupAccess(UUID groupID) 429 public bool GroupAccess(UUID groupID)
diff --git a/OpenSim/Framework/GridInstantMessage.cs b/OpenSim/Framework/GridInstantMessage.cs
index a6bf6e3..6ae0488 100644
--- a/OpenSim/Framework/GridInstantMessage.cs
+++ b/OpenSim/Framework/GridInstantMessage.cs
@@ -44,7 +44,6 @@ namespace OpenSim.Framework
44 public Vector3 Position; 44 public Vector3 Position;
45 public byte[] binaryBucket; 45 public byte[] binaryBucket;
46 46
47
48 public uint ParentEstateID; 47 public uint ParentEstateID;
49 public Guid RegionID; 48 public Guid RegionID;
50 public uint timestamp; 49 public uint timestamp;
@@ -58,7 +57,7 @@ namespace OpenSim.Framework
58 string _fromAgentName, UUID _toAgentID, 57 string _fromAgentName, UUID _toAgentID,
59 byte _dialog, bool _fromGroup, string _message, 58 byte _dialog, bool _fromGroup, string _message,
60 UUID _imSessionID, bool _offline, Vector3 _position, 59 UUID _imSessionID, bool _offline, Vector3 _position,
61 byte[] _binaryBucket) 60 byte[] _binaryBucket, bool addTimestamp)
62 { 61 {
63 fromAgentID = _fromAgentID.Guid; 62 fromAgentID = _fromAgentID.Guid;
64 fromAgentName = _fromAgentName; 63 fromAgentName = _fromAgentName;
@@ -79,7 +78,9 @@ namespace OpenSim.Framework
79 ParentEstateID = scene.RegionInfo.EstateSettings.ParentEstateID; 78 ParentEstateID = scene.RegionInfo.EstateSettings.ParentEstateID;
80 RegionID = scene.RegionInfo.RegionSettings.RegionUUID.Guid; 79 RegionID = scene.RegionInfo.RegionSettings.RegionUUID.Guid;
81 } 80 }
82 timestamp = (uint)Util.UnixTimeSinceEpoch(); 81
82 if (addTimestamp)
83 timestamp = (uint)Util.UnixTimeSinceEpoch();
83 } 84 }
84 85
85 public GridInstantMessage(IScene scene, UUID _fromAgentID, 86 public GridInstantMessage(IScene scene, UUID _fromAgentID,
@@ -87,7 +88,7 @@ namespace OpenSim.Framework
87 string _message, bool _offline, 88 string _message, bool _offline,
88 Vector3 _position) : this(scene, _fromAgentID, _fromAgentName, 89 Vector3 _position) : this(scene, _fromAgentID, _fromAgentName,
89 _toAgentID, _dialog, false, _message, 90 _toAgentID, _dialog, false, _message,
90 _fromAgentID ^ _toAgentID, _offline, _position, new byte[0]) 91 _fromAgentID ^ _toAgentID, _offline, _position, new byte[0], true)
91 { 92 {
92 } 93 }
93 } 94 }
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 5909ce1..a1df637 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -815,8 +815,23 @@ namespace OpenSim.Framework
815 event Action<IClientAPI> OnRegionHandShakeReply; 815 event Action<IClientAPI> OnRegionHandShakeReply;
816 event GenericCall1 OnRequestWearables; 816 event GenericCall1 OnRequestWearables;
817 event Action<IClientAPI, bool> OnCompleteMovementToRegion; 817 event Action<IClientAPI, bool> OnCompleteMovementToRegion;
818
819 /// <summary>
820 /// Called when an AgentUpdate message is received and before OnAgentUpdate.
821 /// </summary>
822 /// <remarks>
823 /// Listeners must not retain a reference to AgentUpdateArgs since this object may be reused for subsequent AgentUpdates.
824 /// </remarks>
818 event UpdateAgent OnPreAgentUpdate; 825 event UpdateAgent OnPreAgentUpdate;
826
827 /// <summary>
828 /// Called when an AgentUpdate message is received and after OnPreAgentUpdate.
829 /// </summary>
830 /// <remarks>
831 /// Listeners must not retain a reference to AgentUpdateArgs since this object may be reused for subsequent AgentUpdates.
832 /// </remarks>
819 event UpdateAgent OnAgentUpdate; 833 event UpdateAgent OnAgentUpdate;
834
820 event AgentRequestSit OnAgentRequestSit; 835 event AgentRequestSit OnAgentRequestSit;
821 event AgentSit OnAgentSit; 836 event AgentSit OnAgentSit;
822 event AvatarPickerRequest OnAvatarPickerRequest; 837 event AvatarPickerRequest OnAvatarPickerRequest;
@@ -1046,8 +1061,21 @@ namespace OpenSim.Framework
1046 1061
1047 void InPacket(object NewPack); 1062 void InPacket(object NewPack);
1048 void ProcessInPacket(Packet NewPack); 1063 void ProcessInPacket(Packet NewPack);
1064
1065 /// <summary>
1066 /// Close this client
1067 /// </summary>
1049 void Close(); 1068 void Close();
1050 void Close(bool sendStop); 1069
1070 /// <summary>
1071 /// Close this client
1072 /// </summary>
1073 /// <param name='force'>
1074 /// If true, attempts the close without checking active status. You do not want to try this except as a last
1075 /// ditch attempt where Active == false but the ScenePresence still exists.
1076 /// </param>
1077 void Close(bool sendStop, bool force);
1078
1051 void Kick(string message); 1079 void Kick(string message);
1052 1080
1053 /// <summary> 1081 /// <summary>
@@ -1084,8 +1112,20 @@ namespace OpenSim.Framework
1084 void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); 1112 void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
1085 void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); 1113 void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
1086 1114
1087 void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, 1115 /// <summary>
1088 byte audible); 1116 /// Send chat to the viewer.
1117 /// </summary>
1118 /// <param name='message'></param>
1119 /// <param name='type'></param>
1120 /// <param name='fromPos'></param>
1121 /// <param name='fromName'></param>
1122 /// <param name='fromAgentID'></param>
1123 /// <param name='ownerID'></param>
1124 /// <param name='source'></param>
1125 /// <param name='audible'></param>
1126 void SendChatMessage(
1127 string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source,
1128 byte audible);
1089 1129
1090 void SendInstantMessage(GridInstantMessage im); 1130 void SendInstantMessage(GridInstantMessage im);
1091 1131
diff --git a/OpenSim/Framework/InventoryFolderBase.cs b/OpenSim/Framework/InventoryFolderBase.cs
index a12183c..b3457a6 100644
--- a/OpenSim/Framework/InventoryFolderBase.cs
+++ b/OpenSim/Framework/InventoryFolderBase.cs
@@ -73,33 +73,27 @@ namespace OpenSim.Framework
73 { 73 {
74 } 74 }
75 75
76 public InventoryFolderBase(UUID id) 76 public InventoryFolderBase(UUID id) : this()
77 { 77 {
78 ID = id; 78 ID = id;
79 } 79 }
80 80
81 public InventoryFolderBase(UUID id, UUID owner) 81 public InventoryFolderBase(UUID id, UUID owner) : this(id)
82 { 82 {
83 ID = id;
84 Owner = owner; 83 Owner = owner;
85 } 84 }
86 85
87 public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) 86 public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner)
88 { 87 {
89 ID = id;
90 Name = name; 88 Name = name;
91 Owner = owner;
92 ParentID = parent; 89 ParentID = parent;
93 } 90 }
94 91
95 public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version) 92 public InventoryFolderBase(
93 UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent)
96 { 94 {
97 ID = id;
98 Name = name;
99 Owner = owner;
100 Type = type; 95 Type = type;
101 ParentID = parent;
102 Version = version; 96 Version = version;
103 } 97 }
104 } 98 }
105} 99} \ No newline at end of file
diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs
index dcaa46d..4dffd3f 100644
--- a/OpenSim/Framework/LandData.cs
+++ b/OpenSim/Framework/LandData.cs
@@ -49,8 +49,8 @@ namespace OpenSim.Framework
49 // use only one serializer to give the runtime a chance to 49 // use only one serializer to give the runtime a chance to
50 // optimize it (it won't do that if you use a new instance 50 // optimize it (it won't do that if you use a new instance
51 // every time) 51 // every time)
52 private static XmlSerializer serializer = new XmlSerializer(typeof (LandData)); 52 private static XmlSerializer serializer = new XmlSerializer(typeof(LandData));
53 53
54 private Vector3 _AABBMax = new Vector3(); 54 private Vector3 _AABBMax = new Vector3();
55 private Vector3 _AABBMin = new Vector3(); 55 private Vector3 _AABBMin = new Vector3();
56 private int _area = 0; 56 private int _area = 0;
@@ -65,11 +65,11 @@ namespace OpenSim.Framework
65 private byte[] _bitmap = new byte[512]; 65 private byte[] _bitmap = new byte[512];
66 private string _description = String.Empty; 66 private string _description = String.Empty;
67 67
68 private uint _flags = (uint) ParcelFlags.AllowFly | (uint) ParcelFlags.AllowLandmark | 68 private uint _flags = (uint)ParcelFlags.AllowFly | (uint)ParcelFlags.AllowLandmark |
69 (uint) ParcelFlags.AllowAPrimitiveEntry | 69 (uint)ParcelFlags.AllowAPrimitiveEntry |
70 (uint) ParcelFlags.AllowDeedToGroup | 70 (uint)ParcelFlags.AllowDeedToGroup |
71 (uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts | 71 (uint)ParcelFlags.CreateObjects | (uint)ParcelFlags.AllowOtherScripts |
72 (uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat; 72 (uint)ParcelFlags.AllowVoiceChat;
73 73
74 private byte _landingType = 0; 74 private byte _landingType = 0;
75 private string _name = "Your Parcel"; 75 private string _name = "Your Parcel";
@@ -97,16 +97,36 @@ namespace OpenSim.Framework
97 private bool _mediaLoop = false; 97 private bool _mediaLoop = false;
98 private bool _obscureMusic = false; 98 private bool _obscureMusic = false;
99 private bool _obscureMedia = false; 99 private bool _obscureMedia = false;
100 private float _dwell = 0;
101
102 /// <summary>
103 /// Traffic count of parcel
104 /// </summary>
105 [XmlIgnore]
106 public float Dwell
107 {
108 get
109 {
110 return _dwell;
111 }
112 set
113 {
114 _dwell = value;
115 }
116 }
100 117
101 /// <summary> 118 /// <summary>
102 /// Whether to obscure parcel media URL 119 /// Whether to obscure parcel media URL
103 /// </summary> 120 /// </summary>
104 [XmlIgnore] 121 [XmlIgnore]
105 public bool ObscureMedia { 122 public bool ObscureMedia
106 get { 123 {
124 get
125 {
107 return _obscureMedia; 126 return _obscureMedia;
108 } 127 }
109 set { 128 set
129 {
110 _obscureMedia = value; 130 _obscureMedia = value;
111 } 131 }
112 } 132 }
@@ -115,11 +135,14 @@ namespace OpenSim.Framework
115 /// Whether to obscure parcel music URL 135 /// Whether to obscure parcel music URL
116 /// </summary> 136 /// </summary>
117 [XmlIgnore] 137 [XmlIgnore]
118 public bool ObscureMusic { 138 public bool ObscureMusic
119 get { 139 {
140 get
141 {
120 return _obscureMusic; 142 return _obscureMusic;
121 } 143 }
122 set { 144 set
145 {
123 _obscureMusic = value; 146 _obscureMusic = value;
124 } 147 }
125 } 148 }
@@ -128,11 +151,14 @@ namespace OpenSim.Framework
128 /// Whether to loop parcel media 151 /// Whether to loop parcel media
129 /// </summary> 152 /// </summary>
130 [XmlIgnore] 153 [XmlIgnore]
131 public bool MediaLoop { 154 public bool MediaLoop
132 get { 155 {
156 get
157 {
133 return _mediaLoop; 158 return _mediaLoop;
134 } 159 }
135 set { 160 set
161 {
136 _mediaLoop = value; 162 _mediaLoop = value;
137 } 163 }
138 } 164 }
@@ -141,11 +167,14 @@ namespace OpenSim.Framework
141 /// Height of parcel media render 167 /// Height of parcel media render
142 /// </summary> 168 /// </summary>
143 [XmlIgnore] 169 [XmlIgnore]
144 public int MediaHeight { 170 public int MediaHeight
145 get { 171 {
172 get
173 {
146 return _mediaHeight; 174 return _mediaHeight;
147 } 175 }
148 set { 176 set
177 {
149 _mediaHeight = value; 178 _mediaHeight = value;
150 } 179 }
151 } 180 }
@@ -154,11 +183,14 @@ namespace OpenSim.Framework
154 /// Width of parcel media render 183 /// Width of parcel media render
155 /// </summary> 184 /// </summary>
156 [XmlIgnore] 185 [XmlIgnore]
157 public int MediaWidth { 186 public int MediaWidth
158 get { 187 {
188 get
189 {
159 return _mediaWidth; 190 return _mediaWidth;
160 } 191 }
161 set { 192 set
193 {
162 _mediaWidth = value; 194 _mediaWidth = value;
163 } 195 }
164 } 196 }
@@ -167,11 +199,14 @@ namespace OpenSim.Framework
167 /// Upper corner of the AABB for the parcel 199 /// Upper corner of the AABB for the parcel
168 /// </summary> 200 /// </summary>
169 [XmlIgnore] 201 [XmlIgnore]
170 public Vector3 AABBMax { 202 public Vector3 AABBMax
171 get { 203 {
204 get
205 {
172 return _AABBMax; 206 return _AABBMax;
173 } 207 }
174 set { 208 set
209 {
175 _AABBMax = value; 210 _AABBMax = value;
176 } 211 }
177 } 212 }
@@ -179,11 +214,14 @@ namespace OpenSim.Framework
179 /// Lower corner of the AABB for the parcel 214 /// Lower corner of the AABB for the parcel
180 /// </summary> 215 /// </summary>
181 [XmlIgnore] 216 [XmlIgnore]
182 public Vector3 AABBMin { 217 public Vector3 AABBMin
183 get { 218 {
219 get
220 {
184 return _AABBMin; 221 return _AABBMin;
185 } 222 }
186 set { 223 set
224 {
187 _AABBMin = value; 225 _AABBMin = value;
188 } 226 }
189 } 227 }
@@ -191,11 +229,14 @@ namespace OpenSim.Framework
191 /// <summary> 229 /// <summary>
192 /// Area in meters^2 the parcel contains 230 /// Area in meters^2 the parcel contains
193 /// </summary> 231 /// </summary>
194 public int Area { 232 public int Area
195 get { 233 {
234 get
235 {
196 return _area; 236 return _area;
197 } 237 }
198 set { 238 set
239 {
199 _area = value; 240 _area = value;
200 } 241 }
201 } 242 }
@@ -203,11 +244,14 @@ namespace OpenSim.Framework
203 /// <summary> 244 /// <summary>
204 /// ID of auction (3rd Party Integration) when parcel is being auctioned 245 /// ID of auction (3rd Party Integration) when parcel is being auctioned
205 /// </summary> 246 /// </summary>
206 public uint AuctionID { 247 public uint AuctionID
207 get { 248 {
249 get
250 {
208 return _auctionID; 251 return _auctionID;
209 } 252 }
210 set { 253 set
254 {
211 _auctionID = value; 255 _auctionID = value;
212 } 256 }
213 } 257 }
@@ -215,11 +259,14 @@ namespace OpenSim.Framework
215 /// <summary> 259 /// <summary>
216 /// UUID of authorized buyer of parcel. This is UUID.Zero if anyone can buy it. 260 /// UUID of authorized buyer of parcel. This is UUID.Zero if anyone can buy it.
217 /// </summary> 261 /// </summary>
218 public UUID AuthBuyerID { 262 public UUID AuthBuyerID
219 get { 263 {
264 get
265 {
220 return _authBuyerID; 266 return _authBuyerID;
221 } 267 }
222 set { 268 set
269 {
223 _authBuyerID = value; 270 _authBuyerID = value;
224 } 271 }
225 } 272 }
@@ -227,11 +274,14 @@ namespace OpenSim.Framework
227 /// <summary> 274 /// <summary>
228 /// Category of parcel. Used for classifying the parcel in classified listings 275 /// Category of parcel. Used for classifying the parcel in classified listings
229 /// </summary> 276 /// </summary>
230 public ParcelCategory Category { 277 public ParcelCategory Category
231 get { 278 {
279 get
280 {
232 return _category; 281 return _category;
233 } 282 }
234 set { 283 set
284 {
235 _category = value; 285 _category = value;
236 } 286 }
237 } 287 }
@@ -239,11 +289,14 @@ namespace OpenSim.Framework
239 /// <summary> 289 /// <summary>
240 /// Date that the current owner purchased or claimed the parcel 290 /// Date that the current owner purchased or claimed the parcel
241 /// </summary> 291 /// </summary>
242 public int ClaimDate { 292 public int ClaimDate
243 get { 293 {
294 get
295 {
244 return _claimDate; 296 return _claimDate;
245 } 297 }
246 set { 298 set
299 {
247 _claimDate = value; 300 _claimDate = value;
248 } 301 }
249 } 302 }
@@ -251,11 +304,14 @@ namespace OpenSim.Framework
251 /// <summary> 304 /// <summary>
252 /// The last price that the parcel was sold at 305 /// The last price that the parcel was sold at
253 /// </summary> 306 /// </summary>
254 public int ClaimPrice { 307 public int ClaimPrice
255 get { 308 {
309 get
310 {
256 return _claimPrice; 311 return _claimPrice;
257 } 312 }
258 set { 313 set
314 {
259 _claimPrice = value; 315 _claimPrice = value;
260 } 316 }
261 } 317 }
@@ -263,11 +319,14 @@ namespace OpenSim.Framework
263 /// <summary> 319 /// <summary>
264 /// Global ID for the parcel. (3rd Party Integration) 320 /// Global ID for the parcel. (3rd Party Integration)
265 /// </summary> 321 /// </summary>
266 public UUID GlobalID { 322 public UUID GlobalID
267 get { 323 {
324 get
325 {
268 return _globalID; 326 return _globalID;
269 } 327 }
270 set { 328 set
329 {
271 _globalID = value; 330 _globalID = value;
272 } 331 }
273 } 332 }
@@ -275,11 +334,14 @@ namespace OpenSim.Framework
275 /// <summary> 334 /// <summary>
276 /// Unique ID of the Group that owns 335 /// Unique ID of the Group that owns
277 /// </summary> 336 /// </summary>
278 public UUID GroupID { 337 public UUID GroupID
279 get { 338 {
339 get
340 {
280 return _groupID; 341 return _groupID;
281 } 342 }
282 set { 343 set
344 {
283 _groupID = value; 345 _groupID = value;
284 } 346 }
285 } 347 }
@@ -287,11 +349,14 @@ namespace OpenSim.Framework
287 /// <summary> 349 /// <summary>
288 /// Returns true if the Land Parcel is owned by a group 350 /// Returns true if the Land Parcel is owned by a group
289 /// </summary> 351 /// </summary>
290 public bool IsGroupOwned { 352 public bool IsGroupOwned
291 get { 353 {
354 get
355 {
292 return _isGroupOwned; 356 return _isGroupOwned;
293 } 357 }
294 set { 358 set
359 {
295 _isGroupOwned = value; 360 _isGroupOwned = value;
296 } 361 }
297 } 362 }
@@ -299,11 +364,14 @@ namespace OpenSim.Framework
299 /// <summary> 364 /// <summary>
300 /// jp2 data for the image representative of the parcel in the parcel dialog 365 /// jp2 data for the image representative of the parcel in the parcel dialog
301 /// </summary> 366 /// </summary>
302 public byte[] Bitmap { 367 public byte[] Bitmap
303 get { 368 {
369 get
370 {
304 return _bitmap; 371 return _bitmap;
305 } 372 }
306 set { 373 set
374 {
307 _bitmap = value; 375 _bitmap = value;
308 } 376 }
309 } 377 }
@@ -311,11 +379,14 @@ namespace OpenSim.Framework
311 /// <summary> 379 /// <summary>
312 /// Parcel Description 380 /// Parcel Description
313 /// </summary> 381 /// </summary>
314 public string Description { 382 public string Description
315 get { 383 {
384 get
385 {
316 return _description; 386 return _description;
317 } 387 }
318 set { 388 set
389 {
319 _description = value; 390 _description = value;
320 } 391 }
321 } 392 }
@@ -323,11 +394,14 @@ namespace OpenSim.Framework
323 /// <summary> 394 /// <summary>
324 /// Parcel settings. Access flags, Fly, NoPush, Voice, Scripts allowed, etc. ParcelFlags 395 /// Parcel settings. Access flags, Fly, NoPush, Voice, Scripts allowed, etc. ParcelFlags
325 /// </summary> 396 /// </summary>
326 public uint Flags { 397 public uint Flags
327 get { 398 {
399 get
400 {
328 return _flags; 401 return _flags;
329 } 402 }
330 set { 403 set
404 {
331 _flags = value; 405 _flags = value;
332 } 406 }
333 } 407 }
@@ -336,11 +410,14 @@ namespace OpenSim.Framework
336 /// Determines if people are able to teleport where they please on the parcel or if they 410 /// Determines if people are able to teleport where they please on the parcel or if they
337 /// get constrainted to a specific point on teleport within the parcel 411 /// get constrainted to a specific point on teleport within the parcel
338 /// </summary> 412 /// </summary>
339 public byte LandingType { 413 public byte LandingType
340 get { 414 {
415 get
416 {
341 return _landingType; 417 return _landingType;
342 } 418 }
343 set { 419 set
420 {
344 _landingType = value; 421 _landingType = value;
345 } 422 }
346 } 423 }
@@ -348,11 +425,14 @@ namespace OpenSim.Framework
348 /// <summary> 425 /// <summary>
349 /// Parcel Name 426 /// Parcel Name
350 /// </summary> 427 /// </summary>
351 public string Name { 428 public string Name
352 get { 429 {
430 get
431 {
353 return _name; 432 return _name;
354 } 433 }
355 set { 434 set
435 {
356 _name = value; 436 _name = value;
357 } 437 }
358 } 438 }
@@ -360,11 +440,14 @@ namespace OpenSim.Framework
360 /// <summary> 440 /// <summary>
361 /// Status of Parcel, Leased, Abandoned, For Sale 441 /// Status of Parcel, Leased, Abandoned, For Sale
362 /// </summary> 442 /// </summary>
363 public ParcelStatus Status { 443 public ParcelStatus Status
364 get { 444 {
445 get
446 {
365 return _status; 447 return _status;
366 } 448 }
367 set { 449 set
450 {
368 _status = value; 451 _status = value;
369 } 452 }
370 } 453 }
@@ -372,11 +455,14 @@ namespace OpenSim.Framework
372 /// <summary> 455 /// <summary>
373 /// Internal ID of the parcel. Sometimes the client will try to use this value 456 /// Internal ID of the parcel. Sometimes the client will try to use this value
374 /// </summary> 457 /// </summary>
375 public int LocalID { 458 public int LocalID
376 get { 459 {
460 get
461 {
377 return _localID; 462 return _localID;
378 } 463 }
379 set { 464 set
465 {
380 _localID = value; 466 _localID = value;
381 } 467 }
382 } 468 }
@@ -384,11 +470,14 @@ namespace OpenSim.Framework
384 /// <summary> 470 /// <summary>
385 /// Determines if we scale the media based on the surface it's on 471 /// Determines if we scale the media based on the surface it's on
386 /// </summary> 472 /// </summary>
387 public byte MediaAutoScale { 473 public byte MediaAutoScale
388 get { 474 {
475 get
476 {
389 return _mediaAutoScale; 477 return _mediaAutoScale;
390 } 478 }
391 set { 479 set
480 {
392 _mediaAutoScale = value; 481 _mediaAutoScale = value;
393 } 482 }
394 } 483 }
@@ -396,11 +485,14 @@ namespace OpenSim.Framework
396 /// <summary> 485 /// <summary>
397 /// Texture Guid to replace with the output of the media stream 486 /// Texture Guid to replace with the output of the media stream
398 /// </summary> 487 /// </summary>
399 public UUID MediaID { 488 public UUID MediaID
400 get { 489 {
490 get
491 {
401 return _mediaID; 492 return _mediaID;
402 } 493 }
403 set { 494 set
495 {
404 _mediaID = value; 496 _mediaID = value;
405 } 497 }
406 } 498 }
@@ -408,11 +500,14 @@ namespace OpenSim.Framework
408 /// <summary> 500 /// <summary>
409 /// URL to the media file to display 501 /// URL to the media file to display
410 /// </summary> 502 /// </summary>
411 public string MediaURL { 503 public string MediaURL
412 get { 504 {
505 get
506 {
413 return _mediaURL; 507 return _mediaURL;
414 } 508 }
415 set { 509 set
510 {
416 _mediaURL = value; 511 _mediaURL = value;
417 } 512 }
418 } 513 }
@@ -432,11 +527,14 @@ namespace OpenSim.Framework
432 /// <summary> 527 /// <summary>
433 /// URL to the shoutcast music stream to play on the parcel 528 /// URL to the shoutcast music stream to play on the parcel
434 /// </summary> 529 /// </summary>
435 public string MusicURL { 530 public string MusicURL
436 get { 531 {
532 get
533 {
437 return _musicURL; 534 return _musicURL;
438 } 535 }
439 set { 536 set
537 {
440 _musicURL = value; 538 _musicURL = value;
441 } 539 }
442 } 540 }
@@ -445,11 +543,14 @@ namespace OpenSim.Framework
445 /// Owner Avatar or Group of the parcel. Naturally, all land masses must be 543 /// Owner Avatar or Group of the parcel. Naturally, all land masses must be
446 /// owned by someone 544 /// owned by someone
447 /// </summary> 545 /// </summary>
448 public UUID OwnerID { 546 public UUID OwnerID
449 get { 547 {
548 get
549 {
450 return _ownerID; 550 return _ownerID;
451 } 551 }
452 set { 552 set
553 {
453 _ownerID = value; 554 _ownerID = value;
454 } 555 }
455 } 556 }
@@ -457,11 +558,14 @@ namespace OpenSim.Framework
457 /// <summary> 558 /// <summary>
458 /// List of access data for the parcel. User data, some bitflags, and a time 559 /// List of access data for the parcel. User data, some bitflags, and a time
459 /// </summary> 560 /// </summary>
460 public List<LandAccessEntry> ParcelAccessList { 561 public List<LandAccessEntry> ParcelAccessList
461 get { 562 {
563 get
564 {
462 return _parcelAccessList; 565 return _parcelAccessList;
463 } 566 }
464 set { 567 set
568 {
465 _parcelAccessList = value; 569 _parcelAccessList = value;
466 } 570 }
467 } 571 }
@@ -469,11 +573,14 @@ namespace OpenSim.Framework
469 /// <summary> 573 /// <summary>
470 /// How long in hours a Pass to the parcel is given 574 /// How long in hours a Pass to the parcel is given
471 /// </summary> 575 /// </summary>
472 public float PassHours { 576 public float PassHours
473 get { 577 {
578 get
579 {
474 return _passHours; 580 return _passHours;
475 } 581 }
476 set { 582 set
583 {
477 _passHours = value; 584 _passHours = value;
478 } 585 }
479 } 586 }
@@ -481,11 +588,14 @@ namespace OpenSim.Framework
481 /// <summary> 588 /// <summary>
482 /// Price to purchase a Pass to a restricted parcel 589 /// Price to purchase a Pass to a restricted parcel
483 /// </summary> 590 /// </summary>
484 public int PassPrice { 591 public int PassPrice
485 get { 592 {
593 get
594 {
486 return _passPrice; 595 return _passPrice;
487 } 596 }
488 set { 597 set
598 {
489 _passPrice = value; 599 _passPrice = value;
490 } 600 }
491 } 601 }
@@ -493,11 +603,14 @@ namespace OpenSim.Framework
493 /// <summary> 603 /// <summary>
494 /// When the parcel is being sold, this is the price to purchase the parcel 604 /// When the parcel is being sold, this is the price to purchase the parcel
495 /// </summary> 605 /// </summary>
496 public int SalePrice { 606 public int SalePrice
497 get { 607 {
608 get
609 {
498 return _salePrice; 610 return _salePrice;
499 } 611 }
500 set { 612 set
613 {
501 _salePrice = value; 614 _salePrice = value;
502 } 615 }
503 } 616 }
@@ -506,11 +619,14 @@ namespace OpenSim.Framework
506 /// Number of meters^2 in the Simulator 619 /// Number of meters^2 in the Simulator
507 /// </summary> 620 /// </summary>
508 [XmlIgnore] 621 [XmlIgnore]
509 public int SimwideArea { 622 public int SimwideArea
510 get { 623 {
624 get
625 {
511 return _simwideArea; 626 return _simwideArea;
512 } 627 }
513 set { 628 set
629 {
514 _simwideArea = value; 630 _simwideArea = value;
515 } 631 }
516 } 632 }
@@ -519,11 +635,14 @@ namespace OpenSim.Framework
519 /// Number of SceneObjectPart in the Simulator 635 /// Number of SceneObjectPart in the Simulator
520 /// </summary> 636 /// </summary>
521 [XmlIgnore] 637 [XmlIgnore]
522 public int SimwidePrims { 638 public int SimwidePrims
523 get { 639 {
640 get
641 {
524 return _simwidePrims; 642 return _simwidePrims;
525 } 643 }
526 set { 644 set
645 {
527 _simwidePrims = value; 646 _simwidePrims = value;
528 } 647 }
529 } 648 }
@@ -531,11 +650,14 @@ namespace OpenSim.Framework
531 /// <summary> 650 /// <summary>
532 /// ID of the snapshot used in the client parcel dialog of the parcel 651 /// ID of the snapshot used in the client parcel dialog of the parcel
533 /// </summary> 652 /// </summary>
534 public UUID SnapshotID { 653 public UUID SnapshotID
535 get { 654 {
655 get
656 {
536 return _snapshotID; 657 return _snapshotID;
537 } 658 }
538 set { 659 set
660 {
539 _snapshotID = value; 661 _snapshotID = value;
540 } 662 }
541 } 663 }
@@ -544,11 +666,14 @@ namespace OpenSim.Framework
544 /// When teleporting is restricted to a certain point, this is the location 666 /// When teleporting is restricted to a certain point, this is the location
545 /// that the user will be redirected to 667 /// that the user will be redirected to
546 /// </summary> 668 /// </summary>
547 public Vector3 UserLocation { 669 public Vector3 UserLocation
548 get { 670 {
671 get
672 {
549 return _userLocation; 673 return _userLocation;
550 } 674 }
551 set { 675 set
676 {
552 _userLocation = value; 677 _userLocation = value;
553 } 678 }
554 } 679 }
@@ -557,11 +682,14 @@ namespace OpenSim.Framework
557 /// When teleporting is restricted to a certain point, this is the rotation 682 /// When teleporting is restricted to a certain point, this is the rotation
558 /// that the user will be positioned 683 /// that the user will be positioned
559 /// </summary> 684 /// </summary>
560 public Vector3 UserLookAt { 685 public Vector3 UserLookAt
561 get { 686 {
687 get
688 {
562 return _userLookAt; 689 return _userLookAt;
563 } 690 }
564 set { 691 set
692 {
565 _userLookAt = value; 693 _userLookAt = value;
566 } 694 }
567 } 695 }
@@ -570,11 +698,14 @@ namespace OpenSim.Framework
570 /// Autoreturn number of minutes to return SceneObjectGroup that are owned by someone who doesn't own 698 /// Autoreturn number of minutes to return SceneObjectGroup that are owned by someone who doesn't own
571 /// the parcel and isn't set to the same 'group' as the parcel. 699 /// the parcel and isn't set to the same 'group' as the parcel.
572 /// </summary> 700 /// </summary>
573 public int OtherCleanTime { 701 public int OtherCleanTime
574 get { 702 {
703 get
704 {
575 return _otherCleanTime; 705 return _otherCleanTime;
576 } 706 }
577 set { 707 set
708 {
578 _otherCleanTime = value; 709 _otherCleanTime = value;
579 } 710 }
580 } 711 }
@@ -582,11 +713,14 @@ namespace OpenSim.Framework
582 /// <summary> 713 /// <summary>
583 /// parcel media description 714 /// parcel media description
584 /// </summary> 715 /// </summary>
585 public string MediaDescription { 716 public string MediaDescription
586 get { 717 {
718 get
719 {
587 return _mediaDescription; 720 return _mediaDescription;
588 } 721 }
589 set { 722 set
723 {
590 _mediaDescription = value; 724 _mediaDescription = value;
591 } 725 }
592 } 726 }
@@ -622,7 +756,7 @@ namespace OpenSim.Framework
622 landData._mediaURL = _mediaURL; 756 landData._mediaURL = _mediaURL;
623 landData._musicURL = _musicURL; 757 landData._musicURL = _musicURL;
624 landData._ownerID = _ownerID; 758 landData._ownerID = _ownerID;
625 landData._bitmap = (byte[]) _bitmap.Clone(); 759 landData._bitmap = (byte[])_bitmap.Clone();
626 landData._description = _description; 760 landData._description = _description;
627 landData._flags = _flags; 761 landData._flags = _flags;
628 landData._name = _name; 762 landData._name = _name;
@@ -643,6 +777,7 @@ namespace OpenSim.Framework
643 landData._obscureMedia = _obscureMedia; 777 landData._obscureMedia = _obscureMedia;
644 landData._simwideArea = _simwideArea; 778 landData._simwideArea = _simwideArea;
645 landData._simwidePrims = _simwidePrims; 779 landData._simwidePrims = _simwidePrims;
780 landData._dwell = _dwell;
646 781
647 landData._parcelAccessList.Clear(); 782 landData._parcelAccessList.Clear();
648 foreach (LandAccessEntry entry in _parcelAccessList) 783 foreach (LandAccessEntry entry in _parcelAccessList)
diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
index 9ee0876..446e3c0 100644
--- a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
@@ -43,27 +43,32 @@ namespace OpenSim.Framework.Monitoring
43 StringBuilder sb = new StringBuilder(Environment.NewLine); 43 StringBuilder sb = new StringBuilder(Environment.NewLine);
44 sb.Append("MEMORY STATISTICS"); 44 sb.Append("MEMORY STATISTICS");
45 sb.Append(Environment.NewLine); 45 sb.Append(Environment.NewLine);
46 sb.Append( 46 sb.AppendFormat(
47 string.Format(
48 "Allocated to OpenSim objects: {0} MB\n", 47 "Allocated to OpenSim objects: {0} MB\n",
49 Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); 48 Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
49
50 sb.AppendFormat(
51 "OpenSim last object memory churn : {0} MB/s\n",
52 Math.Round((MemoryWatchdog.LastMemoryChurn * 1000) / 1024.0 / 1024, 3));
53
54 sb.AppendFormat(
55 "OpenSim average object memory churn : {0} MB/s\n",
56 Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
50 57
51 Process myprocess = Process.GetCurrentProcess(); 58 Process myprocess = Process.GetCurrentProcess();
52 if (!myprocess.HasExited) 59 if (!myprocess.HasExited)
53 { 60 {
54 myprocess.Refresh(); 61 myprocess.Refresh();
55 sb.Append( 62 sb.AppendFormat(
56 string.Format(
57 "Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", 63 "Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
58 Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0), 64 Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0),
59 Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0), 65 Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0),
60 Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0))); 66 Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0));
61 sb.Append( 67 sb.AppendFormat(
62 string.Format(
63 "Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", 68 "Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
64 Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0), 69 Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0),
65 Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0), 70 Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0),
66 Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0))); 71 Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0));
67 } 72 }
68 else 73 else
69 sb.Append("Process reported as Exited \n"); 74 sb.Append("Process reported as Exited \n");
diff --git a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
index a23cf1f..c6010cd 100644
--- a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
+++ b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
@@ -60,7 +60,7 @@ namespace OpenSim.Framework.Monitoring
60 private static bool m_enabled; 60 private static bool m_enabled;
61 61
62 /// <summary> 62 /// <summary>
63 /// Average memory churn in bytes per millisecond. 63 /// Last memory churn in bytes per millisecond.
64 /// </summary> 64 /// </summary>
65 public static double AverageMemoryChurn 65 public static double AverageMemoryChurn
66 { 66 {
@@ -68,6 +68,14 @@ namespace OpenSim.Framework.Monitoring
68 } 68 }
69 69
70 /// <summary> 70 /// <summary>
71 /// Average memory churn in bytes per millisecond.
72 /// </summary>
73 public static double LastMemoryChurn
74 {
75 get { if (m_samples.Count > 0) return m_samples.Last(); else return 0; }
76 }
77
78 /// <summary>
71 /// Maximum number of statistical samples. 79 /// Maximum number of statistical samples.
72 /// </summary> 80 /// </summary>
73 /// <remarks> 81 /// <remarks>
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
index cdd7cc7..aa86202 100644
--- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -355,10 +355,25 @@ Asset service request failures: {3}" + Environment.NewLine,
355 sb.Append(Environment.NewLine); 355 sb.Append(Environment.NewLine);
356 sb.Append( 356 sb.Append(
357 string.Format( 357 string.Format(
358 "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}", 358 "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}\n\n",
359 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime, 359 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
360 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime)); 360 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
361 sb.Append(Environment.NewLine); 361
362 Dictionary<string, Dictionary<string, Stat>> sceneStats;
363
364 if (StatsManager.TryGetStats("scene", out sceneStats))
365 {
366 foreach (KeyValuePair<string, Dictionary<string, Stat>> kvp in sceneStats)
367 {
368 foreach (Stat stat in kvp.Value.Values)
369 {
370 if (stat.Verbosity == StatVerbosity.Info)
371 {
372 sb.AppendFormat("{0} ({1}): {2}{3}\n", stat.Name, stat.Container, stat.Value, stat.UnitName);
373 }
374 }
375 }
376 }
362 377
363 /* 378 /*
364 sb.Append(Environment.NewLine); 379 sb.Append(Environment.NewLine);
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index d78fa6a..4844336 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -25,6 +25,9 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Collections.Generic;
30
28namespace OpenSim.Framework.Monitoring 31namespace OpenSim.Framework.Monitoring
29{ 32{
30 /// <summary> 33 /// <summary>
@@ -32,6 +35,24 @@ namespace OpenSim.Framework.Monitoring
32 /// </summary> 35 /// </summary>
33 public class StatsManager 36 public class StatsManager
34 { 37 {
38 // Subcommand used to list other stats.
39 public const string AllSubCommand = "all";
40
41 // Subcommand used to list other stats.
42 public const string ListSubCommand = "list";
43
44 // All subcommands
45 public static HashSet<string> SubCommands = new HashSet<string> { AllSubCommand, ListSubCommand };
46
47 /// <summary>
48 /// Registered stats categorized by category/container/shortname
49 /// </summary>
50 /// <remarks>
51 /// Do not add or remove directly from this dictionary.
52 /// </remarks>
53 public static Dictionary<string, Dictionary<string, Dictionary<string, Stat>>> RegisteredStats
54 = new Dictionary<string, Dictionary<string, Dictionary<string, Stat>>>();
55
35 private static AssetStatsCollector assetStats; 56 private static AssetStatsCollector assetStats;
36 private static UserStatsCollector userStats; 57 private static UserStatsCollector userStats;
37 private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); 58 private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
@@ -40,6 +61,75 @@ namespace OpenSim.Framework.Monitoring
40 public static UserStatsCollector UserStats { get { return userStats; } } 61 public static UserStatsCollector UserStats { get { return userStats; } }
41 public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } } 62 public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
42 63
64 public static void RegisterConsoleCommands(ICommandConsole console)
65 {
66 console.Commands.AddCommand(
67 "General",
68 false,
69 "show stats",
70 "show stats [list|all|<category>]",
71 "Show statistical information for this server",
72 "If no final argument is specified then legacy statistics information is currently shown.\n"
73 + "If list is specified then statistic categories are shown.\n"
74 + "If all is specified then all registered statistics are shown.\n"
75 + "If a category name is specified then only statistics from that category are shown.\n"
76 + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
77 HandleShowStatsCommand);
78 }
79
80 public static void HandleShowStatsCommand(string module, string[] cmd)
81 {
82 ICommandConsole con = MainConsole.Instance;
83
84 if (cmd.Length > 2)
85 {
86 var categoryName = cmd[2];
87
88 if (categoryName == AllSubCommand)
89 {
90 foreach (var category in RegisteredStats.Values)
91 {
92 OutputCategoryStatsToConsole(con, category);
93 }
94 }
95 else if (categoryName == ListSubCommand)
96 {
97 con.Output("Statistic categories available are:");
98 foreach (string category in RegisteredStats.Keys)
99 con.OutputFormat(" {0}", category);
100 }
101 else
102 {
103 Dictionary<string, Dictionary<string, Stat>> category;
104 if (!RegisteredStats.TryGetValue(categoryName, out category))
105 {
106 con.OutputFormat("No such category as {0}", categoryName);
107 }
108 else
109 {
110 OutputCategoryStatsToConsole(con, category);
111 }
112 }
113 }
114 else
115 {
116 // Legacy
117 con.Output(SimExtraStats.Report());
118 }
119 }
120
121 private static void OutputCategoryStatsToConsole(
122 ICommandConsole con, Dictionary<string, Dictionary<string, Stat>> category)
123 {
124 foreach (var container in category.Values)
125 {
126 foreach (Stat stat in container.Values)
127 {
128 con.Output(stat.ToConsoleString());
129 }
130 }
131 }
132
43 /// <summary> 133 /// <summary>
44 /// Start collecting statistics related to assets. 134 /// Start collecting statistics related to assets.
45 /// Should only be called once. 135 /// Should only be called once.
@@ -61,5 +151,275 @@ namespace OpenSim.Framework.Monitoring
61 151
62 return userStats; 152 return userStats;
63 } 153 }
154
155 /// <summary>
156 /// Registers a statistic.
157 /// </summary>
158 /// <param name='stat'></param>
159 /// <returns></returns>
160 public static bool RegisterStat(Stat stat)
161 {
162 Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
163 Dictionary<string, Stat> container = null, newContainer;
164
165 lock (RegisteredStats)
166 {
167 // Stat name is not unique across category/container/shortname key.
168 // XXX: For now just return false. This is to avoid problems in regression tests where all tests
169 // in a class are run in the same instance of the VM.
170 if (TryGetStat(stat, out category, out container))
171 return false;
172
173 // We take a copy-on-write approach here of replacing dictionaries when keys are added or removed.
174 // This means that we don't need to lock or copy them on iteration, which will be a much more
175 // common operation after startup.
176 if (container != null)
177 newContainer = new Dictionary<string, Stat>(container);
178 else
179 newContainer = new Dictionary<string, Stat>();
180
181 if (category != null)
182 newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
183 else
184 newCategory = new Dictionary<string, Dictionary<string, Stat>>();
185
186 newContainer[stat.ShortName] = stat;
187 newCategory[stat.Container] = newContainer;
188 RegisteredStats[stat.Category] = newCategory;
189 }
190
191 return true;
192 }
193
194 /// <summary>
195 /// Deregister a statistic
196 /// </summary>>
197 /// <param name='stat'></param>
198 /// <returns></returns
199 public static bool DeregisterStat(Stat stat)
200 {
201 Dictionary<string, Dictionary<string, Stat>> category = null, newCategory;
202 Dictionary<string, Stat> container = null, newContainer;
203
204 lock (RegisteredStats)
205 {
206 if (!TryGetStat(stat, out category, out container))
207 return false;
208
209 newContainer = new Dictionary<string, Stat>(container);
210 newContainer.Remove(stat.ShortName);
211
212 newCategory = new Dictionary<string, Dictionary<string, Stat>>(category);
213 newCategory.Remove(stat.Container);
214
215 newCategory[stat.Container] = newContainer;
216 RegisteredStats[stat.Category] = newCategory;
217
218 return true;
219 }
220 }
221
222 public static bool TryGetStats(string category, out Dictionary<string, Dictionary<string, Stat>> stats)
223 {
224 return RegisteredStats.TryGetValue(category, out stats);
225 }
226
227 public static bool TryGetStat(
228 Stat stat,
229 out Dictionary<string, Dictionary<string, Stat>> category,
230 out Dictionary<string, Stat> container)
231 {
232 category = null;
233 container = null;
234
235 lock (RegisteredStats)
236 {
237 if (RegisteredStats.TryGetValue(stat.Category, out category))
238 {
239 if (category.TryGetValue(stat.Container, out container))
240 {
241 if (container.ContainsKey(stat.ShortName))
242 return true;
243 }
244 }
245 }
246
247 return false;
248 }
249 }
250
251 /// <summary>
252 /// Stat type.
253 /// </summary>
254 /// <remarks>
255 /// A push stat is one which is continually updated and so it's value can simply by read.
256 /// A pull stat is one where reading the value triggers a collection method - the stat is not continually updated.
257 /// </remarks>
258 public enum StatType
259 {
260 Push,
261 Pull
262 }
263
264 /// <summary>
265 /// Verbosity of stat.
266 /// </summary>
267 /// <remarks>
268 /// Info will always be displayed.
269 /// </remarks>
270 public enum StatVerbosity
271 {
272 Debug,
273 Info
274 }
275
276 /// <summary>
277 /// Holds individual static details
278 /// </summary>
279 public class Stat
280 {
281 /// <summary>
282 /// Category of this stat (e.g. cache, scene, etc).
283 /// </summary>
284 public string Category { get; private set; }
285
286 /// <summary>
287 /// Containing name for this stat.
288 /// FIXME: In the case of a scene, this is currently the scene name (though this leaves
289 /// us with a to-be-resolved problem of non-unique region names).
290 /// </summary>
291 /// <value>
292 /// The container.
293 /// </value>
294 public string Container { get; private set; }
295
296 public StatType StatType { get; private set; }
297
298 /// <summary>
299 /// Action used to update this stat when the value is requested if it's a pull type.
300 /// </summary>
301 public Action<Stat> PullAction { get; private set; }
302
303 public StatVerbosity Verbosity { get; private set; }
304 public string ShortName { get; private set; }
305 public string Name { get; private set; }
306 public string Description { get; private set; }
307 public virtual string UnitName { get; private set; }
308
309 public virtual double Value
310 {
311 get
312 {
313 // Asking for an update here means that the updater cannot access this value without infinite recursion.
314 // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
315 // called by the pull action and just return the value.
316 if (StatType == StatType.Pull)
317 PullAction(this);
318
319 return m_value;
320 }
321
322 set
323 {
324 m_value = value;
325 }
326 }
327
328 private double m_value;
329
330 /// <summary>
331 /// Constructor
332 /// </summary>
333 /// <param name='shortName'>Short name for the stat. Must not contain spaces. e.g. "LongFrames"</param>
334 /// <param name='name'>Human readable name for the stat. e.g. "Long frames"</param>
335 /// <param name='description'>Description of stat</param>
336 /// <param name='unitName'>
337 /// Unit name for the stat. Should be preceeded by a space if the unit name isn't normally appeneded immediately to the value.
338 /// e.g. " frames"
339 /// </param>
340 /// <param name='category'>Category under which this stat should appear, e.g. "scene". Do not capitalize.</param>
341 /// <param name='container'>Entity to which this stat relates. e.g. scene name if this is a per scene stat.</param>
342 /// <param name='type'>Push or pull</param>
343 /// <param name='pullAction'>Pull stats need an action to update the stat on request. Push stats should set null here.</param>
344 /// <param name='verbosity'>Verbosity of stat. Controls whether it will appear in short stat display or only full display.</param>
345 public Stat(
346 string shortName,
347 string name,
348 string description,
349 string unitName,
350 string category,
351 string container,
352 StatType type,
353 Action<Stat> pullAction,
354 StatVerbosity verbosity)
355 {
356 if (StatsManager.SubCommands.Contains(category))
357 throw new Exception(
358 string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category));
359
360 ShortName = shortName;
361 Name = name;
362 Description = description;
363 UnitName = unitName;
364 Category = category;
365 Container = container;
366 StatType = type;
367
368 if (StatType == StatType.Push && pullAction != null)
369 throw new Exception("A push stat cannot have a pull action");
370 else
371 PullAction = pullAction;
372
373 Verbosity = verbosity;
374 }
375
376 public virtual string ToConsoleString()
377 {
378 return string.Format(
379 "{0}.{1}.{2} : {3}{4}", Category, Container, ShortName, Value, UnitName);
380 }
381 }
382
383 public class PercentageStat : Stat
384 {
385 public int Antecedent { get; set; }
386 public int Consequent { get; set; }
387
388 public override double Value
389 {
390 get
391 {
392 int c = Consequent;
393
394 // Avoid any chance of a multi-threaded divide-by-zero
395 if (c == 0)
396 return 0;
397
398 return (double)Antecedent / c * 100;
399 }
400
401 set
402 {
403 throw new Exception("Cannot set value on a PercentageStat");
404 }
405 }
406
407 public PercentageStat(
408 string shortName,
409 string name,
410 string description,
411 string category,
412 string container,
413 StatType type,
414 Action<Stat> pullAction,
415 StatVerbosity verbosity)
416 : base(shortName, name, description, "%", category, container, type, pullAction, verbosity) {}
417
418 public override string ToConsoleString()
419 {
420 return string.Format(
421 "{0}.{1}.{2} : {3:0.##}{4} ({5}/{6})",
422 Category, Container, ShortName, Value, UnitName, Antecedent, Consequent);
423 }
64 } 424 }
65} \ No newline at end of file 425} \ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
index b709baa..28d6d5c 100644
--- a/OpenSim/Framework/Monitoring/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring
89 FirstTick = Environment.TickCount & Int32.MaxValue; 89 FirstTick = Environment.TickCount & Int32.MaxValue;
90 LastTick = FirstTick; 90 LastTick = FirstTick;
91 } 91 }
92
93 public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
94 {
95 Thread = previousTwi.Thread;
96 FirstTick = previousTwi.FirstTick;
97 LastTick = previousTwi.LastTick;
98 Timeout = previousTwi.Timeout;
99 IsTimedOut = previousTwi.IsTimedOut;
100 AlarmIfTimeout = previousTwi.AlarmIfTimeout;
101 AlarmMethod = previousTwi.AlarmMethod;
102 }
92 } 103 }
93 104
94 /// <summary> 105 /// <summary>
@@ -220,7 +231,25 @@ namespace OpenSim.Framework.Monitoring
220 private static bool RemoveThread(int threadID) 231 private static bool RemoveThread(int threadID)
221 { 232 {
222 lock (m_threads) 233 lock (m_threads)
223 return m_threads.Remove(threadID); 234 {
235 ThreadWatchdogInfo twi;
236 if (m_threads.TryGetValue(threadID, out twi))
237 {
238 m_log.DebugFormat(
239 "[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
240
241 m_threads.Remove(threadID);
242
243 return true;
244 }
245 else
246 {
247 m_log.WarnFormat(
248 "[WATCHDOG]: Requested to remove thread with ID {0} but this is not being monitored", threadID);
249
250 return false;
251 }
252 }
224 } 253 }
225 254
226 public static bool AbortThread(int threadID) 255 public static bool AbortThread(int threadID)
@@ -335,7 +364,9 @@ namespace OpenSim.Framework.Monitoring
335 if (callbackInfos == null) 364 if (callbackInfos == null)
336 callbackInfos = new List<ThreadWatchdogInfo>(); 365 callbackInfos = new List<ThreadWatchdogInfo>();
337 366
338 callbackInfos.Add(threadInfo); 367 // Send a copy of the watchdog info to prevent race conditions where the watchdog
368 // thread updates the monitoring info after an alarm has been sent out.
369 callbackInfos.Add(new ThreadWatchdogInfo(threadInfo));
339 } 370 }
340 } 371 }
341 } 372 }
diff --git a/OpenSim/Framework/Pool.cs b/OpenSim/Framework/Pool.cs
new file mode 100644
index 0000000..5484f5c
--- /dev/null
+++ b/OpenSim/Framework/Pool.cs
@@ -0,0 +1,91 @@
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.Generic;
30
31namespace OpenSim.Framework
32{
33 /// <summary>
34 /// Naive pool implementation.
35 /// </summary>
36 /// <remarks>
37 /// Currently assumes that objects are in a useable state when returned.
38 /// </remarks>
39 public class Pool<T>
40 {
41 /// <summary>
42 /// Number of objects in the pool.
43 /// </summary>
44 public int Count
45 {
46 get
47 {
48 lock (m_pool)
49 return m_pool.Count;
50 }
51 }
52
53 private Stack<T> m_pool;
54
55 /// <summary>
56 /// Maximum pool size. Beyond this, any returned objects are not pooled.
57 /// </summary>
58 private int m_maxPoolSize;
59
60 private Func<T> m_createFunction;
61
62 public Pool(Func<T> createFunction, int maxSize)
63 {
64 m_maxPoolSize = maxSize;
65 m_createFunction = createFunction;
66 m_pool = new Stack<T>(m_maxPoolSize);
67 }
68
69 public T GetObject()
70 {
71 lock (m_pool)
72 {
73 if (m_pool.Count > 0)
74 return m_pool.Pop();
75 else
76 return m_createFunction();
77 }
78 }
79
80 public void ReturnObject(T obj)
81 {
82 lock (m_pool)
83 {
84 if (m_pool.Count >= m_maxPoolSize)
85 return;
86 else
87 m_pool.Push(obj);
88 }
89 }
90 }
91} \ No newline at end of file
diff --git a/OpenSim/Framework/RegionFlags.cs b/OpenSim/Framework/RegionFlags.cs
new file mode 100644
index 0000000..a3089b0
--- /dev/null
+++ b/OpenSim/Framework/RegionFlags.cs
@@ -0,0 +1,53 @@
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;
29
30namespace OpenSim.Framework
31{
32 /// <summary>
33 /// Region flags used internally by OpenSimulator to store installation specific information about regions.
34 /// </summary>
35 /// <remarks>
36 /// Don't confuse with OpenMetaverse.RegionFlags which are client facing flags (i.e. they go over the wire).
37 /// Returned by IGridService.GetRegionFlags()
38 /// </remarks>
39 [Flags]
40 public enum RegionFlags : int
41 {
42 DefaultRegion = 1, // Used for new Rez. Random if multiple defined
43 FallbackRegion = 2, // Regions we redirect to when the destination is down
44 RegionOnline = 4, // Set when a region comes online, unset when it unregisters and DeleteOnUnregister is false
45 NoDirectLogin = 8, // Region unavailable for direct logins (by name)
46 Persistent = 16, // Don't remove on unregister
47 LockedOut = 32, // Don't allow registration
48 NoMove = 64, // Don't allow moving this region
49 Reservation = 128, // This is an inactive reservation
50 Authenticate = 256, // Require authentication
51 Hyperlink = 512 // Record represents a HG link
52 }
53} \ No newline at end of file
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 4bde7be..e7bed6a 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -122,10 +122,13 @@ namespace OpenSim.Framework
122 public UUID lastMapUUID = UUID.Zero; 122 public UUID lastMapUUID = UUID.Zero;
123 public string lastMapRefresh = "0"; 123 public string lastMapRefresh = "0";
124 124
125 private float m_nonphysPrimMin = 0;
125 private int m_nonphysPrimMax = 0; 126 private int m_nonphysPrimMax = 0;
127 private float m_physPrimMin = 0;
126 private int m_physPrimMax = 0; 128 private int m_physPrimMax = 0;
127 private bool m_clampPrimSize = false; 129 private bool m_clampPrimSize = false;
128 private int m_objectCapacity = 0; 130 private int m_objectCapacity = 0;
131 private int m_linksetCapacity = 0;
129 private int m_agentCapacity = 0; 132 private int m_agentCapacity = 0;
130 private string m_regionType = String.Empty; 133 private string m_regionType = String.Empty;
131 private RegionLightShareData m_windlight = new RegionLightShareData(); 134 private RegionLightShareData m_windlight = new RegionLightShareData();
@@ -287,11 +290,21 @@ namespace OpenSim.Framework
287 set { m_windlight = value; } 290 set { m_windlight = value; }
288 } 291 }
289 292
293 public float NonphysPrimMin
294 {
295 get { return m_nonphysPrimMin; }
296 }
297
290 public int NonphysPrimMax 298 public int NonphysPrimMax
291 { 299 {
292 get { return m_nonphysPrimMax; } 300 get { return m_nonphysPrimMax; }
293 } 301 }
294 302
303 public float PhysPrimMin
304 {
305 get { return m_physPrimMin; }
306 }
307
295 public int PhysPrimMax 308 public int PhysPrimMax
296 { 309 {
297 get { return m_physPrimMax; } 310 get { return m_physPrimMax; }
@@ -307,6 +320,11 @@ namespace OpenSim.Framework
307 get { return m_objectCapacity; } 320 get { return m_objectCapacity; }
308 } 321 }
309 322
323 public int LinksetCapacity
324 {
325 get { return m_linksetCapacity; }
326 }
327
310 public int AgentCapacity 328 public int AgentCapacity
311 { 329 {
312 get { return m_agentCapacity; } 330 get { return m_agentCapacity; }
@@ -625,16 +643,31 @@ namespace OpenSim.Framework
625 m_regionType = config.GetString("RegionType", String.Empty); 643 m_regionType = config.GetString("RegionType", String.Empty);
626 allKeys.Remove("RegionType"); 644 allKeys.Remove("RegionType");
627 645
628 // Prim stuff 646 #region Prim stuff
629 // 647
630 m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); 648 m_nonphysPrimMin = config.GetFloat("NonPhysicalPrimMin", 0);
631 allKeys.Remove("NonphysicalPrimMax"); 649 allKeys.Remove("NonPhysicalPrimMin");
650
651 m_nonphysPrimMax = config.GetInt("NonPhysicalPrimMax", 0);
652 allKeys.Remove("NonPhysicalPrimMax");
653
654 m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
655 allKeys.Remove("PhysicalPrimMin");
656
632 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); 657 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
633 allKeys.Remove("PhysicalPrimMax"); 658 allKeys.Remove("PhysicalPrimMax");
659
634 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); 660 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
635 allKeys.Remove("ClampPrimSize"); 661 allKeys.Remove("ClampPrimSize");
662
636 m_objectCapacity = config.GetInt("MaxPrims", 15000); 663 m_objectCapacity = config.GetInt("MaxPrims", 15000);
637 allKeys.Remove("MaxPrims"); 664 allKeys.Remove("MaxPrims");
665
666 m_linksetCapacity = config.GetInt("LinksetPrims", 0);
667 allKeys.Remove("LinksetPrims");
668
669 #endregion
670
638 m_agentCapacity = config.GetInt("MaxAgents", 100); 671 m_agentCapacity = config.GetInt("MaxAgents", 100);
639 allKeys.Remove("MaxAgents"); 672 allKeys.Remove("MaxAgents");
640 673
@@ -673,16 +706,27 @@ namespace OpenSim.Framework
673 706
674 config.Set("ExternalHostName", m_externalHostName); 707 config.Set("ExternalHostName", m_externalHostName);
675 708
676 if (m_nonphysPrimMax != 0) 709 if (m_nonphysPrimMin > 0)
710 config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
711
712 if (m_nonphysPrimMax > 0)
677 config.Set("NonphysicalPrimMax", m_nonphysPrimMax); 713 config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
678 if (m_physPrimMax != 0) 714
715 if (m_physPrimMin > 0)
716 config.Set("PhysicalPrimMax", m_physPrimMin);
717
718 if (m_physPrimMax > 0)
679 config.Set("PhysicalPrimMax", m_physPrimMax); 719 config.Set("PhysicalPrimMax", m_physPrimMax);
720
680 config.Set("ClampPrimSize", m_clampPrimSize.ToString()); 721 config.Set("ClampPrimSize", m_clampPrimSize.ToString());
681 722
682 if (m_objectCapacity != 0) 723 if (m_objectCapacity > 0)
683 config.Set("MaxPrims", m_objectCapacity); 724 config.Set("MaxPrims", m_objectCapacity);
684 725
685 if (m_agentCapacity != 0) 726 if (m_linksetCapacity > 0)
727 config.Set("LinksetPrims", m_linksetCapacity);
728
729 if (m_agentCapacity > 0)
686 config.Set("MaxAgents", m_agentCapacity); 730 config.Set("MaxAgents", m_agentCapacity);
687 731
688 if (ScopeID != UUID.Zero) 732 if (ScopeID != UUID.Zero)
@@ -759,9 +803,15 @@ namespace OpenSim.Framework
759 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, 803 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
760 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); 804 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
761 805
806 configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
807 "Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
808
762 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 809 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
763 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); 810 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
764 811
812 configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
813 "Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
814
765 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 815 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
766 "Maximum size for physical prims", m_physPrimMax.ToString(), true); 816 "Maximum size for physical prims", m_physPrimMax.ToString(), true);
767 817
@@ -771,6 +821,9 @@ namespace OpenSim.Framework
771 configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 821 configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
772 "Max objects this sim will hold", m_objectCapacity.ToString(), true); 822 "Max objects this sim will hold", m_objectCapacity.ToString(), true);
773 823
824 configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
825 "Max prims an object will hold", m_linksetCapacity.ToString(), true);
826
774 configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 827 configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
775 "Max avatars this sim will hold", m_agentCapacity.ToString(), true); 828 "Max avatars this sim will hold", m_agentCapacity.ToString(), true);
776 829
@@ -892,6 +945,9 @@ namespace OpenSim.Framework
892 case "object_capacity": 945 case "object_capacity":
893 m_objectCapacity = (int)configuration_result; 946 m_objectCapacity = (int)configuration_result;
894 break; 947 break;
948 case "linkset_capacity":
949 m_linksetCapacity = (int)configuration_result;
950 break;
895 case "agent_capacity": 951 case "agent_capacity":
896 m_agentCapacity = (int)configuration_result; 952 m_agentCapacity = (int)configuration_result;
897 break; 953 break;
diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs
index 2c5e001..48f1c4f 100644
--- a/OpenSim/Framework/Serialization/ArchiveConstants.cs
+++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs
@@ -53,6 +53,11 @@ namespace OpenSim.Framework.Serialization
53 public const string INVENTORY_PATH = "inventory/"; 53 public const string INVENTORY_PATH = "inventory/";
54 54
55 /// <value> 55 /// <value>
56 /// Path for regions in a multi-region archive
57 /// </value>
58 public const string REGIONS_PATH = "regions/";
59
60 /// <value>
56 /// Path for the prims file 61 /// Path for the prims file
57 /// </value> 62 /// </value>
58 public const string OBJECTS_PATH = "objects/"; 63 public const string OBJECTS_PATH = "objects/";
diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs
index d31d27c..fa7160f 100644
--- a/OpenSim/Framework/Serialization/External/OspResolver.cs
+++ b/OpenSim/Framework/Serialization/External/OspResolver.cs
@@ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization
65 65
66 UserAccount account = userService.GetUserAccount(UUID.Zero, userId); 66 UserAccount account = userService.GetUserAccount(UUID.Zero, userId);
67 if (account != null) 67 if (account != null)
68 {
68 return MakeOspa(account.FirstName, account.LastName); 69 return MakeOspa(account.FirstName, account.LastName);
70 }
69// else 71// else
72// {
70// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId); 73// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId);
74// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId);
75// }
71 76
72 return null; 77 return null;
73 } 78 }
@@ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization
79 /// <returns></returns> 84 /// <returns></returns>
80 public static string MakeOspa(string firstName, string lastName) 85 public static string MakeOspa(string firstName, string lastName)
81 { 86 {
82// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName); 87 string ospa
88 = OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
89
90// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
91// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
83 92
84 return 93 return ospa;
85 OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
86 } 94 }
87 95
88 /// <summary> 96 /// <summary>
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index cf19002..605909d 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -96,11 +96,6 @@ namespace OpenSim.Framework.Servers
96 get { return m_httpServer; } 96 get { return m_httpServer; }
97 } 97 }
98 98
99 /// <summary>
100 /// Holds the non-viewer statistics collection object for this service/server
101 /// </summary>
102 protected IStatsCollector m_stats;
103
104 public BaseOpenSimServer() 99 public BaseOpenSimServer()
105 { 100 {
106 m_startuptime = DateTime.Now; 101 m_startuptime = DateTime.Now;
@@ -177,10 +172,6 @@ namespace OpenSim.Framework.Servers
177 "show info", 172 "show info",
178 "Show general information about the server", HandleShow); 173 "Show general information about the server", HandleShow);
179 174
180 m_console.Commands.AddCommand("General", false, "show stats",
181 "show stats",
182 "Show statistics", HandleShow);
183
184 m_console.Commands.AddCommand("General", false, "show threads", 175 m_console.Commands.AddCommand("General", false, "show threads",
185 "show threads", 176 "show threads",
186 "Show thread status", HandleShow); 177 "Show thread status", HandleShow);
@@ -201,8 +192,19 @@ namespace OpenSim.Framework.Servers
201 "threads show", 192 "threads show",
202 "Show thread status. Synonym for \"show threads\"", 193 "Show thread status. Synonym for \"show threads\"",
203 (string module, string[] args) => Notice(GetThreadsReport())); 194 (string module, string[] args) => Notice(GetThreadsReport()));
195
196 m_console.Commands.AddCommand("General", false, "force gc",
197 "force gc",
198 "Manually invoke runtime garbage collection. For debugging purposes",
199 HandleForceGc);
204 } 200 }
205 } 201 }
202
203 private void HandleForceGc(string module, string[] args)
204 {
205 MainConsole.Instance.Output("Manually invoking runtime garbage collection");
206 GC.Collect();
207 }
206 208
207 /// <summary> 209 /// <summary>
208 /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing 210 /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
@@ -226,12 +228,7 @@ namespace OpenSim.Framework.Servers
226 { 228 {
227 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n"); 229 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
228 sb.Append(GetUptimeReport()); 230 sb.Append(GetUptimeReport());
229 231 sb.Append(StatsManager.SimExtraStats.Report());
230 if (m_stats != null)
231 {
232 sb.Append(m_stats.Report());
233 }
234
235 sb.Append(Environment.NewLine); 232 sb.Append(Environment.NewLine);
236 sb.Append(GetThreadsReport()); 233 sb.Append(GetThreadsReport());
237 234
@@ -382,10 +379,6 @@ namespace OpenSim.Framework.Servers
382 { 379 {
383 Notice("set log level [level] - change the console logging level only. For example, off or debug."); 380 Notice("set log level [level] - change the console logging level only. For example, off or debug.");
384 Notice("show info - show server information (e.g. startup path)."); 381 Notice("show info - show server information (e.g. startup path).");
385
386 if (m_stats != null)
387 Notice("show stats - show statistical information for this server");
388
389 Notice("show threads - list tracked threads"); 382 Notice("show threads - list tracked threads");
390 Notice("show uptime - show server startup time and uptime."); 383 Notice("show uptime - show server startup time and uptime.");
391 Notice("show version - show server version."); 384 Notice("show version - show server version.");
@@ -409,11 +402,6 @@ namespace OpenSim.Framework.Servers
409 ShowInfo(); 402 ShowInfo();
410 break; 403 break;
411 404
412 case "stats":
413 if (m_stats != null)
414 Notice(m_stats.Report());
415 break;
416
417 case "threads": 405 case "threads":
418 Notice(GetThreadsReport()); 406 Notice(GetThreadsReport());
419 break; 407 break;
@@ -604,8 +592,7 @@ namespace OpenSim.Framework.Servers
604 592
605 public string osSecret { 593 public string osSecret {
606 // Secret uuid for the simulator 594 // Secret uuid for the simulator
607 get { return m_osSecret; } 595 get { return m_osSecret; }
608
609 } 596 }
610 597
611 public string StatReport(IOSHttpRequest httpRequest) 598 public string StatReport(IOSHttpRequest httpRequest)
@@ -613,11 +600,11 @@ namespace OpenSim.Framework.Servers
613 // If we catch a request for "callback", wrap the response in the value for jsonp 600 // If we catch a request for "callback", wrap the response in the value for jsonp
614 if (httpRequest.Query.ContainsKey("callback")) 601 if (httpRequest.Query.ContainsKey("callback"))
615 { 602 {
616 return httpRequest.Query["callback"].ToString() + "(" + m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; 603 return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
617 } 604 }
618 else 605 else
619 { 606 {
620 return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); 607 return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
621 } 608 }
622 } 609 }
623 610
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 788a0b9..3198891 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -54,8 +54,23 @@ namespace OpenSim.Framework.Servers.HttpServer
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); 55 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
56 56
57 /// <summary>
58 /// Gets or sets the debug level.
59 /// </summary>
60 /// <value>
61 /// See MainServer.DebugLevel.
62 /// </value>
57 public int DebugLevel { get; set; } 63 public int DebugLevel { get; set; }
58 64
65 /// <summary>
66 /// Request number for diagnostic purposes.
67 /// </summary>
68 /// <remarks>
69 /// This is an internal number. In some debug situations an external number may also be supplied in the
70 /// opensim-request-id header but we are not currently logging this.
71 /// </remarks>
72 public int RequestNumber { get; private set; }
73
59 private volatile int NotSocketErrors = 0; 74 private volatile int NotSocketErrors = 0;
60 public volatile bool HTTPDRunning = false; 75 public volatile bool HTTPDRunning = false;
61 76
@@ -67,7 +82,7 @@ namespace OpenSim.Framework.Servers.HttpServer
67 protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>(); 82 protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>();
68 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>(); 83 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>();
69 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>(); 84 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>();
70 protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>(); 85// protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
71 protected Dictionary<string, PollServiceEventArgs> m_pollHandlers = 86 protected Dictionary<string, PollServiceEventArgs> m_pollHandlers =
72 new Dictionary<string, PollServiceEventArgs>(); 87 new Dictionary<string, PollServiceEventArgs>();
73 88
@@ -245,29 +260,29 @@ namespace OpenSim.Framework.Servers.HttpServer
245 return new List<string>(m_pollHandlers.Keys); 260 return new List<string>(m_pollHandlers.Keys);
246 } 261 }
247 262
248 // Note that the agent string is provided simply to differentiate 263// // Note that the agent string is provided simply to differentiate
249 // the handlers - it is NOT required to be an actual agent header 264// // the handlers - it is NOT required to be an actual agent header
250 // value. 265// // value.
251 public bool AddAgentHandler(string agent, IHttpAgentHandler handler) 266// public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
252 { 267// {
253 lock (m_agentHandlers) 268// lock (m_agentHandlers)
254 { 269// {
255 if (!m_agentHandlers.ContainsKey(agent)) 270// if (!m_agentHandlers.ContainsKey(agent))
256 { 271// {
257 m_agentHandlers.Add(agent, handler); 272// m_agentHandlers.Add(agent, handler);
258 return true; 273// return true;
259 } 274// }
260 } 275// }
261 276//
262 //must already have a handler for that path so return false 277// //must already have a handler for that path so return false
263 return false; 278// return false;
264 } 279// }
265 280//
266 public List<string> GetAgentHandlerKeys() 281// public List<string> GetAgentHandlerKeys()
267 { 282// {
268 lock (m_agentHandlers) 283// lock (m_agentHandlers)
269 return new List<string>(m_agentHandlers.Keys); 284// return new List<string>(m_agentHandlers.Keys);
270 } 285// }
271 286
272 public bool AddLLSDHandler(string path, LLSDMethod handler) 287 public bool AddLLSDHandler(string path, LLSDMethod handler)
273 { 288 {
@@ -296,6 +311,8 @@ namespace OpenSim.Framework.Servers.HttpServer
296 311
297 private void OnRequest(object source, RequestEventArgs args) 312 private void OnRequest(object source, RequestEventArgs args)
298 { 313 {
314 RequestNumber++;
315
299 try 316 try
300 { 317 {
301 IHttpClientContext context = (IHttpClientContext)source; 318 IHttpClientContext context = (IHttpClientContext)source;
@@ -406,7 +423,6 @@ namespace OpenSim.Framework.Servers.HttpServer
406 string requestMethod = request.HttpMethod; 423 string requestMethod = request.HttpMethod;
407 string uriString = request.RawUrl; 424 string uriString = request.RawUrl;
408 425
409// string reqnum = "unknown";
410 int requestStartTick = Environment.TickCount; 426 int requestStartTick = Environment.TickCount;
411 427
412 // Will be adjusted later on. 428 // Will be adjusted later on.
@@ -423,22 +439,22 @@ namespace OpenSim.Framework.Servers.HttpServer
423 439
424 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); 440 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
425 441
426 // This is the REST agent interface. We require an agent to properly identify 442// // This is the REST agent interface. We require an agent to properly identify
427 // itself. If the REST handler recognizes the prefix it will attempt to 443// // itself. If the REST handler recognizes the prefix it will attempt to
428 // satisfy the request. If it is not recognizable, and no damage has occurred 444// // satisfy the request. If it is not recognizable, and no damage has occurred
429 // the request can be passed through to the other handlers. This is a low 445// // the request can be passed through to the other handlers. This is a low
430 // probability event; if a request is matched it is normally expected to be 446// // probability event; if a request is matched it is normally expected to be
431 // handled 447// // handled
432 IHttpAgentHandler agentHandler; 448// IHttpAgentHandler agentHandler;
433 449//
434 if (TryGetAgentHandler(request, response, out agentHandler)) 450// if (TryGetAgentHandler(request, response, out agentHandler))
435 { 451// {
436 if (HandleAgentRequest(agentHandler, request, response)) 452// if (HandleAgentRequest(agentHandler, request, response))
437 { 453// {
438 requestEndTick = Environment.TickCount; 454// requestEndTick = Environment.TickCount;
439 return; 455// return;
440 } 456// }
441 } 457// }
442 458
443 //response.KeepAlive = true; 459 //response.KeepAlive = true;
444 response.SendChunked = false; 460 response.SendChunked = false;
@@ -450,9 +466,7 @@ namespace OpenSim.Framework.Servers.HttpServer
450 if (TryGetStreamHandler(handlerKey, out requestHandler)) 466 if (TryGetStreamHandler(handlerKey, out requestHandler))
451 { 467 {
452 if (DebugLevel >= 3) 468 if (DebugLevel >= 3)
453 m_log.DebugFormat( 469 LogIncomingToStreamHandler(request, requestHandler);
454 "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
455 request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
456 470
457 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. 471 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
458 472
@@ -529,11 +543,8 @@ namespace OpenSim.Framework.Servers.HttpServer
529 { 543 {
530 case null: 544 case null:
531 case "text/html": 545 case "text/html":
532
533 if (DebugLevel >= 3) 546 if (DebugLevel >= 3)
534 m_log.DebugFormat( 547 LogIncomingToContentTypeHandler(request);
535 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
536 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
537 548
538 buffer = HandleHTTPRequest(request, response); 549 buffer = HandleHTTPRequest(request, response);
539 break; 550 break;
@@ -541,11 +552,8 @@ namespace OpenSim.Framework.Servers.HttpServer
541 case "application/llsd+xml": 552 case "application/llsd+xml":
542 case "application/xml+llsd": 553 case "application/xml+llsd":
543 case "application/llsd+json": 554 case "application/llsd+json":
544
545 if (DebugLevel >= 3) 555 if (DebugLevel >= 3)
546 m_log.DebugFormat( 556 LogIncomingToContentTypeHandler(request);
547 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
548 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
549 557
550 buffer = HandleLLSDRequests(request, response); 558 buffer = HandleLLSDRequests(request, response);
551 break; 559 break;
@@ -564,9 +572,7 @@ namespace OpenSim.Framework.Servers.HttpServer
564 if (DoWeHaveALLSDHandler(request.RawUrl)) 572 if (DoWeHaveALLSDHandler(request.RawUrl))
565 { 573 {
566 if (DebugLevel >= 3) 574 if (DebugLevel >= 3)
567 m_log.DebugFormat( 575 LogIncomingToContentTypeHandler(request);
568 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
569 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
570 576
571 buffer = HandleLLSDRequests(request, response); 577 buffer = HandleLLSDRequests(request, response);
572 } 578 }
@@ -574,18 +580,14 @@ namespace OpenSim.Framework.Servers.HttpServer
574 else if (DoWeHaveAHTTPHandler(request.RawUrl)) 580 else if (DoWeHaveAHTTPHandler(request.RawUrl))
575 { 581 {
576 if (DebugLevel >= 3) 582 if (DebugLevel >= 3)
577 m_log.DebugFormat( 583 LogIncomingToContentTypeHandler(request);
578 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
579 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
580 584
581 buffer = HandleHTTPRequest(request, response); 585 buffer = HandleHTTPRequest(request, response);
582 } 586 }
583 else 587 else
584 { 588 {
585 if (DebugLevel >= 3) 589 if (DebugLevel >= 3)
586 m_log.DebugFormat( 590 LogIncomingToXmlRpcHandler(request);
587 "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
588 request.HttpMethod, request.Url.PathAndQuery);
589 591
590 // generic login request. 592 // generic login request.
591 buffer = HandleXmlRpcRequests(request, response); 593 buffer = HandleXmlRpcRequests(request, response);
@@ -629,11 +631,11 @@ namespace OpenSim.Framework.Servers.HttpServer
629 } 631 }
630 catch (IOException e) 632 catch (IOException e)
631 { 633 {
632 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); 634 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
633 } 635 }
634 catch (Exception e) 636 catch (Exception e)
635 { 637 {
636 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); 638 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
637 SendHTML500(response); 639 SendHTML500(response);
638 } 640 }
639 finally 641 finally
@@ -644,17 +646,93 @@ namespace OpenSim.Framework.Servers.HttpServer
644 if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture")) 646 if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
645 { 647 {
646 m_log.InfoFormat( 648 m_log.InfoFormat(
647 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms", 649 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
650 RequestNumber,
648 requestMethod, 651 requestMethod,
649 uriString, 652 uriString,
650 requestHandler != null ? requestHandler.Name : "", 653 requestHandler != null ? requestHandler.Name : "",
651 requestHandler != null ? requestHandler.Description : "", 654 requestHandler != null ? requestHandler.Description : "",
652 request.RemoteIPEndPoint.ToString(), 655 request.RemoteIPEndPoint,
656 tickdiff);
657 }
658 else if (DebugLevel >= 4)
659 {
660 m_log.DebugFormat(
661 "[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms",
662 RequestNumber,
663 Port,
653 tickdiff); 664 tickdiff);
654 } 665 }
655 } 666 }
656 } 667 }
657 668
669 private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler)
670 {
671 m_log.DebugFormat(
672 "[BASE HTTP SERVER]: HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}",
673 RequestNumber,
674 Port,
675 request.HttpMethod,
676 request.Url.PathAndQuery,
677 requestHandler.Name,
678 requestHandler.Description,
679 request.RemoteIPEndPoint);
680
681 if (DebugLevel >= 5)
682 LogIncomingInDetail(request);
683 }
684
685 private void LogIncomingToContentTypeHandler(OSHttpRequest request)
686 {
687 m_log.DebugFormat(
688 "[BASE HTTP SERVER]: HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}",
689 RequestNumber,
690 Port,
691 (request.ContentType == null || request.ContentType == "") ? "not set" : request.ContentType,
692 request.HttpMethod,
693 request.Url.PathAndQuery,
694 request.RemoteIPEndPoint);
695
696 if (DebugLevel >= 5)
697 LogIncomingInDetail(request);
698 }
699
700 private void LogIncomingToXmlRpcHandler(OSHttpRequest request)
701 {
702 m_log.DebugFormat(
703 "[BASE HTTP SERVER]: HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}",
704 RequestNumber,
705 Port,
706 request.HttpMethod,
707 request.Url.PathAndQuery,
708 request.RemoteIPEndPoint);
709
710 if (DebugLevel >= 5)
711 LogIncomingInDetail(request);
712 }
713
714 private void LogIncomingInDetail(OSHttpRequest request)
715 {
716 using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8))
717 {
718 string output;
719
720 if (DebugLevel == 5)
721 {
722 const int sampleLength = 80;
723 char[] sampleChars = new char[sampleLength];
724 reader.Read(sampleChars, 0, sampleLength);
725 output = new string(sampleChars);
726 }
727 else
728 {
729 output = reader.ReadToEnd();
730 }
731
732 m_log.DebugFormat("[BASE HTTP SERVER]: {0}...", output.Replace("\n", @"\n"));
733 }
734 }
735
658 private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) 736 private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler)
659 { 737 {
660 string bestMatch = null; 738 string bestMatch = null;
@@ -747,24 +825,24 @@ namespace OpenSim.Framework.Servers.HttpServer
747 } 825 }
748 } 826 }
749 827
750 private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) 828// private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
751 { 829// {
752 agentHandler = null; 830// agentHandler = null;
753 831//
754 lock (m_agentHandlers) 832// lock (m_agentHandlers)
755 { 833// {
756 foreach (IHttpAgentHandler handler in m_agentHandlers.Values) 834// foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
757 { 835// {
758 if (handler.Match(request, response)) 836// if (handler.Match(request, response))
759 { 837// {
760 agentHandler = handler; 838// agentHandler = handler;
761 return true; 839// return true;
762 } 840// }
763 } 841// }
764 } 842// }
765 843//
766 return false; 844// return false;
767 } 845// }
768 846
769 /// <summary> 847 /// <summary>
770 /// Try all the registered xmlrpc handlers when an xmlrpc request is received. 848 /// Try all the registered xmlrpc handlers when an xmlrpc request is received.
@@ -1737,21 +1815,21 @@ namespace OpenSim.Framework.Servers.HttpServer
1737 m_pollHandlers.Remove(path); 1815 m_pollHandlers.Remove(path);
1738 } 1816 }
1739 1817
1740 public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler) 1818// public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
1741 { 1819// {
1742 lock (m_agentHandlers) 1820// lock (m_agentHandlers)
1743 { 1821// {
1744 IHttpAgentHandler foundHandler; 1822// IHttpAgentHandler foundHandler;
1745 1823//
1746 if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler) 1824// if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler)
1747 { 1825// {
1748 m_agentHandlers.Remove(agent); 1826// m_agentHandlers.Remove(agent);
1749 return true; 1827// return true;
1750 } 1828// }
1751 } 1829// }
1752 1830//
1753 return false; 1831// return false;
1754 } 1832// }
1755 1833
1756 public void RemoveXmlRPCHandler(string method) 1834 public void RemoveXmlRPCHandler(string method)
1757 { 1835 {
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
index db58f6f..0bd3aae 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
@@ -41,10 +41,10 @@ namespace OpenSim.Framework.Servers.HttpServer
41 uint Port { get; } 41 uint Port { get; }
42 bool UseSSL { get; } 42 bool UseSSL { get; }
43 43
44 // Note that the agent string is provided simply to differentiate 44// // Note that the agent string is provided simply to differentiate
45 // the handlers - it is NOT required to be an actual agent header 45// // the handlers - it is NOT required to be an actual agent header
46 // value. 46// // value.
47 bool AddAgentHandler(string agent, IHttpAgentHandler handler); 47// bool AddAgentHandler(string agent, IHttpAgentHandler handler);
48 48
49 /// <summary> 49 /// <summary>
50 /// Add a handler for an HTTP request. 50 /// Add a handler for an HTTP request.
@@ -106,13 +106,13 @@ namespace OpenSim.Framework.Servers.HttpServer
106 106
107 bool SetDefaultLLSDHandler(DefaultLLSDMethod handler); 107 bool SetDefaultLLSDHandler(DefaultLLSDMethod handler);
108 108
109 /// <summary> 109// /// <summary>
110 /// Remove the agent if it is registered. 110// /// Remove the agent if it is registered.
111 /// </summary> 111// /// </summary>
112 /// <param name="agent"></param> 112// /// <param name="agent"></param>
113 /// <param name="handler"></param> 113// /// <param name="handler"></param>
114 /// <returns></returns> 114// /// <returns></returns>
115 bool RemoveAgentHandler(string agent, IHttpAgentHandler handler); 115// bool RemoveAgentHandler(string agent, IHttpAgentHandler handler);
116 116
117 /// <summary> 117 /// <summary>
118 /// Remove an HTTP handler 118 /// Remove an HTTP handler
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index 8dc0e3a..ae7d515 100644
--- a/OpenSim/Framework/Servers/MainServer.cs
+++ b/OpenSim/Framework/Servers/MainServer.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Net; 31using System.Net;
32using System.Text;
32using log4net; 33using log4net;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
@@ -47,9 +48,12 @@ namespace OpenSim.Framework.Servers
47 /// Control the printing of certain debug messages. 48 /// Control the printing of certain debug messages.
48 /// </summary> 49 /// </summary>
49 /// <remarks> 50 /// <remarks>
50 /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data. 51 /// If DebugLevel >= 1 then short warnings are logged when receiving bad input data.
51 /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data. 52 /// If DebugLevel >= 2 then long warnings are logged when receiving bad input data.
52 /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged. 53 /// If DebugLevel >= 3 then short notices about all incoming non-poll HTTP requests are logged.
54 /// If DebugLevel >= 4 then the time taken to fulfill the request is logged.
55 /// If DebugLevel >= 5 then the start of the body of incoming non-poll HTTP requests will be logged.
56 /// If DebugLevel >= 6 then the entire body of incoming non-poll HTTP requests will be logged.
53 /// </remarks> 57 /// </remarks>
54 public static int DebugLevel 58 public static int DebugLevel
55 { 59 {
@@ -101,17 +105,28 @@ namespace OpenSim.Framework.Servers
101 get { return new Dictionary<uint, BaseHttpServer>(m_Servers); } 105 get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
102 } 106 }
103 107
104
105 public static void RegisterHttpConsoleCommands(ICommandConsole console) 108 public static void RegisterHttpConsoleCommands(ICommandConsole console)
106 { 109 {
107 console.Commands.AddCommand( 110 console.Commands.AddCommand(
108 "Debug", false, "debug http", "debug http [<level>]", 111 "Comms", false, "show http-handlers",
109 "Turn on inbound non-poll http request debugging.", 112 "show http-handlers",
110 "If level <= 0, then no extra logging is done.\n" 113 "Show all registered http handlers", HandleShowHttpHandlersCommand);
111 + "If level >= 1, then short warnings are logged when receiving bad input data.\n" 114
112 + "If level >= 2, then long warnings are logged when receiving bad input data.\n" 115 console.Commands.AddCommand(
113 + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n" 116 "Debug", false, "debug http", "debug http <in|out|all> [<level>]",
114 + "If no level is specified then the current level is returned.", 117 "Turn on http request logging.",
118 "If in or all and\n"
119 + " level <= 0 then no extra logging is done.\n"
120 + " level >= 1 then short warnings are logged when receiving bad input data.\n"
121 + " level >= 2 then long warnings are logged when receiving bad input data.\n"
122 + " level >= 3 then short notices about all incoming non-poll HTTP requests are logged.\n"
123 + " level >= 4 then the time taken to fulfill the request is logged.\n"
124 + " level >= 5 then a sample from the beginning of the incoming data is logged.\n"
125 + " level >= 6 then the entire incoming data is logged.\n"
126 + " no level is specified then the current level is returned.\n\n"
127 + "If out or all and\n"
128 + " level >= 3 then short notices about all outgoing requests going through WebUtil are logged.\n"
129 + " level >= 4 then the time taken to fulfill the request is logged.\n",
115 HandleDebugHttpCommand); 130 HandleDebugHttpCommand);
116 } 131 }
117 132
@@ -119,25 +134,120 @@ namespace OpenSim.Framework.Servers
119 /// Turn on some debugging values for OpenSim. 134 /// Turn on some debugging values for OpenSim.
120 /// </summary> 135 /// </summary>
121 /// <param name="args"></param> 136 /// <param name="args"></param>
122 private static void HandleDebugHttpCommand(string module, string[] args) 137 private static void HandleDebugHttpCommand(string module, string[] cmdparams)
123 { 138 {
124 if (args.Length == 3) 139 if (cmdparams.Length < 3)
140 {
141 MainConsole.Instance.Output("Usage: debug http <in|out|all> 0..6");
142 return;
143 }
144
145 bool inReqs = false;
146 bool outReqs = false;
147 bool allReqs = false;
148
149 string subCommand = cmdparams[2];
150
151 if (subCommand.ToLower() == "in")
152 {
153 inReqs = true;
154 }
155 else if (subCommand.ToLower() == "out")
156 {
157 outReqs = true;
158 }
159 else if (subCommand.ToLower() == "all")
160 {
161 allReqs = true;
162 }
163 else
125 { 164 {
165 MainConsole.Instance.Output("You must specify in, out or all");
166 return;
167 }
168
169 if (cmdparams.Length >= 4)
170 {
171 string rawNewDebug = cmdparams[3];
126 int newDebug; 172 int newDebug;
127 if (int.TryParse(args[2], out newDebug)) 173
174 if (!int.TryParse(rawNewDebug, out newDebug))
175 {
176 MainConsole.Instance.OutputFormat("{0} is not a valid debug level", rawNewDebug);
177 return;
178 }
179
180 if (newDebug < 0 || newDebug > 6)
181 {
182 MainConsole.Instance.OutputFormat("{0} is outside the valid debug level range of 0..6", newDebug);
183 return;
184 }
185
186 if (allReqs || inReqs)
128 { 187 {
129 MainServer.DebugLevel = newDebug; 188 MainServer.DebugLevel = newDebug;
130 MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug); 189 MainConsole.Instance.OutputFormat("IN debug level set to {0}", newDebug);
190 }
191
192 if (allReqs || outReqs)
193 {
194 WebUtil.DebugLevel = newDebug;
195 MainConsole.Instance.OutputFormat("OUT debug level set to {0}", newDebug);
131 } 196 }
132 } 197 }
133 else if (args.Length == 2) 198 else
134 { 199 {
135 MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel); 200 if (allReqs || inReqs)
201 MainConsole.Instance.OutputFormat("Current IN debug level is {0}", MainServer.DebugLevel);
202
203 if (allReqs || outReqs)
204 MainConsole.Instance.OutputFormat("Current OUT debug level is {0}", WebUtil.DebugLevel);
136 } 205 }
137 else 206 }
207
208 private static void HandleShowHttpHandlersCommand(string module, string[] args)
209 {
210 if (args.Length != 2)
211 {
212 MainConsole.Instance.Output("Usage: show http-handlers");
213 return;
214 }
215
216 StringBuilder handlers = new StringBuilder();
217
218 lock (m_Servers)
138 { 219 {
139 MainConsole.Instance.Output("Usage: debug http 0..3"); 220 foreach (BaseHttpServer httpServer in m_Servers.Values)
221 {
222 handlers.AppendFormat(
223 "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port);
224
225 handlers.AppendFormat("* XMLRPC:\n");
226 foreach (String s in httpServer.GetXmlRpcHandlerKeys())
227 handlers.AppendFormat("\t{0}\n", s);
228
229 handlers.AppendFormat("* HTTP:\n");
230 List<String> poll = httpServer.GetPollServiceHandlerKeys();
231 foreach (String s in httpServer.GetHTTPHandlerKeys())
232 handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
233
234// handlers.AppendFormat("* Agent:\n");
235// foreach (String s in httpServer.GetAgentHandlerKeys())
236// handlers.AppendFormat("\t{0}\n", s);
237
238 handlers.AppendFormat("* LLSD:\n");
239 foreach (String s in httpServer.GetLLSDHandlerKeys())
240 handlers.AppendFormat("\t{0}\n", s);
241
242 handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count);
243 foreach (String s in httpServer.GetStreamHandlerKeys())
244 handlers.AppendFormat("\t{0}\n", s);
245
246 handlers.Append("\n");
247 }
140 } 248 }
249
250 MainConsole.Instance.Output(handlers.ToString());
141 } 251 }
142 252
143 /// <summary> 253 /// <summary>
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs
index 016a174..bb094ed 100644
--- a/OpenSim/Framework/Servers/VersionInfo.cs
+++ b/OpenSim/Framework/Servers/VersionInfo.cs
@@ -29,7 +29,7 @@ namespace OpenSim
29{ 29{
30 public class VersionInfo 30 public class VersionInfo
31 { 31 {
32 private const string VERSION_NUMBER = "0.7.4CM"; 32 private const string VERSION_NUMBER = "0.7.5CM";
33 private const Flavour VERSION_FLAVOUR = Flavour.Dev; 33 private const Flavour VERSION_FLAVOUR = Flavour.Dev;
34 34
35 public enum Flavour 35 public enum Flavour
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs
index 4d07746..62ecbd1 100644
--- a/OpenSim/Framework/TaskInventoryDictionary.cs
+++ b/OpenSim/Framework/TaskInventoryDictionary.cs
@@ -39,10 +39,12 @@ using OpenMetaverse;
39namespace OpenSim.Framework 39namespace OpenSim.Framework
40{ 40{
41 /// <summary> 41 /// <summary>
42 /// A dictionary for task inventory. 42 /// A dictionary containing task inventory items. Indexed by item UUID.
43 /// </summary> 43 /// </summary>
44 /// <remarks>
44 /// This class is not thread safe. Callers must synchronize on Dictionary methods or Clone() this object before 45 /// This class is not thread safe. Callers must synchronize on Dictionary methods or Clone() this object before
45 /// iterating over it. 46 /// iterating over it.
47 /// </remarks>
46 public class TaskInventoryDictionary : Dictionary<UUID, TaskInventoryItem>, 48 public class TaskInventoryDictionary : Dictionary<UUID, TaskInventoryItem>,
47 ICloneable, IXmlSerializable 49 ICloneable, IXmlSerializable
48 { 50 {
diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs
index fb818ee..574ee56 100644
--- a/OpenSim/Framework/TaskInventoryItem.cs
+++ b/OpenSim/Framework/TaskInventoryItem.cs
@@ -73,9 +73,6 @@ namespace OpenSim.Framework
73 73
74 private bool _ownerChanged = false; 74 private bool _ownerChanged = false;
75 75
76 // This used ONLY during copy. It can't be relied on at other times!
77 private bool _scriptRunning = true;
78
79 public UUID AssetID { 76 public UUID AssetID {
80 get { 77 get {
81 return _assetID; 78 return _assetID;
@@ -353,14 +350,13 @@ namespace OpenSim.Framework
353 } 350 }
354 } 351 }
355 352
356 public bool ScriptRunning { 353 /// <summary>
357 get { 354 /// This used ONLY during copy. It can't be relied on at other times!
358 return _scriptRunning; 355 /// </summary>
359 } 356 /// <remarks>
360 set { 357 /// For true script running status, use IEntityInventory.TryGetScriptInstanceRunning() for now.
361 _scriptRunning = value; 358 /// </remarks>
362 } 359 public bool ScriptRunning { get; set; }
363 }
364 360
365 // See ICloneable 361 // See ICloneable
366 362
@@ -388,6 +384,7 @@ namespace OpenSim.Framework
388 384
389 public TaskInventoryItem() 385 public TaskInventoryItem()
390 { 386 {
387 ScriptRunning = true;
391 CreationDate = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; 388 CreationDate = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
392 } 389 }
393 } 390 }
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 384f716..e76a37b 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -546,6 +546,19 @@ namespace OpenSim.Framework
546 } 546 }
547 547
548 /// <summary> 548 /// <summary>
549 /// Determines whether a point is inside a bounding box.
550 /// </summary>
551 /// <param name='v'></param>
552 /// <param name='min'></param>
553 /// <param name='max'></param>
554 /// <returns></returns>
555 public static bool IsInsideBox(Vector3 v, Vector3 min, Vector3 max)
556 {
557 return v.X >= min.X & v.Y >= min.Y && v.Z >= min.Z
558 && v.X <= max.X && v.Y <= max.Y && v.Z <= max.Z;
559 }
560
561 /// <summary>
549 /// Are the co-ordinates of the new region visible from the old region? 562 /// Are the co-ordinates of the new region visible from the old region?
550 /// </summary> 563 /// </summary>
551 /// <param name="oldx">Old region x-coord</param> 564 /// <param name="oldx">Old region x-coord</param>
@@ -862,6 +875,12 @@ namespace OpenSim.Framework
862 return Math.Min(Math.Max(x, min), max); 875 return Math.Min(Math.Max(x, min), max);
863 } 876 }
864 877
878 public static Vector3 Clip(Vector3 vec, float min, float max)
879 {
880 return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max),
881 Clip(vec.Z, min, max));
882 }
883
865 /// <summary> 884 /// <summary>
866 /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens. 885 /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
867 /// </summary> 886 /// </summary>
@@ -1013,6 +1032,38 @@ namespace OpenSim.Framework
1013 } 1032 }
1014 } 1033 }
1015 1034
1035 /// <summary>
1036 /// Copy data from one stream to another, leaving the read position of both streams at the beginning.
1037 /// </summary>
1038 /// <param name='inputStream'>
1039 /// Input stream. Must be seekable.
1040 /// </param>
1041 /// <exception cref='ArgumentException'>
1042 /// Thrown if the input stream is not seekable.
1043 /// </exception>
1044 public static Stream Copy(Stream inputStream)
1045 {
1046 if (!inputStream.CanSeek)
1047 throw new ArgumentException("Util.Copy(Stream inputStream) must receive an inputStream that can seek");
1048
1049 const int readSize = 256;
1050 byte[] buffer = new byte[readSize];
1051 MemoryStream ms = new MemoryStream();
1052
1053 int count = inputStream.Read(buffer, 0, readSize);
1054
1055 while (count > 0)
1056 {
1057 ms.Write(buffer, 0, count);
1058 count = inputStream.Read(buffer, 0, readSize);
1059 }
1060
1061 ms.Position = 0;
1062 inputStream.Position = 0;
1063
1064 return ms;
1065 }
1066
1016 public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args) 1067 public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args)
1017 { 1068 {
1018 return SendXmlRpcCommand(url, methodName, args); 1069 return SendXmlRpcCommand(url, methodName, args);
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 30a8c28..b85d93d 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -54,9 +54,17 @@ namespace OpenSim.Framework
54 MethodBase.GetCurrentMethod().DeclaringType); 54 MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 /// <summary> 56 /// <summary>
57 /// Control the printing of certain debug messages.
58 /// </summary>
59 /// <remarks>
60 /// If DebugLevel >= 3 then short notices about outgoing HTTP requests are logged.
61 /// </remarks>
62 public static int DebugLevel { get; set; }
63
64 /// <summary>
57 /// Request number for diagnostic purposes. 65 /// Request number for diagnostic purposes.
58 /// </summary> 66 /// </summary>
59 public static int RequestNumber = 0; 67 public static int RequestNumber { get; internal set; }
60 68
61 /// <summary> 69 /// <summary>
62 /// this is the header field used to communicate the local request id 70 /// this is the header field used to communicate the local request id
@@ -146,7 +154,11 @@ namespace OpenSim.Framework
146 private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed) 154 private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
147 { 155 {
148 int reqnum = RequestNumber++; 156 int reqnum = RequestNumber++;
149 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 157
158 if (DebugLevel >= 3)
159 m_log.DebugFormat(
160 "[WEB UTIL]: HTTP OUT {0} ServiceOSD {1} {2} (timeout {3}, compressed {4})",
161 reqnum, method, url, timeout, compressed);
150 162
151 string errorMessage = "unknown error"; 163 string errorMessage = "unknown error";
152 int tickstart = Util.EnvironmentTickCount(); 164 int tickstart = Util.EnvironmentTickCount();
@@ -230,7 +242,7 @@ namespace OpenSim.Framework
230 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 242 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
231 if (tickdiff > LongCallTime) 243 if (tickdiff > LongCallTime)
232 m_log.InfoFormat( 244 m_log.InfoFormat(
233 "[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", 245 "[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
234 reqnum, 246 reqnum,
235 method, 247 method,
236 url, 248 url,
@@ -239,10 +251,14 @@ namespace OpenSim.Framework
239 strBuffer != null 251 strBuffer != null
240 ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) 252 ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
241 : ""); 253 : "");
254 else if (DebugLevel >= 4)
255 m_log.DebugFormat(
256 "[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
257 reqnum, tickdiff, tickdata);
242 } 258 }
243 259
244 m_log.DebugFormat( 260 m_log.DebugFormat(
245 "[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage); 261 "[WEB UTIL]: ServiceOSD request {0} {1} {2} FAILED: {3}", reqnum, url, method, errorMessage);
246 262
247 return ErrorResponseMap(errorMessage); 263 return ErrorResponseMap(errorMessage);
248 } 264 }
@@ -318,7 +334,11 @@ namespace OpenSim.Framework
318 { 334 {
319 int reqnum = RequestNumber++; 335 int reqnum = RequestNumber++;
320 string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; 336 string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
321 // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); 337
338 if (DebugLevel >= 3)
339 m_log.DebugFormat(
340 "[WEB UTIL]: HTTP OUT {0} ServiceForm {1} {2} (timeout {3})",
341 reqnum, method, url, timeout);
322 342
323 string errorMessage = "unknown error"; 343 string errorMessage = "unknown error";
324 int tickstart = Util.EnvironmentTickCount(); 344 int tickstart = Util.EnvironmentTickCount();
@@ -381,7 +401,7 @@ namespace OpenSim.Framework
381 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 401 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
382 if (tickdiff > LongCallTime) 402 if (tickdiff > LongCallTime)
383 m_log.InfoFormat( 403 m_log.InfoFormat(
384 "[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", 404 "[WEB UTIL]: Slow ServiceForm request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
385 reqnum, 405 reqnum,
386 method, 406 method,
387 url, 407 url,
@@ -390,9 +410,13 @@ namespace OpenSim.Framework
390 queryString != null 410 queryString != null
391 ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString 411 ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
392 : ""); 412 : "");
413 else if (DebugLevel >= 4)
414 m_log.DebugFormat(
415 "[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
416 reqnum, tickdiff, tickdata);
393 } 417 }
394 418
395 m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage); 419 m_log.WarnFormat("[WEB UTIL]: ServiceForm request {0} {1} {2} failed: {2}", reqnum, method, url, errorMessage);
396 420
397 return ErrorResponseMap(errorMessage); 421 return ErrorResponseMap(errorMessage);
398 } 422 }
@@ -644,7 +668,6 @@ namespace OpenSim.Framework
644 /// <returns></returns> 668 /// <returns></returns>
645 public static string[] GetPreferredImageTypes(string accept) 669 public static string[] GetPreferredImageTypes(string accept)
646 { 670 {
647
648 if (accept == null || accept == string.Empty) 671 if (accept == null || accept == string.Empty)
649 return new string[0]; 672 return new string[0];
650 673
@@ -703,14 +726,16 @@ namespace OpenSim.Framework
703 int maxConnections) 726 int maxConnections)
704 { 727 {
705 int reqnum = WebUtil.RequestNumber++; 728 int reqnum = WebUtil.RequestNumber++;
706 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 729
730 if (WebUtil.DebugLevel >= 3)
731 m_log.DebugFormat(
732 "[WEB UTIL]: HTTP OUT {0} AsynchronousRequestObject {1} {2}",
733 reqnum, verb, requestUrl);
707 734
708 int tickstart = Util.EnvironmentTickCount(); 735 int tickstart = Util.EnvironmentTickCount();
709// int tickdata = 0; 736// int tickdata = 0;
710 int tickdiff = 0; 737 int tickdiff = 0;
711 738
712// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
713
714 Type type = typeof(TRequest); 739 Type type = typeof(TRequest);
715 740
716 WebRequest request = WebRequest.Create(requestUrl); 741 WebRequest request = WebRequest.Create(requestUrl);
@@ -868,7 +893,7 @@ namespace OpenSim.Framework
868 } 893 }
869 894
870 m_log.InfoFormat( 895 m_log.InfoFormat(
871 "[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", 896 "[ASYNC REQUEST]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
872 reqnum, 897 reqnum,
873 verb, 898 verb,
874 requestUrl, 899 requestUrl,
@@ -883,6 +908,12 @@ namespace OpenSim.Framework
883 requestUrl, 908 requestUrl,
884 tickdiff); 909 tickdiff);
885 } 910 }
911 else if (WebUtil.DebugLevel >= 4)
912 {
913 m_log.DebugFormat(
914 "[WEB UTIL]: HTTP OUT {0} took {1}ms",
915 reqnum, tickdiff);
916 }
886 } 917 }
887 } 918 }
888 919
@@ -903,7 +934,11 @@ namespace OpenSim.Framework
903 public static string MakeRequest(string verb, string requestUrl, string obj) 934 public static string MakeRequest(string verb, string requestUrl, string obj)
904 { 935 {
905 int reqnum = WebUtil.RequestNumber++; 936 int reqnum = WebUtil.RequestNumber++;
906 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 937
938 if (WebUtil.DebugLevel >= 3)
939 m_log.DebugFormat(
940 "[WEB UTIL]: HTTP OUT {0} SynchronousRestForms {1} {2}",
941 reqnum, verb, requestUrl);
907 942
908 int tickstart = Util.EnvironmentTickCount(); 943 int tickstart = Util.EnvironmentTickCount();
909 int tickdata = 0; 944 int tickdata = 0;
@@ -990,7 +1025,7 @@ namespace OpenSim.Framework
990 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 1025 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
991 if (tickdiff > WebUtil.LongCallTime) 1026 if (tickdiff > WebUtil.LongCallTime)
992 m_log.InfoFormat( 1027 m_log.InfoFormat(
993 "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms {4}ms writing {5}", 1028 "[FORMS]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
994 reqnum, 1029 reqnum,
995 verb, 1030 verb,
996 requestUrl, 1031 requestUrl,
@@ -998,6 +1033,10 @@ namespace OpenSim.Framework
998 tickset, 1033 tickset,
999 tickdata, 1034 tickdata,
1000 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); 1035 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
1036 else if (WebUtil.DebugLevel >= 4)
1037 m_log.DebugFormat(
1038 "[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
1039 reqnum, tickdiff, tickdata);
1001 1040
1002 return respstring; 1041 return respstring;
1003 } 1042 }
@@ -1032,7 +1071,11 @@ namespace OpenSim.Framework
1032 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections) 1071 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections)
1033 { 1072 {
1034 int reqnum = WebUtil.RequestNumber++; 1073 int reqnum = WebUtil.RequestNumber++;
1035 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 1074
1075 if (WebUtil.DebugLevel >= 3)
1076 m_log.DebugFormat(
1077 "[WEB UTIL]: HTTP OUT {0} SynchronousRestObject {1} {2}",
1078 reqnum, verb, requestUrl);
1036 1079
1037 int tickstart = Util.EnvironmentTickCount(); 1080 int tickstart = Util.EnvironmentTickCount();
1038 int tickdata = 0; 1081 int tickdata = 0;
@@ -1151,7 +1194,7 @@ namespace OpenSim.Framework
1151 } 1194 }
1152 1195
1153 m_log.InfoFormat( 1196 m_log.InfoFormat(
1154 "[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", 1197 "[SynchronousRestObjectRequester]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
1155 reqnum, 1198 reqnum,
1156 verb, 1199 verb,
1157 requestUrl, 1200 requestUrl,
@@ -1159,6 +1202,12 @@ namespace OpenSim.Framework
1159 tickdata, 1202 tickdata,
1160 originalRequest); 1203 originalRequest);
1161 } 1204 }
1205 else if (WebUtil.DebugLevel >= 4)
1206 {
1207 m_log.DebugFormat(
1208 "[WEB UTIL]: HTTP OUT {0} took {1}ms, {2}ms writing",
1209 reqnum, tickdiff, tickdata);
1210 }
1162 1211
1163 return deserial; 1212 return deserial;
1164 } 1213 }
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 41d17c5..9f22fb4 100644
--- a/OpenSim/Framework/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -31,10 +31,10 @@ using System.Reflection;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenMetaverse.Packets; 32using OpenMetaverse.Packets;
33using log4net; 33using log4net;
34using OpenSim.Framework.Monitoring;
34 35
35namespace OpenSim.Framework 36namespace OpenSim.Region.ClientStack.LindenUDP
36{ 37{
37
38 public sealed class PacketPool 38 public sealed class PacketPool
39 { 39 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -44,14 +44,32 @@ namespace OpenSim.Framework
44 private bool packetPoolEnabled = true; 44 private bool packetPoolEnabled = true;
45 private bool dataBlockPoolEnabled = true; 45 private bool dataBlockPoolEnabled = true;
46 46
47 private PercentageStat m_packetsReusedStat = new PercentageStat(
48 "PacketsReused",
49 "Packets reused",
50 "Number of packets reused out of all requests to the packet pool",
51 "clientstack",
52 "packetpool",
53 StatType.Push,
54 null,
55 StatVerbosity.Debug);
56
57 private PercentageStat m_blocksReusedStat = new PercentageStat(
58 "PacketDataBlocksReused",
59 "Packet data blocks reused",
60 "Number of data blocks reused out of all requests to the packet pool",
61 "clientstack",
62 "packetpool",
63 StatType.Push,
64 null,
65 StatVerbosity.Debug);
66
67 /// <summary>
68 /// Pool of packets available for reuse.
69 /// </summary>
47 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>(); 70 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
48 71
49 private static Dictionary<Type, Stack<Object>> DataBlocks = 72 private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>();
50 new Dictionary<Type, Stack<Object>>();
51
52 static PacketPool()
53 {
54 }
55 73
56 public static PacketPool Instance 74 public static PacketPool Instance
57 { 75 {
@@ -70,8 +88,45 @@ namespace OpenSim.Framework
70 get { return dataBlockPoolEnabled; } 88 get { return dataBlockPoolEnabled; }
71 } 89 }
72 90
91 private PacketPool()
92 {
93 StatsManager.RegisterStat(m_packetsReusedStat);
94 StatsManager.RegisterStat(m_blocksReusedStat);
95
96 StatsManager.RegisterStat(
97 new Stat(
98 "PacketsPoolCount",
99 "Objects within the packet pool",
100 "The number of objects currently stored within the packet pool",
101 "",
102 "clientstack",
103 "packetpool",
104 StatType.Pull,
105 stat => { lock (pool) { stat.Value = pool.Count; } },
106 StatVerbosity.Debug));
107
108 StatsManager.RegisterStat(
109 new Stat(
110 "PacketDataBlocksPoolCount",
111 "Objects within the packet data block pool",
112 "The number of objects currently stored within the packet data block pool",
113 "",
114 "clientstack",
115 "packetpool",
116 StatType.Pull,
117 stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
118 StatVerbosity.Debug));
119 }
120
121 /// <summary>
122 /// Gets a packet of the given type.
123 /// </summary>
124 /// <param name='type'></param>
125 /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns>
73 public Packet GetPacket(PacketType type) 126 public Packet GetPacket(PacketType type)
74 { 127 {
128 m_packetsReusedStat.Consequent++;
129
75 Packet packet; 130 Packet packet;
76 131
77 if (!packetPoolEnabled) 132 if (!packetPoolEnabled)
@@ -81,13 +136,19 @@ namespace OpenSim.Framework
81 { 136 {
82 if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0) 137 if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
83 { 138 {
139// m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type);
140
84 // Creating a new packet if we cannot reuse an old package 141 // Creating a new packet if we cannot reuse an old package
85 packet = Packet.BuildPacket(type); 142 packet = Packet.BuildPacket(type);
86 } 143 }
87 else 144 else
88 { 145 {
146// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
147
89 // Recycle old packages 148 // Recycle old packages
90 packet = (pool[type]).Pop(); 149 m_packetsReusedStat.Antecedent++;
150
151 packet = pool[type].Pop();
91 } 152 }
92 } 153 }
93 154
@@ -136,7 +197,7 @@ namespace OpenSim.Framework
136 { 197 {
137 PacketType type = GetType(bytes); 198 PacketType type = GetType(bytes);
138 199
139 Array.Clear(zeroBuffer, 0, zeroBuffer.Length); 200// Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
140 201
141 int i = 0; 202 int i = 0;
142 Packet packet = GetPacket(type); 203 Packet packet = GetPacket(type);
@@ -183,6 +244,7 @@ namespace OpenSim.Framework
183 switch (packet.Type) 244 switch (packet.Type)
184 { 245 {
185 // List pooling packets here 246 // List pooling packets here
247 case PacketType.AgentUpdate:
186 case PacketType.PacketAck: 248 case PacketType.PacketAck:
187 case PacketType.ObjectUpdate: 249 case PacketType.ObjectUpdate:
188 case PacketType.ImprovedTerseObjectUpdate: 250 case PacketType.ImprovedTerseObjectUpdate:
@@ -197,7 +259,9 @@ namespace OpenSim.Framework
197 259
198 if ((pool[type]).Count < 50) 260 if ((pool[type]).Count < 50)
199 { 261 {
200 (pool[type]).Push(packet); 262// m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
263
264 pool[type].Push(packet);
201 } 265 }
202 } 266 }
203 break; 267 break;
@@ -209,16 +273,21 @@ namespace OpenSim.Framework
209 } 273 }
210 } 274 }
211 275
212 public static T GetDataBlock<T>() where T: new() 276 public T GetDataBlock<T>() where T: new()
213 { 277 {
214 lock (DataBlocks) 278 lock (DataBlocks)
215 { 279 {
280 m_blocksReusedStat.Consequent++;
281
216 Stack<Object> s; 282 Stack<Object> s;
217 283
218 if (DataBlocks.TryGetValue(typeof(T), out s)) 284 if (DataBlocks.TryGetValue(typeof(T), out s))
219 { 285 {
220 if (s.Count > 0) 286 if (s.Count > 0)
287 {
288 m_blocksReusedStat.Antecedent++;
221 return (T)s.Pop(); 289 return (T)s.Pop();
290 }
222 } 291 }
223 else 292 else
224 { 293 {
@@ -229,7 +298,7 @@ namespace OpenSim.Framework
229 } 298 }
230 } 299 }
231 300
232 public static void ReturnDataBlock<T>(T block) where T: new() 301 public void ReturnDataBlock<T>(T block) where T: new()
233 { 302 {
234 if (block == null) 303 if (block == null)
235 return; 304 return;
@@ -244,4 +313,4 @@ namespace OpenSim.Framework
244 } 313 }
245 } 314 }
246 } 315 }
247} 316} \ No newline at end of file