diff options
Diffstat (limited to 'OpenSim')
37 files changed, 961 insertions, 957 deletions
diff --git a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs index 6ba022c..6731923 100644 --- a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs +++ b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs | |||
@@ -46,7 +46,7 @@ namespace OpenSim.OfflineIM | |||
46 | { | 46 | { |
47 | public class OfflineIMService : OfflineIMServiceBase, IOfflineIMService | 47 | public class OfflineIMService : OfflineIMServiceBase, IOfflineIMService |
48 | { | 48 | { |
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | private const int MAX_IM = 25; | 50 | private const int MAX_IM = 25; |
51 | 51 | ||
52 | private XmlSerializer m_serializer; | 52 | private XmlSerializer m_serializer; |
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs index c0ca1e1..2c91328 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs | |||
@@ -46,7 +46,7 @@ namespace OpenSim.Capabilities.Handlers | |||
46 | { | 46 | { |
47 | public class FetchInventory2Handler | 47 | public class FetchInventory2Handler |
48 | { | 48 | { |
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | 50 | ||
51 | private IInventoryService m_inventoryService; | 51 | private IInventoryService m_inventoryService; |
52 | 52 | ||
@@ -121,4 +121,4 @@ namespace OpenSim.Capabilities.Handlers | |||
121 | return llsdItem; | 121 | return llsdItem; |
122 | } | 122 | } |
123 | } | 123 | } |
124 | } | 124 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs index be1d02b..20495f6 100644 --- a/OpenSim/Framework/Monitoring/BaseStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -45,16 +45,16 @@ namespace OpenSim.Framework.Monitoring | |||
45 | sb.Append(Environment.NewLine); | 45 | sb.Append(Environment.NewLine); |
46 | 46 | ||
47 | sb.AppendFormat( | 47 | sb.AppendFormat( |
48 | "Allocated to OpenSim objects: {0} MB\n", | 48 | "Heap allocated to OpenSim : {0} MB\n", |
49 | Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)); | 49 | Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)); |
50 | 50 | ||
51 | sb.AppendFormat( | 51 | sb.AppendFormat( |
52 | "OpenSim last object memory churn : {0} MB/s\n", | 52 | "Last heap allocation rate : {0} MB/s\n", |
53 | Math.Round((MemoryWatchdog.LastMemoryChurn * 1000) / 1024.0 / 1024, 3)); | 53 | Math.Round((MemoryWatchdog.LastHeapAllocationRate * 1000) / 1024.0 / 1024, 3)); |
54 | 54 | ||
55 | sb.AppendFormat( | 55 | sb.AppendFormat( |
56 | "OpenSim average object memory churn : {0} MB/s\n", | 56 | "Average heap allocation rate: {0} MB/s\n", |
57 | Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3)); | 57 | Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3)); |
58 | 58 | ||
59 | sb.AppendFormat( | 59 | sb.AppendFormat( |
60 | "Process memory : {0} MB\n", | 60 | "Process memory : {0} MB\n", |
diff --git a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs index c6010cd..c474622 100644 --- a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs +++ b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs | |||
@@ -60,17 +60,17 @@ namespace OpenSim.Framework.Monitoring | |||
60 | private static bool m_enabled; | 60 | private static bool m_enabled; |
61 | 61 | ||
62 | /// <summary> | 62 | /// <summary> |
63 | /// Last memory churn in bytes per millisecond. | 63 | /// Average heap allocation rate in bytes per millisecond. |
64 | /// </summary> | 64 | /// </summary> |
65 | public static double AverageMemoryChurn | 65 | public static double AverageHeapAllocationRate |
66 | { | 66 | { |
67 | get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; } | 67 | get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; } |
68 | } | 68 | } |
69 | 69 | ||
70 | /// <summary> | 70 | /// <summary> |
71 | /// Average memory churn in bytes per millisecond. | 71 | /// Last heap allocation in bytes |
72 | /// </summary> | 72 | /// </summary> |
73 | public static double LastMemoryChurn | 73 | public static double LastHeapAllocationRate |
74 | { | 74 | { |
75 | get { if (m_samples.Count > 0) return m_samples.Last(); else return 0; } | 75 | get { if (m_samples.Count > 0) return m_samples.Last(); else return 0; } |
76 | } | 76 | } |
diff --git a/OpenSim/Framework/Monitoring/ServerStatsCollector.cs b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs new file mode 100644 index 0000000..ac0f0bc --- /dev/null +++ b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs | |||
@@ -0,0 +1,349 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Diagnostics; | ||
31 | using System.Linq; | ||
32 | using System.Net.NetworkInformation; | ||
33 | using System.Text; | ||
34 | using System.Threading; | ||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse.StructuredData; | ||
38 | using OpenSim.Framework; | ||
39 | |||
40 | namespace OpenSim.Framework.Monitoring | ||
41 | { | ||
42 | public class ServerStatsCollector | ||
43 | { | ||
44 | private readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
45 | private readonly string LogHeader = "[SERVER STATS]"; | ||
46 | |||
47 | public bool Enabled = false; | ||
48 | private static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>(); | ||
49 | |||
50 | public readonly string CategoryServer = "server"; | ||
51 | |||
52 | public readonly string ContainerThreadpool = "threadpool"; | ||
53 | public readonly string ContainerProcessor = "processor"; | ||
54 | public readonly string ContainerMemory = "memory"; | ||
55 | public readonly string ContainerNetwork = "network"; | ||
56 | public readonly string ContainerProcess = "process"; | ||
57 | |||
58 | public string NetworkInterfaceTypes = "Ethernet"; | ||
59 | |||
60 | readonly int performanceCounterSampleInterval = 500; | ||
61 | // int lastperformanceCounterSampleTime = 0; | ||
62 | |||
63 | private class PerfCounterControl | ||
64 | { | ||
65 | public PerformanceCounter perfCounter; | ||
66 | public int lastFetch; | ||
67 | public string name; | ||
68 | public PerfCounterControl(PerformanceCounter pPc) | ||
69 | : this(pPc, String.Empty) | ||
70 | { | ||
71 | } | ||
72 | public PerfCounterControl(PerformanceCounter pPc, string pName) | ||
73 | { | ||
74 | perfCounter = pPc; | ||
75 | lastFetch = 0; | ||
76 | name = pName; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | PerfCounterControl processorPercentPerfCounter = null; | ||
81 | |||
82 | // IRegionModuleBase.Initialize | ||
83 | public void Initialise(IConfigSource source) | ||
84 | { | ||
85 | IConfig cfg = source.Configs["Monitoring"]; | ||
86 | |||
87 | if (cfg != null) | ||
88 | Enabled = cfg.GetBoolean("ServerStatsEnabled", true); | ||
89 | |||
90 | if (Enabled) | ||
91 | { | ||
92 | NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet"); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | public void Start() | ||
97 | { | ||
98 | if (RegisteredStats.Count == 0) | ||
99 | RegisterServerStats(); | ||
100 | } | ||
101 | |||
102 | public void Close() | ||
103 | { | ||
104 | if (RegisteredStats.Count > 0) | ||
105 | { | ||
106 | foreach (Stat stat in RegisteredStats.Values) | ||
107 | { | ||
108 | StatsManager.DeregisterStat(stat); | ||
109 | stat.Dispose(); | ||
110 | } | ||
111 | RegisteredStats.Clear(); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action<Stat> act) | ||
116 | { | ||
117 | MakeStat(pName, pDesc, pUnit, pContainer, act, MeasuresOfInterest.None); | ||
118 | } | ||
119 | |||
120 | private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action<Stat> act, MeasuresOfInterest moi) | ||
121 | { | ||
122 | string desc = pDesc; | ||
123 | if (desc == null) | ||
124 | desc = pName; | ||
125 | Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, moi, act, StatVerbosity.Debug); | ||
126 | StatsManager.RegisterStat(stat); | ||
127 | RegisteredStats.Add(pName, stat); | ||
128 | } | ||
129 | |||
130 | public void RegisterServerStats() | ||
131 | { | ||
132 | // lastperformanceCounterSampleTime = Util.EnvironmentTickCount(); | ||
133 | PerformanceCounter tempPC; | ||
134 | Stat tempStat; | ||
135 | string tempName; | ||
136 | |||
137 | try | ||
138 | { | ||
139 | tempName = "CPUPercent"; | ||
140 | tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total"); | ||
141 | processorPercentPerfCounter = new PerfCounterControl(tempPC); | ||
142 | // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy. | ||
143 | tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor, | ||
144 | StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); }, | ||
145 | StatVerbosity.Info); | ||
146 | StatsManager.RegisterStat(tempStat); | ||
147 | RegisteredStats.Add(tempName, tempStat); | ||
148 | |||
149 | MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor, | ||
150 | (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; }); | ||
151 | |||
152 | MakeStat("UserProcessorTime", null, "sec", ContainerProcessor, | ||
153 | (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; }); | ||
154 | |||
155 | MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor, | ||
156 | (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; }); | ||
157 | |||
158 | MakeStat("Threads", null, "threads", ContainerProcessor, | ||
159 | (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; }); | ||
160 | } | ||
161 | catch (Exception e) | ||
162 | { | ||
163 | m_log.ErrorFormat("{0} Exception creating 'Process': {1}", LogHeader, e); | ||
164 | } | ||
165 | |||
166 | MakeStat("BuiltinThreadpoolWorkerThreadsAvailable", null, "threads", ContainerThreadpool, | ||
167 | s => | ||
168 | { | ||
169 | int workerThreads, iocpThreads; | ||
170 | ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); | ||
171 | s.Value = workerThreads; | ||
172 | }); | ||
173 | |||
174 | MakeStat("BuiltinThreadpoolIOCPThreadsAvailable", null, "threads", ContainerThreadpool, | ||
175 | s => | ||
176 | { | ||
177 | int workerThreads, iocpThreads; | ||
178 | ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); | ||
179 | s.Value = iocpThreads; | ||
180 | }); | ||
181 | |||
182 | if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool && Util.GetSmartThreadPoolInfo() != null) | ||
183 | { | ||
184 | MakeStat("STPMaxThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MaxThreads); | ||
185 | MakeStat("STPMinThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MinThreads); | ||
186 | MakeStat("STPConcurrency", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MaxConcurrentWorkItems); | ||
187 | MakeStat("STPActiveThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().ActiveThreads); | ||
188 | MakeStat("STPInUseThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().InUseThreads); | ||
189 | MakeStat("STPWorkItemsWaiting", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().WaitingCallbacks); | ||
190 | } | ||
191 | |||
192 | MakeStat( | ||
193 | "HTTPRequestsMade", | ||
194 | "Number of outbound HTTP requests made", | ||
195 | "requests", | ||
196 | ContainerNetwork, | ||
197 | s => s.Value = WebUtil.RequestNumber, | ||
198 | MeasuresOfInterest.AverageChangeOverTime); | ||
199 | |||
200 | try | ||
201 | { | ||
202 | List<string> okInterfaceTypes = new List<string>(NetworkInterfaceTypes.Split(',')); | ||
203 | |||
204 | IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces(); | ||
205 | foreach (NetworkInterface nic in nics) | ||
206 | { | ||
207 | if (nic.OperationalStatus != OperationalStatus.Up) | ||
208 | continue; | ||
209 | |||
210 | string nicInterfaceType = nic.NetworkInterfaceType.ToString(); | ||
211 | if (!okInterfaceTypes.Contains(nicInterfaceType)) | ||
212 | { | ||
213 | m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.", | ||
214 | LogHeader, nic.Name, nicInterfaceType); | ||
215 | m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}", | ||
216 | LogHeader, NetworkInterfaceTypes); | ||
217 | continue; | ||
218 | } | ||
219 | |||
220 | if (nic.Supports(NetworkInterfaceComponent.IPv4)) | ||
221 | { | ||
222 | IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics(); | ||
223 | if (nicStats != null) | ||
224 | { | ||
225 | MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork, | ||
226 | (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }); | ||
227 | MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork, | ||
228 | (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }); | ||
229 | MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork, | ||
230 | (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }); | ||
231 | } | ||
232 | } | ||
233 | // TODO: add IPv6 (it may actually happen someday) | ||
234 | } | ||
235 | } | ||
236 | catch (Exception e) | ||
237 | { | ||
238 | m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e); | ||
239 | } | ||
240 | |||
241 | MakeStat("ProcessMemory", null, "MB", ContainerMemory, | ||
242 | (s) => { s.Value = Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d, 3); }); | ||
243 | MakeStat("HeapMemory", null, "MB", ContainerMemory, | ||
244 | (s) => { s.Value = Math.Round(GC.GetTotalMemory(false) / 1024d / 1024d, 3); }); | ||
245 | MakeStat("LastHeapAllocationRate", null, "MB/sec", ContainerMemory, | ||
246 | (s) => { s.Value = Math.Round(MemoryWatchdog.LastHeapAllocationRate * 1000d / 1024d / 1024d, 3); }); | ||
247 | MakeStat("AverageHeapAllocationRate", null, "MB/sec", ContainerMemory, | ||
248 | (s) => { s.Value = Math.Round(MemoryWatchdog.AverageHeapAllocationRate * 1000d / 1024d / 1024d, 3); }); | ||
249 | } | ||
250 | |||
251 | // Notes on performance counters: | ||
252 | // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx | ||
253 | // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c | ||
254 | // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters | ||
255 | private delegate double PerfCounterNextValue(); | ||
256 | private void GetNextValue(Stat stat, PerfCounterControl perfControl) | ||
257 | { | ||
258 | GetNextValue(stat, perfControl, 1.0); | ||
259 | } | ||
260 | private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor) | ||
261 | { | ||
262 | if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval) | ||
263 | { | ||
264 | if (perfControl != null && perfControl.perfCounter != null) | ||
265 | { | ||
266 | try | ||
267 | { | ||
268 | // Kludge for factor to run double duty. If -1, subtract the value from one | ||
269 | if (factor == -1) | ||
270 | stat.Value = 1 - perfControl.perfCounter.NextValue(); | ||
271 | else | ||
272 | stat.Value = perfControl.perfCounter.NextValue() / factor; | ||
273 | } | ||
274 | catch (Exception e) | ||
275 | { | ||
276 | m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e); | ||
277 | } | ||
278 | perfControl.lastFetch = Util.EnvironmentTickCount(); | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | |||
283 | // Lookup the nic that goes with this stat and set the value by using a fetch action. | ||
284 | // Not sure about closure with delegates inside delegates. | ||
285 | private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat); | ||
286 | private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor) | ||
287 | { | ||
288 | // Get the one nic that has the name of this stat | ||
289 | IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces().Where( | ||
290 | (network) => network.Name == stat.Description); | ||
291 | try | ||
292 | { | ||
293 | foreach (NetworkInterface nic in nics) | ||
294 | { | ||
295 | IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics(); | ||
296 | if (intrStats != null) | ||
297 | { | ||
298 | double newVal = Math.Round(getter(intrStats) / factor, 3); | ||
299 | stat.Value = newVal; | ||
300 | } | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | catch | ||
305 | { | ||
306 | // There are times interfaces go away so we just won't update the stat for this | ||
307 | m_log.ErrorFormat("{0} Exception fetching stat on interface '{1}'", LogHeader, stat.Description); | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | |||
312 | public class ServerStatsAggregator : Stat | ||
313 | { | ||
314 | public ServerStatsAggregator( | ||
315 | string shortName, | ||
316 | string name, | ||
317 | string description, | ||
318 | string unitName, | ||
319 | string category, | ||
320 | string container | ||
321 | ) | ||
322 | : base( | ||
323 | shortName, | ||
324 | name, | ||
325 | description, | ||
326 | unitName, | ||
327 | category, | ||
328 | container, | ||
329 | StatType.Push, | ||
330 | MeasuresOfInterest.None, | ||
331 | null, | ||
332 | StatVerbosity.Info) | ||
333 | { | ||
334 | } | ||
335 | public override string ToConsoleString() | ||
336 | { | ||
337 | StringBuilder sb = new StringBuilder(); | ||
338 | |||
339 | return sb.ToString(); | ||
340 | } | ||
341 | |||
342 | public override OSDMap ToOSDMap() | ||
343 | { | ||
344 | OSDMap ret = new OSDMap(); | ||
345 | |||
346 | return ret; | ||
347 | } | ||
348 | } | ||
349 | } | ||
diff --git a/OpenSim/Framework/Monitoring/Stats/Stat.cs b/OpenSim/Framework/Monitoring/Stats/Stat.cs index 2e7665f..c57ee0c 100644 --- a/OpenSim/Framework/Monitoring/Stats/Stat.cs +++ b/OpenSim/Framework/Monitoring/Stats/Stat.cs | |||
@@ -27,8 +27,10 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
31 | using System.Reflection; | ||
30 | using System.Text; | 32 | using System.Text; |
31 | 33 | using log4net; | |
32 | using OpenMetaverse.StructuredData; | 34 | using OpenMetaverse.StructuredData; |
33 | 35 | ||
34 | namespace OpenSim.Framework.Monitoring | 36 | namespace OpenSim.Framework.Monitoring |
@@ -38,6 +40,10 @@ namespace OpenSim.Framework.Monitoring | |||
38 | /// </summary> | 40 | /// </summary> |
39 | public class Stat : IDisposable | 41 | public class Stat : IDisposable |
40 | { | 42 | { |
43 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | public static readonly char[] DisallowedShortNameCharacters = { '.' }; | ||
46 | |||
41 | /// <summary> | 47 | /// <summary> |
42 | /// Category of this stat (e.g. cache, scene, etc). | 48 | /// Category of this stat (e.g. cache, scene, etc). |
43 | /// </summary> | 49 | /// </summary> |
@@ -95,7 +101,7 @@ namespace OpenSim.Framework.Monitoring | |||
95 | /// <remarks> | 101 | /// <remarks> |
96 | /// Will be null if no measures of interest require samples. | 102 | /// Will be null if no measures of interest require samples. |
97 | /// </remarks> | 103 | /// </remarks> |
98 | private static Queue<double> m_samples; | 104 | private Queue<double> m_samples; |
99 | 105 | ||
100 | /// <summary> | 106 | /// <summary> |
101 | /// Maximum number of statistical samples. | 107 | /// Maximum number of statistical samples. |
@@ -162,6 +168,12 @@ namespace OpenSim.Framework.Monitoring | |||
162 | throw new Exception( | 168 | throw new Exception( |
163 | string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category)); | 169 | string.Format("Stat cannot be in category '{0}' since this is reserved for a subcommand", category)); |
164 | 170 | ||
171 | foreach (char c in DisallowedShortNameCharacters) | ||
172 | { | ||
173 | if (shortName.IndexOf(c) != -1) | ||
174 | throw new Exception(string.Format("Stat name {0} cannot contain character {1}", shortName, c)); | ||
175 | } | ||
176 | |||
165 | ShortName = shortName; | 177 | ShortName = shortName; |
166 | Name = name; | 178 | Name = name; |
167 | Description = description; | 179 | Description = description; |
@@ -204,6 +216,8 @@ namespace OpenSim.Framework.Monitoring | |||
204 | if (m_samples.Count >= m_maxSamples) | 216 | if (m_samples.Count >= m_maxSamples) |
205 | m_samples.Dequeue(); | 217 | m_samples.Dequeue(); |
206 | 218 | ||
219 | // m_log.DebugFormat("[STAT]: Recording value {0} for {1}", newValue, Name); | ||
220 | |||
207 | m_samples.Enqueue(newValue); | 221 | m_samples.Enqueue(newValue); |
208 | } | 222 | } |
209 | } | 223 | } |
@@ -242,6 +256,10 @@ namespace OpenSim.Framework.Monitoring | |||
242 | 256 | ||
243 | lock (m_samples) | 257 | lock (m_samples) |
244 | { | 258 | { |
259 | // m_log.DebugFormat( | ||
260 | // "[STAT]: Samples for {0} are {1}", | ||
261 | // Name, string.Join(",", m_samples.Select(s => s.ToString()).ToArray())); | ||
262 | |||
245 | foreach (double s in m_samples) | 263 | foreach (double s in m_samples) |
246 | { | 264 | { |
247 | if (lastSample != null) | 265 | if (lastSample != null) |
@@ -253,7 +271,7 @@ namespace OpenSim.Framework.Monitoring | |||
253 | 271 | ||
254 | int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1; | 272 | int divisor = m_samples.Count <= 1 ? 1 : m_samples.Count - 1; |
255 | 273 | ||
256 | sb.AppendFormat(", {0:0.##}{1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName); | 274 | sb.AppendFormat(", {0:0.##} {1}/s", totalChange / divisor / (Watchdog.WATCHDOG_INTERVAL_MS / 1000), UnitName); |
257 | } | 275 | } |
258 | } | 276 | } |
259 | } | 277 | } |
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 24db6d4..12d3a75 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
30 | using System.Text; | 31 | using System.Text; |
31 | 32 | ||
32 | namespace OpenSim.Framework.Monitoring | 33 | namespace OpenSim.Framework.Monitoring |
@@ -54,13 +55,13 @@ namespace OpenSim.Framework.Monitoring | |||
54 | public static SortedDictionary<string, SortedDictionary<string, SortedDictionary<string, Stat>>> RegisteredStats | 55 | public static SortedDictionary<string, SortedDictionary<string, SortedDictionary<string, Stat>>> RegisteredStats |
55 | = new SortedDictionary<string, SortedDictionary<string, SortedDictionary<string, Stat>>>(); | 56 | = new SortedDictionary<string, SortedDictionary<string, SortedDictionary<string, Stat>>>(); |
56 | 57 | ||
57 | private static AssetStatsCollector assetStats; | 58 | // private static AssetStatsCollector assetStats; |
58 | private static UserStatsCollector userStats; | 59 | // private static UserStatsCollector userStats; |
59 | private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); | 60 | // private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); |
60 | 61 | ||
61 | public static AssetStatsCollector AssetStats { get { return assetStats; } } | 62 | // public static AssetStatsCollector AssetStats { get { return assetStats; } } |
62 | public static UserStatsCollector UserStats { get { return userStats; } } | 63 | // public static UserStatsCollector UserStats { get { return userStats; } } |
63 | public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } } | 64 | public static SimExtraStatsCollector SimExtraStats { get; set; } |
64 | 65 | ||
65 | public static void RegisterConsoleCommands(ICommandConsole console) | 66 | public static void RegisterConsoleCommands(ICommandConsole console) |
66 | { | 67 | { |
@@ -68,12 +69,14 @@ namespace OpenSim.Framework.Monitoring | |||
68 | "General", | 69 | "General", |
69 | false, | 70 | false, |
70 | "show stats", | 71 | "show stats", |
71 | "show stats [list|all|<category>]", | 72 | "show stats [list|all|(<category>[.<container>])+", |
72 | "Show statistical information for this server", | 73 | "Show statistical information for this server", |
73 | "If no final argument is specified then legacy statistics information is currently shown.\n" | 74 | "If no final argument is specified then legacy statistics information is currently shown.\n" |
74 | + "If list is specified then statistic categories are shown.\n" | 75 | + "'list' argument will show statistic categories.\n" |
75 | + "If all is specified then all registered statistics are shown.\n" | 76 | + "'all' will show all statistics.\n" |
76 | + "If a category name is specified then only statistics from that category are shown.\n" | 77 | + "A <category> name will show statistics from that category.\n" |
78 | + "A <category>.<container> name will show statistics from that category in that container.\n" | ||
79 | + "More than one name can be given separated by spaces.\n" | ||
77 | + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS", | 80 | + "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS", |
78 | HandleShowStatsCommand); | 81 | HandleShowStatsCommand); |
79 | } | 82 | } |
@@ -84,43 +87,47 @@ namespace OpenSim.Framework.Monitoring | |||
84 | 87 | ||
85 | if (cmd.Length > 2) | 88 | if (cmd.Length > 2) |
86 | { | 89 | { |
87 | var categoryName = cmd[2]; | 90 | foreach (string name in cmd.Skip(2)) |
88 | var containerName = cmd.Length > 3 ? cmd[3] : String.Empty; | ||
89 | |||
90 | if (categoryName == AllSubCommand) | ||
91 | { | 91 | { |
92 | foreach (var category in RegisteredStats.Values) | 92 | string[] components = name.Split('.'); |
93 | |||
94 | string categoryName = components[0]; | ||
95 | string containerName = components.Length > 1 ? components[1] : null; | ||
96 | |||
97 | if (categoryName == AllSubCommand) | ||
93 | { | 98 | { |
94 | OutputCategoryStatsToConsole(con, category); | 99 | OutputAllStatsToConsole(con); |
95 | } | 100 | } |
96 | } | 101 | else if (categoryName == ListSubCommand) |
97 | else if (categoryName == ListSubCommand) | ||
98 | { | ||
99 | con.Output("Statistic categories available are:"); | ||
100 | foreach (string category in RegisteredStats.Keys) | ||
101 | con.OutputFormat(" {0}", category); | ||
102 | } | ||
103 | else | ||
104 | { | ||
105 | SortedDictionary<string, SortedDictionary<string, Stat>> category; | ||
106 | if (!RegisteredStats.TryGetValue(categoryName, out category)) | ||
107 | { | 102 | { |
108 | con.OutputFormat("No such category as {0}", categoryName); | 103 | con.Output("Statistic categories available are:"); |
104 | foreach (string category in RegisteredStats.Keys) | ||
105 | con.OutputFormat(" {0}", category); | ||
109 | } | 106 | } |
110 | else | 107 | else |
111 | { | 108 | { |
112 | if (String.IsNullOrEmpty(containerName)) | 109 | SortedDictionary<string, SortedDictionary<string, Stat>> category; |
113 | OutputCategoryStatsToConsole(con, category); | 110 | if (!RegisteredStats.TryGetValue(categoryName, out category)) |
111 | { | ||
112 | con.OutputFormat("No such category as {0}", categoryName); | ||
113 | } | ||
114 | else | 114 | else |
115 | { | 115 | { |
116 | SortedDictionary<string, Stat> container; | 116 | if (String.IsNullOrEmpty(containerName)) |
117 | if (category.TryGetValue(containerName, out container)) | ||
118 | { | 117 | { |
119 | OutputContainerStatsToConsole(con, container); | 118 | OutputCategoryStatsToConsole(con, category); |
120 | } | 119 | } |
121 | else | 120 | else |
122 | { | 121 | { |
123 | con.OutputFormat("No such container {0} in category {1}", containerName, categoryName); | 122 | SortedDictionary<string, Stat> container; |
123 | if (category.TryGetValue(containerName, out container)) | ||
124 | { | ||
125 | OutputContainerStatsToConsole(con, container); | ||
126 | } | ||
127 | else | ||
128 | { | ||
129 | con.OutputFormat("No such container {0} in category {1}", containerName, categoryName); | ||
130 | } | ||
124 | } | 131 | } |
125 | } | 132 | } |
126 | } | 133 | } |
@@ -129,7 +136,18 @@ namespace OpenSim.Framework.Monitoring | |||
129 | else | 136 | else |
130 | { | 137 | { |
131 | // Legacy | 138 | // Legacy |
132 | con.Output(SimExtraStats.Report()); | 139 | if (SimExtraStats != null) |
140 | con.Output(SimExtraStats.Report()); | ||
141 | else | ||
142 | OutputAllStatsToConsole(con); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | private static void OutputAllStatsToConsole(ICommandConsole con) | ||
147 | { | ||
148 | foreach (var category in RegisteredStats.Values) | ||
149 | { | ||
150 | OutputCategoryStatsToConsole(con, category); | ||
133 | } | 151 | } |
134 | } | 152 | } |
135 | 153 | ||
@@ -150,27 +168,27 @@ namespace OpenSim.Framework.Monitoring | |||
150 | } | 168 | } |
151 | } | 169 | } |
152 | 170 | ||
153 | /// <summary> | 171 | // /// <summary> |
154 | /// Start collecting statistics related to assets. | 172 | // /// Start collecting statistics related to assets. |
155 | /// Should only be called once. | 173 | // /// Should only be called once. |
156 | /// </summary> | 174 | // /// </summary> |
157 | public static AssetStatsCollector StartCollectingAssetStats() | 175 | // public static AssetStatsCollector StartCollectingAssetStats() |
158 | { | 176 | // { |
159 | assetStats = new AssetStatsCollector(); | 177 | // assetStats = new AssetStatsCollector(); |
160 | 178 | // | |
161 | return assetStats; | 179 | // return assetStats; |
162 | } | 180 | // } |
163 | 181 | // | |
164 | /// <summary> | 182 | // /// <summary> |
165 | /// Start collecting statistics related to users. | 183 | // /// Start collecting statistics related to users. |
166 | /// Should only be called once. | 184 | // /// Should only be called once. |
167 | /// </summary> | 185 | // /// </summary> |
168 | public static UserStatsCollector StartCollectingUserStats() | 186 | // public static UserStatsCollector StartCollectingUserStats() |
169 | { | 187 | // { |
170 | userStats = new UserStatsCollector(); | 188 | // userStats = new UserStatsCollector(); |
171 | 189 | // | |
172 | return userStats; | 190 | // return userStats; |
173 | } | 191 | // } |
174 | 192 | ||
175 | /// <summary> | 193 | /// <summary> |
176 | /// Registers a statistic. | 194 | /// Registers a statistic. |
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 035b3ad..4ab6908 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs | |||
@@ -86,26 +86,23 @@ namespace OpenSim.Framework.Servers | |||
86 | /// </summary> | 86 | /// </summary> |
87 | protected virtual void StartupSpecific() | 87 | protected virtual void StartupSpecific() |
88 | { | 88 | { |
89 | if (m_console == null) | 89 | StatsManager.SimExtraStats = new SimExtraStatsCollector(); |
90 | return; | ||
91 | |||
92 | RegisterCommonCommands(); | 90 | RegisterCommonCommands(); |
93 | 91 | RegisterCommonComponents(Config); | |
94 | m_console.Commands.AddCommand("General", false, "quit", | 92 | } |
95 | "quit", | 93 | |
96 | "Quit the application", HandleQuit); | 94 | protected override void ShutdownSpecific() |
95 | { | ||
96 | m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); | ||
97 | |||
98 | RemovePIDFile(); | ||
99 | |||
100 | base.ShutdownSpecific(); | ||
97 | 101 | ||
98 | m_console.Commands.AddCommand("General", false, "shutdown", | 102 | Environment.Exit(0); |
99 | "shutdown", | ||
100 | "Quit the application", HandleQuit); | ||
101 | } | 103 | } |
102 | 104 | ||
103 | /// <summary> | 105 | /// <summary> |
104 | /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing | ||
105 | /// </summary> | ||
106 | public virtual void ShutdownSpecific() {} | ||
107 | |||
108 | /// <summary> | ||
109 | /// Provides a list of help topics that are available. Overriding classes should append their topics to the | 106 | /// Provides a list of help topics that are available. Overriding classes should append their topics to the |
110 | /// information returned when the base method is called. | 107 | /// information returned when the base method is called. |
111 | /// </summary> | 108 | /// </summary> |
@@ -143,25 +140,8 @@ namespace OpenSim.Framework.Servers | |||
143 | timeTaken.Minutes, timeTaken.Seconds); | 140 | timeTaken.Minutes, timeTaken.Seconds); |
144 | } | 141 | } |
145 | 142 | ||
146 | /// <summary> | 143 | public string osSecret |
147 | /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing | ||
148 | /// </summary> | ||
149 | public virtual void Shutdown() | ||
150 | { | 144 | { |
151 | ShutdownSpecific(); | ||
152 | |||
153 | m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); | ||
154 | RemovePIDFile(); | ||
155 | |||
156 | Environment.Exit(0); | ||
157 | } | ||
158 | |||
159 | private void HandleQuit(string module, string[] args) | ||
160 | { | ||
161 | Shutdown(); | ||
162 | } | ||
163 | |||
164 | public string osSecret { | ||
165 | // Secret uuid for the simulator | 145 | // Secret uuid for the simulator |
166 | get { return m_osSecret; } | 146 | get { return m_osSecret; } |
167 | } | 147 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 96a030b..40b8c5c 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -54,7 +54,6 @@ 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 | |||
58 | /// <summary> | 57 | /// <summary> |
59 | /// This is a pending websocket request before it got an sucessful upgrade response. | 58 | /// This is a pending websocket request before it got an sucessful upgrade response. |
60 | /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to | 59 | /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to |
@@ -81,6 +80,11 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
81 | /// </remarks> | 80 | /// </remarks> |
82 | public int RequestNumber { get; private set; } | 81 | public int RequestNumber { get; private set; } |
83 | 82 | ||
83 | /// <summary> | ||
84 | /// Statistic for holding number of requests processed. | ||
85 | /// </summary> | ||
86 | private Stat m_requestsProcessedStat; | ||
87 | |||
84 | private volatile int NotSocketErrors = 0; | 88 | private volatile int NotSocketErrors = 0; |
85 | public volatile bool HTTPDRunning = false; | 89 | public volatile bool HTTPDRunning = false; |
86 | 90 | ||
@@ -436,9 +440,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
436 | } | 440 | } |
437 | } | 441 | } |
438 | 442 | ||
439 | public void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request) | 443 | private void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request) |
440 | { | 444 | { |
441 | |||
442 | OSHttpRequest req = new OSHttpRequest(context, request); | 445 | OSHttpRequest req = new OSHttpRequest(context, request); |
443 | WebSocketRequestDelegate dWebSocketRequestDelegate = null; | 446 | WebSocketRequestDelegate dWebSocketRequestDelegate = null; |
444 | lock (m_WebSocketHandlers) | 447 | lock (m_WebSocketHandlers) |
@@ -454,8 +457,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
454 | 457 | ||
455 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); | 458 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); |
456 | resp.ReuseContext = true; | 459 | resp.ReuseContext = true; |
457 | HandleRequest(req, resp); | 460 | HandleRequest(req, resp); |
458 | |||
459 | 461 | ||
460 | // !!!HACK ALERT!!! | 462 | // !!!HACK ALERT!!! |
461 | // There seems to be a bug in the underlying http code that makes subsequent requests | 463 | // There seems to be a bug in the underlying http code that makes subsequent requests |
@@ -1824,6 +1826,21 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1824 | // useful without inbound HTTP. | 1826 | // useful without inbound HTTP. |
1825 | throw e; | 1827 | throw e; |
1826 | } | 1828 | } |
1829 | |||
1830 | m_requestsProcessedStat | ||
1831 | = new Stat( | ||
1832 | "HTTPRequestsServed", | ||
1833 | "Number of inbound HTTP requests processed", | ||
1834 | "", | ||
1835 | "requests", | ||
1836 | "httpserver", | ||
1837 | Port.ToString(), | ||
1838 | StatType.Pull, | ||
1839 | MeasuresOfInterest.AverageChangeOverTime, | ||
1840 | stat => stat.Value = RequestNumber, | ||
1841 | StatVerbosity.Debug); | ||
1842 | |||
1843 | StatsManager.RegisterStat(m_requestsProcessedStat); | ||
1827 | } | 1844 | } |
1828 | 1845 | ||
1829 | public void httpServerDisconnectMonitor(IHttpClientContext source, SocketError err) | 1846 | public void httpServerDisconnectMonitor(IHttpClientContext source, SocketError err) |
@@ -1854,6 +1871,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1854 | public void Stop() | 1871 | public void Stop() |
1855 | { | 1872 | { |
1856 | HTTPDRunning = false; | 1873 | HTTPDRunning = false; |
1874 | |||
1875 | StatsManager.DeregisterStat(m_requestsProcessedStat); | ||
1876 | |||
1857 | try | 1877 | try |
1858 | { | 1878 | { |
1859 | m_PollServiceManager.Stop(); | 1879 | m_PollServiceManager.Stop(); |
diff --git a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs index ee96b47..de89e2e 100644 --- a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs | |||
@@ -75,7 +75,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
75 | /// <summary> | 75 | /// <summary> |
76 | /// This is a regular HTTP Request... This may be removed in the future. | 76 | /// This is a regular HTTP Request... This may be removed in the future. |
77 | /// </summary> | 77 | /// </summary> |
78 | public event RegularHttpRequestDelegate OnRegularHttpRequest; | 78 | // public event RegularHttpRequestDelegate OnRegularHttpRequest; |
79 | 79 | ||
80 | /// <summary> | 80 | /// <summary> |
81 | /// When the upgrade from a HTTP request to a Websocket is completed, this will be fired | 81 | /// When the upgrade from a HTTP request to a Websocket is completed, this will be fired |
@@ -304,15 +304,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
304 | if (d != null) | 304 | if (d != null) |
305 | d(this, new UpgradeCompletedEventArgs()); | 305 | d(this, new UpgradeCompletedEventArgs()); |
306 | } | 306 | } |
307 | catch (IOException fail) | 307 | catch (IOException) |
308 | { | 308 | { |
309 | Close(string.Empty); | 309 | Close(string.Empty); |
310 | } | 310 | } |
311 | catch (ObjectDisposedException fail) | 311 | catch (ObjectDisposedException) |
312 | { | 312 | { |
313 | Close(string.Empty); | 313 | Close(string.Empty); |
314 | } | 314 | } |
315 | |||
316 | } | 315 | } |
317 | 316 | ||
318 | /// <summary> | 317 | /// <summary> |
@@ -414,8 +413,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
414 | _socketState.Header = pheader; | 413 | _socketState.Header = pheader; |
415 | } | 414 | } |
416 | 415 | ||
417 | |||
418 | |||
419 | if (_socketState.FrameComplete) | 416 | if (_socketState.FrameComplete) |
420 | { | 417 | { |
421 | ProcessFrame(_socketState); | 418 | ProcessFrame(_socketState); |
@@ -424,7 +421,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
424 | _socketState.ExpectedBytes = 0; | 421 | _socketState.ExpectedBytes = 0; |
425 | 422 | ||
426 | } | 423 | } |
427 | |||
428 | } | 424 | } |
429 | } | 425 | } |
430 | else | 426 | else |
@@ -457,8 +453,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
457 | _socketState.ReceivedBytes.Clear(); | 453 | _socketState.ReceivedBytes.Clear(); |
458 | _socketState.ExpectedBytes = 0; | 454 | _socketState.ExpectedBytes = 0; |
459 | // do some processing | 455 | // do some processing |
460 | } | 456 | } |
461 | |||
462 | } | 457 | } |
463 | } | 458 | } |
464 | if (offset > 0) | 459 | if (offset > 0) |
@@ -477,13 +472,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
477 | { | 472 | { |
478 | // We can't read the stream anymore... | 473 | // We can't read the stream anymore... |
479 | } | 474 | } |
480 | |||
481 | } | 475 | } |
482 | catch (IOException fail) | 476 | catch (IOException) |
483 | { | 477 | { |
484 | Close(string.Empty); | 478 | Close(string.Empty); |
485 | } | 479 | } |
486 | catch (ObjectDisposedException fail) | 480 | catch (ObjectDisposedException) |
487 | { | 481 | { |
488 | Close(string.Empty); | 482 | Close(string.Empty); |
489 | } | 483 | } |
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index 2c4a687..029b848 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs | |||
@@ -62,6 +62,8 @@ namespace OpenSim.Framework.Servers | |||
62 | 62 | ||
63 | protected string m_pidFile = String.Empty; | 63 | protected string m_pidFile = String.Empty; |
64 | 64 | ||
65 | protected ServerStatsCollector m_serverStatsCollector; | ||
66 | |||
65 | /// <summary> | 67 | /// <summary> |
66 | /// Server version information. Usually VersionInfo + information about git commit, operating system, etc. | 68 | /// Server version information. Usually VersionInfo + information about git commit, operating system, etc. |
67 | /// </summary> | 69 | /// </summary> |
@@ -259,6 +261,25 @@ namespace OpenSim.Framework.Servers | |||
259 | "force gc", | 261 | "force gc", |
260 | "Manually invoke runtime garbage collection. For debugging purposes", | 262 | "Manually invoke runtime garbage collection. For debugging purposes", |
261 | HandleForceGc); | 263 | HandleForceGc); |
264 | |||
265 | m_console.Commands.AddCommand( | ||
266 | "General", false, "quit", | ||
267 | "quit", | ||
268 | "Quit the application", (mod, args) => Shutdown()); | ||
269 | |||
270 | m_console.Commands.AddCommand( | ||
271 | "General", false, "shutdown", | ||
272 | "shutdown", | ||
273 | "Quit the application", (mod, args) => Shutdown()); | ||
274 | |||
275 | StatsManager.RegisterConsoleCommands(m_console); | ||
276 | } | ||
277 | |||
278 | public void RegisterCommonComponents(IConfigSource configSource) | ||
279 | { | ||
280 | m_serverStatsCollector = new ServerStatsCollector(); | ||
281 | m_serverStatsCollector.Initialise(configSource); | ||
282 | m_serverStatsCollector.Start(); | ||
262 | } | 283 | } |
263 | 284 | ||
264 | private void HandleForceGc(string module, string[] args) | 285 | private void HandleForceGc(string module, string[] args) |
@@ -646,7 +667,68 @@ namespace OpenSim.Framework.Servers | |||
646 | sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); | 667 | sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); |
647 | 668 | ||
648 | sb.Append("Main threadpool (excluding script engine pools)\n"); | 669 | sb.Append("Main threadpool (excluding script engine pools)\n"); |
649 | sb.Append(Util.GetThreadPoolReport()); | 670 | sb.Append(GetThreadPoolReport()); |
671 | |||
672 | return sb.ToString(); | ||
673 | } | ||
674 | |||
675 | /// <summary> | ||
676 | /// Get a thread pool report. | ||
677 | /// </summary> | ||
678 | /// <returns></returns> | ||
679 | public static string GetThreadPoolReport() | ||
680 | { | ||
681 | string threadPoolUsed = null; | ||
682 | int maxThreads = 0; | ||
683 | int minThreads = 0; | ||
684 | int allocatedThreads = 0; | ||
685 | int inUseThreads = 0; | ||
686 | int waitingCallbacks = 0; | ||
687 | int completionPortThreads = 0; | ||
688 | |||
689 | StringBuilder sb = new StringBuilder(); | ||
690 | if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) | ||
691 | { | ||
692 | STPInfo stpi = Util.GetSmartThreadPoolInfo(); | ||
693 | |||
694 | // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool. | ||
695 | if (stpi != null) | ||
696 | { | ||
697 | threadPoolUsed = "SmartThreadPool"; | ||
698 | maxThreads = stpi.MaxThreads; | ||
699 | minThreads = stpi.MinThreads; | ||
700 | inUseThreads = stpi.InUseThreads; | ||
701 | allocatedThreads = stpi.ActiveThreads; | ||
702 | waitingCallbacks = stpi.WaitingCallbacks; | ||
703 | } | ||
704 | } | ||
705 | else if ( | ||
706 | Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem | ||
707 | || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) | ||
708 | { | ||
709 | threadPoolUsed = "BuiltInThreadPool"; | ||
710 | ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads); | ||
711 | ThreadPool.GetMinThreads(out minThreads, out completionPortThreads); | ||
712 | int availableThreads; | ||
713 | ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads); | ||
714 | inUseThreads = maxThreads - availableThreads; | ||
715 | allocatedThreads = -1; | ||
716 | waitingCallbacks = -1; | ||
717 | } | ||
718 | |||
719 | if (threadPoolUsed != null) | ||
720 | { | ||
721 | sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); | ||
722 | sb.AppendFormat("Max threads : {0}\n", maxThreads); | ||
723 | sb.AppendFormat("Min threads : {0}\n", minThreads); | ||
724 | sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString()); | ||
725 | sb.AppendFormat("In use threads : {0}\n", inUseThreads); | ||
726 | sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString()); | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | sb.AppendFormat("Thread pool not used\n"); | ||
731 | } | ||
650 | 732 | ||
651 | return sb.ToString(); | 733 | return sb.ToString(); |
652 | } | 734 | } |
@@ -698,5 +780,16 @@ namespace OpenSim.Framework.Servers | |||
698 | if (m_console != null) | 780 | if (m_console != null) |
699 | m_console.OutputFormat(format, components); | 781 | m_console.OutputFormat(format, components); |
700 | } | 782 | } |
783 | |||
784 | public virtual void Shutdown() | ||
785 | { | ||
786 | m_serverStatsCollector.Close(); | ||
787 | ShutdownSpecific(); | ||
788 | } | ||
789 | |||
790 | /// <summary> | ||
791 | /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing | ||
792 | /// </summary> | ||
793 | protected virtual void ShutdownSpecific() {} | ||
701 | } | 794 | } |
702 | } \ No newline at end of file | 795 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 7f0850f..ba6cc75 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -89,9 +89,30 @@ namespace OpenSim.Framework | |||
89 | } | 89 | } |
90 | 90 | ||
91 | /// <summary> | 91 | /// <summary> |
92 | /// Class for delivering SmartThreadPool statistical information | ||
93 | /// </summary> | ||
94 | /// <remarks> | ||
95 | /// We do it this way so that we do not directly expose STP. | ||
96 | /// </remarks> | ||
97 | public class STPInfo | ||
98 | { | ||
99 | public string Name { get; set; } | ||
100 | public STPStartInfo STPStartInfo { get; set; } | ||
101 | public WIGStartInfo WIGStartInfo { get; set; } | ||
102 | public bool IsIdle { get; set; } | ||
103 | public bool IsShuttingDown { get; set; } | ||
104 | public int MaxThreads { get; set; } | ||
105 | public int MinThreads { get; set; } | ||
106 | public int InUseThreads { get; set; } | ||
107 | public int ActiveThreads { get; set; } | ||
108 | public int WaitingCallbacks { get; set; } | ||
109 | public int MaxConcurrentWorkItems { get; set; } | ||
110 | } | ||
111 | |||
112 | /// <summary> | ||
92 | /// Miscellaneous utility functions | 113 | /// Miscellaneous utility functions |
93 | /// </summary> | 114 | /// </summary> |
94 | public class Util | 115 | public static class Util |
95 | { | 116 | { |
96 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 117 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
97 | 118 | ||
@@ -1852,74 +1873,31 @@ namespace OpenSim.Framework | |||
1852 | } | 1873 | } |
1853 | 1874 | ||
1854 | /// <summary> | 1875 | /// <summary> |
1855 | /// Get a thread pool report. | 1876 | /// Get information about the current state of the smart thread pool. |
1856 | /// </summary> | 1877 | /// </summary> |
1857 | /// <returns></returns> | 1878 | /// <returns> |
1858 | public static string GetThreadPoolReport() | 1879 | /// null if this isn't the pool being used for non-scriptengine threads. |
1880 | /// </returns> | ||
1881 | public static STPInfo GetSmartThreadPoolInfo() | ||
1859 | { | 1882 | { |
1860 | string threadPoolUsed = null; | 1883 | if (m_ThreadPool == null) |
1861 | int maxThreads = 0; | 1884 | return null; |
1862 | int minThreads = 0; | ||
1863 | int allocatedThreads = 0; | ||
1864 | int inUseThreads = 0; | ||
1865 | int waitingCallbacks = 0; | ||
1866 | int completionPortThreads = 0; | ||
1867 | |||
1868 | StringBuilder sb = new StringBuilder(); | ||
1869 | if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) | ||
1870 | { | ||
1871 | // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool. | ||
1872 | if (m_ThreadPool != null) | ||
1873 | { | ||
1874 | threadPoolUsed = "SmartThreadPool"; | ||
1875 | maxThreads = m_ThreadPool.MaxThreads; | ||
1876 | minThreads = m_ThreadPool.MinThreads; | ||
1877 | inUseThreads = m_ThreadPool.InUseThreads; | ||
1878 | allocatedThreads = m_ThreadPool.ActiveThreads; | ||
1879 | waitingCallbacks = m_ThreadPool.WaitingCallbacks; | ||
1880 | } | ||
1881 | } | ||
1882 | else if ( | ||
1883 | FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem | ||
1884 | || FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) | ||
1885 | { | ||
1886 | threadPoolUsed = "BuiltInThreadPool"; | ||
1887 | ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads); | ||
1888 | ThreadPool.GetMinThreads(out minThreads, out completionPortThreads); | ||
1889 | int availableThreads; | ||
1890 | ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads); | ||
1891 | inUseThreads = maxThreads - availableThreads; | ||
1892 | allocatedThreads = -1; | ||
1893 | waitingCallbacks = -1; | ||
1894 | } | ||
1895 | 1885 | ||
1896 | if (threadPoolUsed != null) | 1886 | STPInfo stpi = new STPInfo(); |
1897 | { | 1887 | stpi.Name = m_ThreadPool.Name; |
1898 | sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); | 1888 | stpi.STPStartInfo = m_ThreadPool.STPStartInfo; |
1899 | sb.AppendFormat("Max threads : {0}\n", maxThreads); | 1889 | stpi.IsIdle = m_ThreadPool.IsIdle; |
1900 | sb.AppendFormat("Min threads : {0}\n", minThreads); | 1890 | stpi.IsShuttingDown = m_ThreadPool.IsShuttingdown; |
1901 | sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString()); | 1891 | stpi.MaxThreads = m_ThreadPool.MaxThreads; |
1902 | sb.AppendFormat("In use threads : {0}\n", inUseThreads); | 1892 | stpi.MinThreads = m_ThreadPool.MinThreads; |
1903 | sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString()); | 1893 | stpi.InUseThreads = m_ThreadPool.InUseThreads; |
1904 | } | 1894 | stpi.ActiveThreads = m_ThreadPool.ActiveThreads; |
1905 | else | 1895 | stpi.WaitingCallbacks = m_ThreadPool.WaitingCallbacks; |
1906 | { | 1896 | stpi.MaxConcurrentWorkItems = m_ThreadPool.Concurrency; |
1907 | sb.AppendFormat("Thread pool not used\n"); | ||
1908 | } | ||
1909 | 1897 | ||
1910 | return sb.ToString(); | 1898 | return stpi; |
1911 | } | 1899 | } |
1912 | 1900 | ||
1913 | // private static object SmartThreadPoolCallback(object o) | ||
1914 | // { | ||
1915 | // object[] array = (object[])o; | ||
1916 | // WaitCallback callback = (WaitCallback)array[0]; | ||
1917 | // object obj = array[1]; | ||
1918 | // | ||
1919 | // callback(obj); | ||
1920 | // return null; | ||
1921 | // } | ||
1922 | |||
1923 | #endregion FireAndForget Threading Pattern | 1901 | #endregion FireAndForget Threading Pattern |
1924 | 1902 | ||
1925 | /// <summary> | 1903 | /// <summary> |
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index c3e7ec2..e451aa8 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs | |||
@@ -124,6 +124,7 @@ namespace OpenSim | |||
124 | workerThreads = workerThreadsMax; | 124 | workerThreads = workerThreadsMax; |
125 | m_log.InfoFormat("[OPENSIM MAIN]: Limiting worker threads to {0}",workerThreads); | 125 | m_log.InfoFormat("[OPENSIM MAIN]: Limiting worker threads to {0}",workerThreads); |
126 | } | 126 | } |
127 | |||
127 | // Increase the number of IOCP threads available. | 128 | // Increase the number of IOCP threads available. |
128 | // Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17) | 129 | // Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17) |
129 | if (iocpThreads < iocpThreadsMin) | 130 | if (iocpThreads < iocpThreadsMin) |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 11dd052..9325b12 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -372,7 +372,7 @@ namespace OpenSim | |||
372 | "Unload a module", HandleModules); | 372 | "Unload a module", HandleModules); |
373 | } | 373 | } |
374 | 374 | ||
375 | public override void ShutdownSpecific() | 375 | protected override void ShutdownSpecific() |
376 | { | 376 | { |
377 | if (m_shutdownCommandsFile != String.Empty) | 377 | if (m_shutdownCommandsFile != String.Empty) |
378 | { | 378 | { |
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index f9e0cf1..7ca87a3 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -231,10 +231,7 @@ namespace OpenSim | |||
231 | } | 231 | } |
232 | 232 | ||
233 | if (m_console != null) | 233 | if (m_console != null) |
234 | { | ||
235 | StatsManager.RegisterConsoleCommands(m_console); | ||
236 | AddPluginCommands(m_console); | 234 | AddPluginCommands(m_console); |
237 | } | ||
238 | } | 235 | } |
239 | 236 | ||
240 | protected virtual void AddPluginCommands(ICommandConsole console) | 237 | protected virtual void AddPluginCommands(ICommandConsole console) |
@@ -880,7 +877,7 @@ namespace OpenSim | |||
880 | /// <summary> | 877 | /// <summary> |
881 | /// Performs any last-minute sanity checking and shuts down the region server | 878 | /// Performs any last-minute sanity checking and shuts down the region server |
882 | /// </summary> | 879 | /// </summary> |
883 | public override void ShutdownSpecific() | 880 | protected override void ShutdownSpecific() |
884 | { | 881 | { |
885 | if (proxyUrl.Length > 0) | 882 | if (proxyUrl.Length > 0) |
886 | { | 883 | { |
@@ -900,6 +897,8 @@ namespace OpenSim | |||
900 | { | 897 | { |
901 | m_log.Error("[SHUTDOWN]: Ignoring failure during shutdown - ", e); | 898 | m_log.Error("[SHUTDOWN]: Ignoring failure during shutdown - ", e); |
902 | } | 899 | } |
900 | |||
901 | base.ShutdownSpecific(); | ||
903 | } | 902 | } |
904 | 903 | ||
905 | /// <summary> | 904 | /// <summary> |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 2024018..0e3cd6b 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -34,6 +34,7 @@ using log4net; | |||
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using Mono.Addins; | 35 | using Mono.Addins; |
36 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | using OpenMetaverse.StructuredData; | ||
37 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Monitoring; | 39 | using OpenSim.Framework.Monitoring; |
39 | using OpenSim.Framework.Servers; | 40 | using OpenSim.Framework.Servers; |
@@ -44,8 +45,6 @@ using OpenSim.Framework.Capabilities; | |||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | using Caps = OpenSim.Framework.Capabilities.Caps; | 46 | using Caps = OpenSim.Framework.Capabilities.Caps; |
46 | using OpenSim.Capabilities.Handlers; | 47 | using OpenSim.Capabilities.Handlers; |
47 | using OpenMetaverse; | ||
48 | using OpenMetaverse.StructuredData; | ||
49 | 48 | ||
50 | namespace OpenSim.Region.ClientStack.Linden | 49 | namespace OpenSim.Region.ClientStack.Linden |
51 | { | 50 | { |
@@ -64,7 +63,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
64 | public List<UUID> folders; | 63 | public List<UUID> folders; |
65 | } | 64 | } |
66 | 65 | ||
67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 66 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
68 | 67 | ||
69 | private Scene m_scene; | 68 | private Scene m_scene; |
70 | 69 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 556df30..b47ff54 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs | |||
@@ -33,6 +33,7 @@ using NUnit.Framework; | |||
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenMetaverse.Packets; | 34 | using OpenMetaverse.Packets; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Monitoring; | ||
36 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Tests.Common; | 38 | using OpenSim.Tests.Common; |
38 | using OpenSim.Tests.Common.Mock; | 39 | using OpenSim.Tests.Common.Mock; |
@@ -69,6 +70,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
69 | { | 70 | { |
70 | base.SetUp(); | 71 | base.SetUp(); |
71 | m_scene = new SceneHelpers().SetupScene(); | 72 | m_scene = new SceneHelpers().SetupScene(); |
73 | StatsManager.SimExtraStats = new SimExtraStatsCollector(); | ||
72 | } | 74 | } |
73 | 75 | ||
74 | /// <summary> | 76 | /// <summary> |
@@ -210,8 +212,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
210 | 212 | ||
211 | ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); | 213 | ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); |
212 | Assert.That(spAfterAckTimeout, Is.Null); | 214 | Assert.That(spAfterAckTimeout, Is.Null); |
213 | |||
214 | // TestHelpers.DisableLogging(); | ||
215 | } | 215 | } |
216 | 216 | ||
217 | // /// <summary> | 217 | // /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 7d763fa..7f3d0a2 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | |||
@@ -182,7 +182,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
182 | "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); | 182 | "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); |
183 | 183 | ||
184 | if (msglist == null) | 184 | if (msglist == null) |
185 | { | ||
185 | m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list."); | 186 | m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list."); |
187 | return; | ||
188 | } | ||
186 | 189 | ||
187 | foreach (GridInstantMessage im in msglist) | 190 | foreach (GridInstantMessage im in msglist) |
188 | { | 191 | { |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 02ed1a0..630d1c3 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -53,8 +53,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
54 | 54 | ||
55 | private int m_levelHGTeleport = 0; | 55 | private int m_levelHGTeleport = 0; |
56 | private string m_ThisHomeURI; | ||
56 | 57 | ||
57 | private GatekeeperServiceConnector m_GatekeeperConnector; | 58 | private GatekeeperServiceConnector m_GatekeeperConnector; |
59 | private IUserAgentService m_UAS; | ||
58 | 60 | ||
59 | protected bool m_RestrictAppearanceAbroad; | 61 | protected bool m_RestrictAppearanceAbroad; |
60 | protected string m_AccountName; | 62 | protected string m_AccountName; |
@@ -143,6 +145,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
143 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); | 145 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); |
144 | } | 146 | } |
145 | } | 147 | } |
148 | |||
149 | moduleConfig = source.Configs["Hypergrid"]; | ||
150 | if (moduleConfig != null) | ||
151 | { | ||
152 | m_ThisHomeURI = moduleConfig.GetString("HomeURI", string.Empty); | ||
153 | if (m_ThisHomeURI != string.Empty && !m_ThisHomeURI.EndsWith("/")) | ||
154 | m_ThisHomeURI += '/'; | ||
155 | } | ||
146 | } | 156 | } |
147 | 157 | ||
148 | public override void AddRegion(Scene scene) | 158 | public override void AddRegion(Scene scene) |
@@ -194,7 +204,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
194 | base.RegionLoaded(scene); | 204 | base.RegionLoaded(scene); |
195 | 205 | ||
196 | if (m_Enabled) | 206 | if (m_Enabled) |
207 | { | ||
197 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); | 208 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); |
209 | m_UAS = scene.RequestModuleInterface<IUserAgentService>(); | ||
210 | } | ||
198 | } | 211 | } |
199 | 212 | ||
200 | public override void RemoveRegion(Scene scene) | 213 | public override void RemoveRegion(Scene scene) |
@@ -272,8 +285,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
272 | if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) | 285 | if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) |
273 | { | 286 | { |
274 | string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); | 287 | string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); |
275 | IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); | 288 | IUserAgentService connector; |
276 | bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); | 289 | |
290 | if (userAgentDriver.Equals(m_ThisHomeURI) && m_UAS != null) | ||
291 | connector = m_UAS; | ||
292 | else | ||
293 | connector = new UserAgentServiceConnector(userAgentDriver); | ||
294 | |||
295 | bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, false, out reason); | ||
277 | logout = success; // flag for later logout from this grid; this is an HG TP | 296 | logout = success; // flag for later logout from this grid; this is an HG TP |
278 | 297 | ||
279 | if (success) | 298 | if (success) |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index b2a1b23..d120e11 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs | |||
@@ -194,7 +194,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
194 | return false; | 194 | return false; |
195 | 195 | ||
196 | // Try local first | 196 | // Try local first |
197 | if (m_localBackend.IsLocalRegion(destination.RegionHandle)) | 197 | if (m_localBackend.IsLocalRegion(destination.RegionID)) |
198 | return m_localBackend.UpdateAgent(destination, cAgentData); | 198 | return m_localBackend.UpdateAgent(destination, cAgentData); |
199 | 199 | ||
200 | return m_remoteConnector.UpdateAgent(destination, cAgentData); | 200 | return m_remoteConnector.UpdateAgent(destination, cAgentData); |
@@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
206 | return false; | 206 | return false; |
207 | 207 | ||
208 | // Try local first | 208 | // Try local first |
209 | if (m_localBackend.IsLocalRegion(destination.RegionHandle)) | 209 | if (m_localBackend.IsLocalRegion(destination.RegionID)) |
210 | return m_localBackend.UpdateAgent(destination, cAgentData); | 210 | return m_localBackend.UpdateAgent(destination, cAgentData); |
211 | 211 | ||
212 | return m_remoteConnector.UpdateAgent(destination, cAgentData); | 212 | return m_remoteConnector.UpdateAgent(destination, cAgentData); |
@@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
224 | return true; | 224 | return true; |
225 | 225 | ||
226 | // else do the remote thing | 226 | // else do the remote thing |
227 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | 227 | if (!m_localBackend.IsLocalRegion(destination.RegionID)) |
228 | return m_remoteConnector.RetrieveAgent(destination, id, out agent); | 228 | return m_remoteConnector.RetrieveAgent(destination, id, out agent); |
229 | 229 | ||
230 | return false; | 230 | return false; |
@@ -273,7 +273,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
273 | return true; | 273 | return true; |
274 | 274 | ||
275 | // else do the remote thing | 275 | // else do the remote thing |
276 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | 276 | if (!m_localBackend.IsLocalRegion(destination.RegionID)) |
277 | return m_remoteConnector.CloseAgent(destination, id); | 277 | return m_remoteConnector.CloseAgent(destination, id); |
278 | 278 | ||
279 | return false; | 279 | return false; |
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
296 | } | 296 | } |
297 | 297 | ||
298 | // else do the remote thing | 298 | // else do the remote thing |
299 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | 299 | if (!m_localBackend.IsLocalRegion(destination.RegionID)) |
300 | return m_remoteConnector.CreateObject(destination, newPosition, sog, isLocalCall); | 300 | return m_remoteConnector.CreateObject(destination, newPosition, sog, isLocalCall); |
301 | 301 | ||
302 | return false; | 302 | return false; |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 8406442..e55c9ed 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -81,14 +81,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
81 | 81 | ||
82 | set { m_landData = value; } | 82 | set { m_landData = value; } |
83 | } | 83 | } |
84 | 84 | ||
85 | public IPrimCounts PrimCounts { get; set; } | 85 | public IPrimCounts PrimCounts { get; set; } |
86 | 86 | ||
87 | public UUID RegionUUID | 87 | public UUID RegionUUID |
88 | { | 88 | { |
89 | get { return m_scene.RegionInfo.RegionID; } | 89 | get { return m_scene.RegionInfo.RegionID; } |
90 | } | 90 | } |
91 | 91 | ||
92 | public Vector3 StartPoint | 92 | public Vector3 StartPoint |
93 | { | 93 | { |
94 | get | 94 | get |
@@ -101,11 +101,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
101 | return new Vector3(x * 4, y * 4, 0); | 101 | return new Vector3(x * 4, y * 4, 0); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | return new Vector3(-1, -1, -1); | 105 | return new Vector3(-1, -1, -1); |
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | public Vector3 EndPoint | 109 | public Vector3 EndPoint |
110 | { | 110 | { |
111 | get | 111 | get |
@@ -116,15 +116,15 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
116 | { | 116 | { |
117 | if (LandBitmap[x, y]) | 117 | if (LandBitmap[x, y]) |
118 | { | 118 | { |
119 | return new Vector3(x * 4, y * 4, 0); | 119 | return new Vector3(x * 4 + 4, y * 4 + 4, 0); |
120 | } | 120 | } |
121 | } | 121 | } |
122 | } | 122 | } |
123 | 123 | ||
124 | return new Vector3(-1, -1, -1); | 124 | return new Vector3(-1, -1, -1); |
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | #region Constructors | 128 | #region Constructors |
129 | 129 | ||
130 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) | 130 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6c79b13..1e4d558 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -326,7 +326,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
326 | // Update item with new asset | 326 | // Update item with new asset |
327 | item.AssetID = asset.FullID; | 327 | item.AssetID = asset.FullID; |
328 | if (group.UpdateInventoryItem(item)) | 328 | if (group.UpdateInventoryItem(item)) |
329 | remoteClient.SendAgentAlertMessage("Script saved", false); | 329 | remoteClient.SendAlertMessage("Script saved"); |
330 | 330 | ||
331 | part.SendPropertiesToClient(remoteClient); | 331 | part.SendPropertiesToClient(remoteClient); |
332 | 332 | ||
@@ -342,7 +342,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
342 | } | 342 | } |
343 | else | 343 | else |
344 | { | 344 | { |
345 | remoteClient.SendAgentAlertMessage("Script saved", false); | 345 | remoteClient.SendAlertMessage("Script saved"); |
346 | } | 346 | } |
347 | 347 | ||
348 | // Tell anyone managing scripts that a script has been reloaded/changed | 348 | // Tell anyone managing scripts that a script has been reloaded/changed |
@@ -1616,11 +1616,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1616 | remoteClient, part, transactionID, currentItem); | 1616 | remoteClient, part, transactionID, currentItem); |
1617 | 1617 | ||
1618 | if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) | 1618 | if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) |
1619 | remoteClient.SendAgentAlertMessage("Notecard saved", false); | 1619 | remoteClient.SendAlertMessage("Notecard saved"); |
1620 | else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) | 1620 | else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) |
1621 | remoteClient.SendAgentAlertMessage("Script saved", false); | 1621 | remoteClient.SendAlertMessage("Script saved"); |
1622 | else | 1622 | else |
1623 | remoteClient.SendAgentAlertMessage("Item saved", false); | 1623 | remoteClient.SendAlertMessage("Item saved"); |
1624 | } | 1624 | } |
1625 | 1625 | ||
1626 | // Base ALWAYS has move | 1626 | // Base ALWAYS has move |
diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs deleted file mode 100644 index 6e74ce0..0000000 --- a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs +++ /dev/null | |||
@@ -1,339 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Diagnostics; | ||
31 | using System.Linq; | ||
32 | using System.Net.NetworkInformation; | ||
33 | using System.Text; | ||
34 | using System.Threading; | ||
35 | |||
36 | using log4net; | ||
37 | using Mono.Addins; | ||
38 | using Nini.Config; | ||
39 | |||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Framework.Console; | ||
42 | using OpenSim.Framework.Monitoring; | ||
43 | using OpenSim.Region.Framework.Interfaces; | ||
44 | using OpenSim.Region.Framework.Scenes; | ||
45 | |||
46 | using OpenMetaverse.StructuredData; | ||
47 | |||
48 | namespace OpenSim.Region.OptionalModules.Framework.Monitoring | ||
49 | { | ||
50 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ServerStatistics")] | ||
51 | public class ServerStats : ISharedRegionModule | ||
52 | { | ||
53 | private readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
54 | private readonly string LogHeader = "[SERVER STATS]"; | ||
55 | |||
56 | public bool Enabled = false; | ||
57 | private static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>(); | ||
58 | |||
59 | public readonly string CategoryServer = "server"; | ||
60 | |||
61 | public readonly string ContainerProcessor = "processor"; | ||
62 | public readonly string ContainerMemory = "memory"; | ||
63 | public readonly string ContainerNetwork = "network"; | ||
64 | public readonly string ContainerProcess = "process"; | ||
65 | |||
66 | public string NetworkInterfaceTypes = "Ethernet"; | ||
67 | |||
68 | readonly int performanceCounterSampleInterval = 500; | ||
69 | int lastperformanceCounterSampleTime = 0; | ||
70 | |||
71 | private class PerfCounterControl | ||
72 | { | ||
73 | public PerformanceCounter perfCounter; | ||
74 | public int lastFetch; | ||
75 | public string name; | ||
76 | public PerfCounterControl(PerformanceCounter pPc) | ||
77 | : this(pPc, String.Empty) | ||
78 | { | ||
79 | } | ||
80 | public PerfCounterControl(PerformanceCounter pPc, string pName) | ||
81 | { | ||
82 | perfCounter = pPc; | ||
83 | lastFetch = 0; | ||
84 | name = pName; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | PerfCounterControl processorPercentPerfCounter = null; | ||
89 | |||
90 | #region ISharedRegionModule | ||
91 | // IRegionModuleBase.Name | ||
92 | public string Name { get { return "Server Stats"; } } | ||
93 | // IRegionModuleBase.ReplaceableInterface | ||
94 | public Type ReplaceableInterface { get { return null; } } | ||
95 | // IRegionModuleBase.Initialize | ||
96 | public void Initialise(IConfigSource source) | ||
97 | { | ||
98 | IConfig cfg = source.Configs["Monitoring"]; | ||
99 | |||
100 | if (cfg != null) | ||
101 | Enabled = cfg.GetBoolean("ServerStatsEnabled", true); | ||
102 | |||
103 | if (Enabled) | ||
104 | { | ||
105 | NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet"); | ||
106 | } | ||
107 | } | ||
108 | // IRegionModuleBase.Close | ||
109 | public void Close() | ||
110 | { | ||
111 | if (RegisteredStats.Count > 0) | ||
112 | { | ||
113 | foreach (Stat stat in RegisteredStats.Values) | ||
114 | { | ||
115 | StatsManager.DeregisterStat(stat); | ||
116 | stat.Dispose(); | ||
117 | } | ||
118 | RegisteredStats.Clear(); | ||
119 | } | ||
120 | } | ||
121 | // IRegionModuleBase.AddRegion | ||
122 | public void AddRegion(Scene scene) | ||
123 | { | ||
124 | } | ||
125 | // IRegionModuleBase.RemoveRegion | ||
126 | public void RemoveRegion(Scene scene) | ||
127 | { | ||
128 | } | ||
129 | // IRegionModuleBase.RegionLoaded | ||
130 | public void RegionLoaded(Scene scene) | ||
131 | { | ||
132 | } | ||
133 | // ISharedRegionModule.PostInitialize | ||
134 | public void PostInitialise() | ||
135 | { | ||
136 | if (RegisteredStats.Count == 0) | ||
137 | { | ||
138 | RegisterServerStats(); | ||
139 | } | ||
140 | } | ||
141 | #endregion ISharedRegionModule | ||
142 | |||
143 | private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action<Stat> act) | ||
144 | { | ||
145 | string desc = pDesc; | ||
146 | if (desc == null) | ||
147 | desc = pName; | ||
148 | Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info); | ||
149 | StatsManager.RegisterStat(stat); | ||
150 | RegisteredStats.Add(pName, stat); | ||
151 | } | ||
152 | |||
153 | public void RegisterServerStats() | ||
154 | { | ||
155 | lastperformanceCounterSampleTime = Util.EnvironmentTickCount(); | ||
156 | PerformanceCounter tempPC; | ||
157 | Stat tempStat; | ||
158 | string tempName; | ||
159 | |||
160 | try | ||
161 | { | ||
162 | tempName = "CPUPercent"; | ||
163 | tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total"); | ||
164 | processorPercentPerfCounter = new PerfCounterControl(tempPC); | ||
165 | // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy. | ||
166 | tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor, | ||
167 | StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); }, | ||
168 | StatVerbosity.Info); | ||
169 | StatsManager.RegisterStat(tempStat); | ||
170 | RegisteredStats.Add(tempName, tempStat); | ||
171 | |||
172 | MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor, | ||
173 | (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; }); | ||
174 | |||
175 | MakeStat("UserProcessorTime", null, "sec", ContainerProcessor, | ||
176 | (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; }); | ||
177 | |||
178 | MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor, | ||
179 | (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; }); | ||
180 | |||
181 | MakeStat("Threads", null, "threads", ContainerProcessor, | ||
182 | (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; }); | ||
183 | } | ||
184 | catch (Exception e) | ||
185 | { | ||
186 | m_log.ErrorFormat("{0} Exception creating 'Process': {1}", LogHeader, e); | ||
187 | } | ||
188 | |||
189 | try | ||
190 | { | ||
191 | List<string> okInterfaceTypes = new List<string>(NetworkInterfaceTypes.Split(',')); | ||
192 | |||
193 | IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces(); | ||
194 | foreach (NetworkInterface nic in nics) | ||
195 | { | ||
196 | if (nic.OperationalStatus != OperationalStatus.Up) | ||
197 | continue; | ||
198 | |||
199 | string nicInterfaceType = nic.NetworkInterfaceType.ToString(); | ||
200 | if (!okInterfaceTypes.Contains(nicInterfaceType)) | ||
201 | { | ||
202 | m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.", | ||
203 | LogHeader, nic.Name, nicInterfaceType); | ||
204 | m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}", | ||
205 | LogHeader, NetworkInterfaceTypes); | ||
206 | continue; | ||
207 | } | ||
208 | |||
209 | if (nic.Supports(NetworkInterfaceComponent.IPv4)) | ||
210 | { | ||
211 | IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics(); | ||
212 | if (nicStats != null) | ||
213 | { | ||
214 | MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork, | ||
215 | (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }); | ||
216 | MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork, | ||
217 | (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }); | ||
218 | MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork, | ||
219 | (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }); | ||
220 | } | ||
221 | } | ||
222 | // TODO: add IPv6 (it may actually happen someday) | ||
223 | } | ||
224 | } | ||
225 | catch (Exception e) | ||
226 | { | ||
227 | m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e); | ||
228 | } | ||
229 | |||
230 | MakeStat("ProcessMemory", null, "MB", ContainerMemory, | ||
231 | (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }); | ||
232 | MakeStat("ObjectMemory", null, "MB", ContainerMemory, | ||
233 | (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }); | ||
234 | MakeStat("LastMemoryChurn", null, "MB/sec", ContainerMemory, | ||
235 | (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }); | ||
236 | MakeStat("AverageMemoryChurn", null, "MB/sec", ContainerMemory, | ||
237 | (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }); | ||
238 | } | ||
239 | |||
240 | // Notes on performance counters: | ||
241 | // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx | ||
242 | // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c | ||
243 | // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters | ||
244 | private delegate double PerfCounterNextValue(); | ||
245 | private void GetNextValue(Stat stat, PerfCounterControl perfControl) | ||
246 | { | ||
247 | GetNextValue(stat, perfControl, 1.0); | ||
248 | } | ||
249 | private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor) | ||
250 | { | ||
251 | if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval) | ||
252 | { | ||
253 | if (perfControl != null && perfControl.perfCounter != null) | ||
254 | { | ||
255 | try | ||
256 | { | ||
257 | // Kludge for factor to run double duty. If -1, subtract the value from one | ||
258 | if (factor == -1) | ||
259 | stat.Value = 1 - perfControl.perfCounter.NextValue(); | ||
260 | else | ||
261 | stat.Value = perfControl.perfCounter.NextValue() / factor; | ||
262 | } | ||
263 | catch (Exception e) | ||
264 | { | ||
265 | m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e); | ||
266 | } | ||
267 | perfControl.lastFetch = Util.EnvironmentTickCount(); | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | // Lookup the nic that goes with this stat and set the value by using a fetch action. | ||
273 | // Not sure about closure with delegates inside delegates. | ||
274 | private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat); | ||
275 | private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor) | ||
276 | { | ||
277 | // Get the one nic that has the name of this stat | ||
278 | IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces().Where( | ||
279 | (network) => network.Name == stat.Description); | ||
280 | try | ||
281 | { | ||
282 | foreach (NetworkInterface nic in nics) | ||
283 | { | ||
284 | IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics(); | ||
285 | if (intrStats != null) | ||
286 | { | ||
287 | double newVal = Math.Round(getter(intrStats) / factor, 3); | ||
288 | stat.Value = newVal; | ||
289 | } | ||
290 | break; | ||
291 | } | ||
292 | } | ||
293 | catch | ||
294 | { | ||
295 | // There are times interfaces go away so we just won't update the stat for this | ||
296 | m_log.ErrorFormat("{0} Exception fetching stat on interface '{1}'", LogHeader, stat.Description); | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | |||
301 | public class ServerStatsAggregator : Stat | ||
302 | { | ||
303 | public ServerStatsAggregator( | ||
304 | string shortName, | ||
305 | string name, | ||
306 | string description, | ||
307 | string unitName, | ||
308 | string category, | ||
309 | string container | ||
310 | ) | ||
311 | : base( | ||
312 | shortName, | ||
313 | name, | ||
314 | description, | ||
315 | unitName, | ||
316 | category, | ||
317 | container, | ||
318 | StatType.Push, | ||
319 | MeasuresOfInterest.None, | ||
320 | null, | ||
321 | StatVerbosity.Info) | ||
322 | { | ||
323 | } | ||
324 | public override string ToConsoleString() | ||
325 | { | ||
326 | StringBuilder sb = new StringBuilder(); | ||
327 | |||
328 | return sb.ToString(); | ||
329 | } | ||
330 | |||
331 | public override OSDMap ToOSDMap() | ||
332 | { | ||
333 | OSDMap ret = new OSDMap(); | ||
334 | |||
335 | return ret; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | } | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs index ac8c30c..928b350 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs | |||
@@ -43,8 +43,14 @@ public class BSActorAvatarMove : BSActor | |||
43 | // Set to true if we think we're going up stairs. | 43 | // Set to true if we think we're going up stairs. |
44 | // This state is remembered because collisions will turn on and off as we go up stairs. | 44 | // This state is remembered because collisions will turn on and off as we go up stairs. |
45 | int m_walkingUpStairs; | 45 | int m_walkingUpStairs; |
46 | // The amount the step up is applying. Used to smooth stair walking. | ||
46 | float m_lastStepUp; | 47 | float m_lastStepUp; |
47 | 48 | ||
49 | // Jumping happens over several frames. If use applies up force while colliding, start the | ||
50 | // jump and allow the jump to continue for this number of frames. | ||
51 | int m_jumpFrames = 0; | ||
52 | float m_jumpVelocity = 0f; | ||
53 | |||
48 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) | 54 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) |
49 | : base(physicsScene, pObj, actorName) | 55 | : base(physicsScene, pObj, actorName) |
50 | { | 56 | { |
@@ -206,17 +212,45 @@ public class BSActorAvatarMove : BSActor | |||
206 | 212 | ||
207 | if (m_controllingPrim.Friction != BSParam.AvatarFriction) | 213 | if (m_controllingPrim.Friction != BSParam.AvatarFriction) |
208 | { | 214 | { |
209 | // Probably starting up walking. Set friction to moving friction. | 215 | // Probably starting to walk. Set friction to moving friction. |
210 | m_controllingPrim.Friction = BSParam.AvatarFriction; | 216 | m_controllingPrim.Friction = BSParam.AvatarFriction; |
211 | m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction); | 217 | m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction); |
212 | } | 218 | } |
213 | 219 | ||
214 | // If falling, we keep the world's downward vector no matter what the other axis specify. | ||
215 | // The check for RawVelocity.Z < 0 makes jumping work (temporary upward force). | ||
216 | if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding) | 220 | if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding) |
217 | { | 221 | { |
218 | if (m_controllingPrim.RawVelocity.Z < 0) | 222 | stepVelocity.Z = m_controllingPrim.RawVelocity.Z; |
223 | } | ||
224 | |||
225 | |||
226 | // Colliding and not flying with an upward force. The avatar must be trying to jump. | ||
227 | if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0) | ||
228 | { | ||
229 | // We allow the upward force to happen for this many frames. | ||
230 | m_jumpFrames = BSParam.AvatarJumpFrames; | ||
231 | m_jumpVelocity = stepVelocity.Z; | ||
232 | } | ||
233 | |||
234 | // The case where the avatar is not colliding and is not flying is special. | ||
235 | // The avatar is either falling or jumping and the user can be applying force to the avatar | ||
236 | // (force in some direction or force up or down). | ||
237 | // If the avatar has negative Z velocity and is not colliding, presume we're falling and keep the velocity. | ||
238 | // If the user is trying to apply upward force but we're not colliding, assume the avatar | ||
239 | // is trying to jump and don't apply the upward force if not touching the ground any more. | ||
240 | if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding) | ||
241 | { | ||
242 | // If upward velocity is being applied, this must be a jump and only allow that to go on so long | ||
243 | if (m_jumpFrames > 0) | ||
244 | { | ||
245 | // Since not touching the ground, only apply upward force for so long. | ||
246 | m_jumpFrames--; | ||
247 | stepVelocity.Z = m_jumpVelocity; | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | // Since we're not affected by anything, whatever vertical motion the avatar has, continue that. | ||
219 | stepVelocity.Z = m_controllingPrim.RawVelocity.Z; | 252 | stepVelocity.Z = m_controllingPrim.RawVelocity.Z; |
253 | } | ||
220 | // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); | 254 | // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); |
221 | } | 255 | } |
222 | 256 | ||
@@ -241,7 +275,7 @@ public class BSActorAvatarMove : BSActor | |||
241 | m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4},avHeight={5}", | 275 | m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4},avHeight={5}", |
242 | m_controllingPrim.LocalID, m_controllingPrim.IsColliding, m_controllingPrim.Flying, | 276 | m_controllingPrim.LocalID, m_controllingPrim.IsColliding, m_controllingPrim.Flying, |
243 | m_controllingPrim.TargetVelocitySpeed, m_controllingPrim.CollisionsLastTick.Count, m_controllingPrim.Size.Z); | 277 | m_controllingPrim.TargetVelocitySpeed, m_controllingPrim.CollisionsLastTick.Count, m_controllingPrim.Size.Z); |
244 | // This test is done if moving forward, not flying and is colliding with something. | 278 | |
245 | // Check for stairs climbing if colliding, not flying and moving forward | 279 | // Check for stairs climbing if colliding, not flying and moving forward |
246 | if ( m_controllingPrim.IsColliding | 280 | if ( m_controllingPrim.IsColliding |
247 | && !m_controllingPrim.Flying | 281 | && !m_controllingPrim.Flying |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 311cf4f..07e87d1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -209,7 +209,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
209 | m_VhoverTimescale = Math.Max(pValue, 0.01f); | 209 | m_VhoverTimescale = Math.Max(pValue, 0.01f); |
210 | break; | 210 | break; |
211 | case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: | 211 | case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: |
212 | m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); | 212 | m_linearDeflectionEfficiency = ClampInRange(0f, pValue, 1f); |
213 | break; | 213 | break; |
214 | case Vehicle.LINEAR_DEFLECTION_TIMESCALE: | 214 | case Vehicle.LINEAR_DEFLECTION_TIMESCALE: |
215 | m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); | 215 | m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); |
@@ -707,7 +707,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
707 | private Vector3 m_knownRotationalVelocity; | 707 | private Vector3 m_knownRotationalVelocity; |
708 | private Vector3 m_knownRotationalForce; | 708 | private Vector3 m_knownRotationalForce; |
709 | private Vector3 m_knownRotationalImpulse; | 709 | private Vector3 m_knownRotationalImpulse; |
710 | private Vector3 m_knownForwardVelocity; // vehicle relative forward speed | ||
711 | 710 | ||
712 | private const int m_knownChangedPosition = 1 << 0; | 711 | private const int m_knownChangedPosition = 1 << 0; |
713 | private const int m_knownChangedVelocity = 1 << 1; | 712 | private const int m_knownChangedVelocity = 1 << 1; |
@@ -719,7 +718,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
719 | private const int m_knownChangedRotationalImpulse = 1 << 7; | 718 | private const int m_knownChangedRotationalImpulse = 1 << 7; |
720 | private const int m_knownChangedTerrainHeight = 1 << 8; | 719 | private const int m_knownChangedTerrainHeight = 1 << 8; |
721 | private const int m_knownChangedWaterLevel = 1 << 9; | 720 | private const int m_knownChangedWaterLevel = 1 << 9; |
722 | private const int m_knownChangedForwardVelocity = 1 <<10; | ||
723 | 721 | ||
724 | public void ForgetKnownVehicleProperties() | 722 | public void ForgetKnownVehicleProperties() |
725 | { | 723 | { |
@@ -923,12 +921,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
923 | { | 921 | { |
924 | get | 922 | get |
925 | { | 923 | { |
926 | if ((m_knownHas & m_knownChangedForwardVelocity) == 0) | 924 | return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); |
927 | { | ||
928 | m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); | ||
929 | m_knownHas |= m_knownChangedForwardVelocity; | ||
930 | } | ||
931 | return m_knownForwardVelocity; | ||
932 | } | 925 | } |
933 | } | 926 | } |
934 | private float VehicleForwardSpeed | 927 | private float VehicleForwardSpeed |
@@ -981,6 +974,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
981 | { | 974 | { |
982 | ComputeLinearVelocity(pTimestep); | 975 | ComputeLinearVelocity(pTimestep); |
983 | 976 | ||
977 | ComputeLinearDeflection(pTimestep); | ||
978 | |||
984 | ComputeLinearTerrainHeightCorrection(pTimestep); | 979 | ComputeLinearTerrainHeightCorrection(pTimestep); |
985 | 980 | ||
986 | ComputeLinearHover(pTimestep); | 981 | ComputeLinearHover(pTimestep); |
@@ -1026,12 +1021,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1026 | { | 1021 | { |
1027 | // Step the motor from the current value. Get the correction needed this step. | 1022 | // Step the motor from the current value. Get the correction needed this step. |
1028 | Vector3 origVelW = VehicleVelocity; // DEBUG | 1023 | Vector3 origVelW = VehicleVelocity; // DEBUG |
1029 | Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); | 1024 | Vector3 currentVelV = VehicleForwardVelocity; |
1030 | Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV); | 1025 | Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV); |
1031 | 1026 | ||
1032 | // Friction reduces vehicle motion | 1027 | // Friction reduces vehicle motion based on absolute speed. Slow vehicle down by friction. |
1033 | Vector3 frictionFactorW = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep); | 1028 | Vector3 frictionFactorV = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep); |
1034 | linearMotorCorrectionV -= (currentVelV * frictionFactorW); | 1029 | linearMotorCorrectionV -= (currentVelV * frictionFactorV); |
1035 | 1030 | ||
1036 | // Motor is vehicle coordinates. Rotate it to world coordinates | 1031 | // Motor is vehicle coordinates. Rotate it to world coordinates |
1037 | Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; | 1032 | Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; |
@@ -1046,11 +1041,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1046 | // Add this correction to the velocity to make it faster/slower. | 1041 | // Add this correction to the velocity to make it faster/slower. |
1047 | VehicleVelocity += linearMotorVelocityW; | 1042 | VehicleVelocity += linearMotorVelocityW; |
1048 | 1043 | ||
1049 | |||
1050 | |||
1051 | VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}", | 1044 | VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}", |
1052 | ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, | 1045 | ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, |
1053 | linearMotorVelocityW, VehicleVelocity, frictionFactorW); | 1046 | linearMotorVelocityW, VehicleVelocity, frictionFactorV); |
1047 | } | ||
1048 | |||
1049 | //Given a Deflection Effiency and a Velocity, Returns a Velocity that is Partially Deflected onto the X Axis | ||
1050 | //Clamped so that a DeflectionTimescale of less then 1 does not increase force over original velocity | ||
1051 | private void ComputeLinearDeflection(float pTimestep) | ||
1052 | { | ||
1053 | Vector3 linearDeflectionV = Vector3.Zero; | ||
1054 | Vector3 velocityV = VehicleForwardVelocity; | ||
1055 | |||
1056 | // Velocity in Y and Z dimensions is movement to the side or turning. | ||
1057 | // Compute deflection factor from the to the side and rotational velocity | ||
1058 | linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y); | ||
1059 | linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z); | ||
1060 | |||
1061 | // Velocity to the side and around is corrected and moved into the forward direction | ||
1062 | linearDeflectionV.X += Math.Abs(linearDeflectionV.Y); | ||
1063 | linearDeflectionV.X += Math.Abs(linearDeflectionV.Z); | ||
1064 | |||
1065 | // Scale the deflection to the fractional simulation time | ||
1066 | linearDeflectionV *= pTimestep; | ||
1067 | |||
1068 | // Subtract the sideways and rotational velocity deflection factors while adding the correction forward | ||
1069 | linearDeflectionV *= new Vector3(1,-1,-1); | ||
1070 | |||
1071 | // Correciont is vehicle relative. Convert to world coordinates and add to the velocity | ||
1072 | VehicleVelocity += linearDeflectionV * VehicleOrientation; | ||
1073 | |||
1074 | VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}", | ||
1075 | ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV); | ||
1054 | } | 1076 | } |
1055 | 1077 | ||
1056 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) | 1078 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) |
@@ -1652,6 +1674,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1652 | return frictionFactor; | 1674 | return frictionFactor; |
1653 | } | 1675 | } |
1654 | 1676 | ||
1677 | private float SortedClampInRange(float clampa, float val, float clampb) | ||
1678 | { | ||
1679 | if (clampa > clampb) | ||
1680 | { | ||
1681 | float temp = clampa; | ||
1682 | clampa = clampb; | ||
1683 | clampb = temp; | ||
1684 | } | ||
1685 | return ClampInRange(clampa, val, clampb); | ||
1686 | |||
1687 | } | ||
1688 | |||
1655 | private float ClampInRange(float low, float val, float high) | 1689 | private float ClampInRange(float low, float val, float high) |
1656 | { | 1690 | { |
1657 | return Math.Max(low, Math.Min(val, high)); | 1691 | return Math.Max(low, Math.Min(val, high)); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index aad1108..6437b04 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -134,6 +134,7 @@ public static class BSParam | |||
134 | public static float AvatarHeightMidFudge { get; private set; } | 134 | public static float AvatarHeightMidFudge { get; private set; } |
135 | public static float AvatarHeightHighFudge { get; private set; } | 135 | public static float AvatarHeightHighFudge { get; private set; } |
136 | public static float AvatarContactProcessingThreshold { get; private set; } | 136 | public static float AvatarContactProcessingThreshold { get; private set; } |
137 | public static int AvatarJumpFrames { get; private set; } | ||
137 | public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } | 138 | public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } |
138 | public static float AvatarStepHeight { get; private set; } | 139 | public static float AvatarStepHeight { get; private set; } |
139 | public static float AvatarStepApproachFactor { get; private set; } | 140 | public static float AvatarStepApproachFactor { get; private set; } |
@@ -567,6 +568,8 @@ public static class BSParam | |||
567 | 0.1f ), | 568 | 0.1f ), |
568 | new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", | 569 | new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", |
569 | 1.0f ), | 570 | 1.0f ), |
571 | new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.", | ||
572 | 4 ), | ||
570 | new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", | 573 | new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", |
571 | 0.6f ) , | 574 | 0.6f ) , |
572 | new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", | 575 | new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", |
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index b13c87d..667cef8 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs | |||
@@ -34,6 +34,7 @@ using System.Text; | |||
34 | using System.Xml; | 34 | using System.Xml; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Console; | 36 | using OpenSim.Framework.Console; |
37 | using OpenSim.Framework.Monitoring; | ||
37 | using OpenSim.Framework.Servers; | 38 | using OpenSim.Framework.Servers; |
38 | using log4net; | 39 | using log4net; |
39 | using log4net.Config; | 40 | using log4net.Config; |
@@ -190,16 +191,7 @@ namespace OpenSim.Server.Base | |||
190 | } | 191 | } |
191 | 192 | ||
192 | RegisterCommonCommands(); | 193 | RegisterCommonCommands(); |
193 | 194 | RegisterCommonComponents(Config); | |
194 | // Register the quit command | ||
195 | // | ||
196 | MainConsole.Instance.Commands.AddCommand("General", false, "quit", | ||
197 | "quit", | ||
198 | "Quit the application", HandleQuit); | ||
199 | |||
200 | MainConsole.Instance.Commands.AddCommand("General", false, "shutdown", | ||
201 | "shutdown", | ||
202 | "Quit the application", HandleQuit); | ||
203 | 195 | ||
204 | // Allow derived classes to perform initialization that | 196 | // Allow derived classes to perform initialization that |
205 | // needs to be done after the console has opened | 197 | // needs to be done after the console has opened |
@@ -214,6 +206,9 @@ namespace OpenSim.Server.Base | |||
214 | 206 | ||
215 | public virtual int Run() | 207 | public virtual int Run() |
216 | { | 208 | { |
209 | Watchdog.Enabled = true; | ||
210 | MemoryWatchdog.Enabled = true; | ||
211 | |||
217 | while (m_Running) | 212 | while (m_Running) |
218 | { | 213 | { |
219 | try | 214 | try |
@@ -231,11 +226,12 @@ namespace OpenSim.Server.Base | |||
231 | return 0; | 226 | return 0; |
232 | } | 227 | } |
233 | 228 | ||
234 | protected virtual void HandleQuit(string module, string[] args) | 229 | protected override void ShutdownSpecific() |
235 | { | 230 | { |
236 | m_Running = false; | 231 | m_Running = false; |
237 | m_log.Info("[CONSOLE] Quitting"); | 232 | m_log.Info("[CONSOLE] Quitting"); |
238 | 233 | ||
234 | base.ShutdownSpecific(); | ||
239 | } | 235 | } |
240 | 236 | ||
241 | protected virtual void ReadConfig() | 237 | protected virtual void ReadConfig() |
@@ -246,4 +242,4 @@ namespace OpenSim.Server.Base | |||
246 | { | 242 | { |
247 | } | 243 | } |
248 | } | 244 | } |
249 | } | 245 | } \ No newline at end of file |
diff --git a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs index cf1af15..adc2fbc 100644 --- a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs | |||
@@ -61,7 +61,7 @@ namespace OpenSim.Server.Handlers.Hypergrid | |||
61 | m_Proxy = proxy; | 61 | m_Proxy = proxy; |
62 | } | 62 | } |
63 | 63 | ||
64 | protected override bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) | 64 | protected override bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason) |
65 | { | 65 | { |
66 | return m_GatekeeperService.LoginAgent(aCircuit, destination, out reason); | 66 | return m_GatekeeperService.LoginAgent(aCircuit, destination, out reason); |
67 | } | 67 | } |
diff --git a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs index 968c1e6..df875af 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs | |||
@@ -49,191 +49,87 @@ using log4net; | |||
49 | 49 | ||
50 | namespace OpenSim.Server.Handlers.Hypergrid | 50 | namespace OpenSim.Server.Handlers.Hypergrid |
51 | { | 51 | { |
52 | public class HomeAgentHandler | 52 | public class HomeAgentHandler : AgentPostHandler |
53 | { | 53 | { |
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 IUserAgentService m_UserAgentService; | 55 | private IUserAgentService m_UserAgentService; |
56 | 56 | ||
57 | private string m_LoginServerIP; | 57 | private string m_LoginServerIP; |
58 | private bool m_Proxy = false; | ||
59 | 58 | ||
60 | public HomeAgentHandler(IUserAgentService userAgentService, string loginServerIP, bool proxy) | 59 | public HomeAgentHandler(IUserAgentService userAgentService, string loginServerIP, bool proxy) : |
60 | base("/homeagent") | ||
61 | { | 61 | { |
62 | m_UserAgentService = userAgentService; | 62 | m_UserAgentService = userAgentService; |
63 | m_LoginServerIP = loginServerIP; | 63 | m_LoginServerIP = loginServerIP; |
64 | m_Proxy = proxy; | 64 | m_Proxy = proxy; |
65 | } | 65 | } |
66 | 66 | ||
67 | public Hashtable Handler(Hashtable request) | 67 | protected override AgentDestinationData CreateAgentDestinationData() |
68 | { | 68 | { |
69 | // m_log.Debug("[CONNECTION DEBUGGING]: HomeAgentHandler Called"); | 69 | return new ExtendedAgentDestinationData(); |
70 | // | 70 | } |
71 | // m_log.Debug("---------------------------"); | 71 | protected override void UnpackData(OSDMap args, AgentDestinationData d, Hashtable request) |
72 | // m_log.Debug(" >> uri=" + request["uri"]); | 72 | { |
73 | // m_log.Debug(" >> content-type=" + request["content-type"]); | 73 | base.UnpackData(args, d, request); |
74 | // m_log.Debug(" >> http-method=" + request["http-method"]); | 74 | ExtendedAgentDestinationData data = (ExtendedAgentDestinationData)d; |
75 | // m_log.Debug("---------------------------\n"); | 75 | try |
76 | |||
77 | Hashtable responsedata = new Hashtable(); | ||
78 | responsedata["content_type"] = "text/html"; | ||
79 | responsedata["keepalive"] = false; | ||
80 | |||
81 | |||
82 | UUID agentID; | ||
83 | UUID regionID; | ||
84 | string action; | ||
85 | if (!Utils.GetParams((string)request["uri"], out agentID, out regionID, out action)) | ||
86 | { | 76 | { |
87 | m_log.InfoFormat("[HOME AGENT HANDLER]: Invalid parameters for agent message {0}", request["uri"]); | 77 | if (args.ContainsKey("gatekeeper_host") && args["gatekeeper_host"] != null) |
88 | responsedata["int_response_code"] = 404; | 78 | data.host = args["gatekeeper_host"].AsString(); |
89 | responsedata["str_response_string"] = "false"; | 79 | if (args.ContainsKey("gatekeeper_port") && args["gatekeeper_port"] != null) |
80 | Int32.TryParse(args["gatekeeper_port"].AsString(), out data.port); | ||
81 | if (args.ContainsKey("gatekeeper_serveruri") && args["gatekeeper_serveruri"] != null) | ||
82 | data.gatekeeperServerURI = args["gatekeeper_serveruri"]; | ||
83 | if (args.ContainsKey("destination_serveruri") && args["destination_serveruri"] != null) | ||
84 | data.destinationServerURI = args["destination_serveruri"]; | ||
90 | 85 | ||
91 | return responsedata; | ||
92 | } | 86 | } |
93 | 87 | catch (InvalidCastException e) | |
94 | // Next, let's parse the verb | ||
95 | string method = (string)request["http-method"]; | ||
96 | if (method.Equals("POST")) | ||
97 | { | 88 | { |
98 | DoAgentPost(request, responsedata, agentID); | 89 | m_log.ErrorFormat("[HOME AGENT HANDLER]: Bad cast in UnpackData"); |
99 | return responsedata; | ||
100 | } | 90 | } |
101 | else | ||
102 | { | ||
103 | m_log.InfoFormat("[HOME AGENT HANDLER]: method {0} not supported in agent message", method); | ||
104 | responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; | ||
105 | responsedata["str_response_string"] = "Method not allowed"; | ||
106 | 91 | ||
107 | return responsedata; | 92 | string callerIP = GetCallerIP(request); |
108 | } | 93 | // Verify if this call came from the login server |
94 | if (callerIP == m_LoginServerIP) | ||
95 | data.fromLogin = true; | ||
109 | 96 | ||
110 | } | 97 | } |
111 | 98 | ||
112 | protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) | 99 | protected override GridRegion ExtractGatekeeper(AgentDestinationData d) |
113 | { | 100 | { |
114 | OSDMap args = Utils.GetOSDMap((string)request["body"]); | 101 | if (d is ExtendedAgentDestinationData) |
115 | if (args == null) | ||
116 | { | 102 | { |
117 | responsedata["int_response_code"] = HttpStatusCode.BadRequest; | 103 | ExtendedAgentDestinationData data = (ExtendedAgentDestinationData)d; |
118 | responsedata["str_response_string"] = "Bad request"; | 104 | GridRegion gatekeeper = new GridRegion(); |
119 | return; | 105 | gatekeeper.ServerURI = data.gatekeeperServerURI; |
106 | gatekeeper.ExternalHostName = data.host; | ||
107 | gatekeeper.HttpPort = (uint)data.port; | ||
108 | gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||
109 | |||
110 | return gatekeeper; | ||
120 | } | 111 | } |
121 | |||
122 | // retrieve the input arguments | ||
123 | int x = 0, y = 0; | ||
124 | UUID uuid = UUID.Zero; | ||
125 | string regionname = string.Empty; | ||
126 | string gatekeeper_host = string.Empty; | ||
127 | string gatekeeper_serveruri = string.Empty; | ||
128 | string destination_serveruri = string.Empty; | ||
129 | int gatekeeper_port = 0; | ||
130 | IPEndPoint client_ipaddress = null; | ||
131 | |||
132 | if (args.ContainsKey("gatekeeper_host") && args["gatekeeper_host"] != null) | ||
133 | gatekeeper_host = args["gatekeeper_host"].AsString(); | ||
134 | if (args.ContainsKey("gatekeeper_port") && args["gatekeeper_port"] != null) | ||
135 | Int32.TryParse(args["gatekeeper_port"].AsString(), out gatekeeper_port); | ||
136 | if (args.ContainsKey("gatekeeper_serveruri") && args["gatekeeper_serveruri"] !=null) | ||
137 | gatekeeper_serveruri = args["gatekeeper_serveruri"]; | ||
138 | if (args.ContainsKey("destination_serveruri") && args["destination_serveruri"] !=null) | ||
139 | destination_serveruri = args["destination_serveruri"]; | ||
140 | |||
141 | GridRegion gatekeeper = new GridRegion(); | ||
142 | gatekeeper.ServerURI = gatekeeper_serveruri; | ||
143 | gatekeeper.ExternalHostName = gatekeeper_host; | ||
144 | gatekeeper.HttpPort = (uint)gatekeeper_port; | ||
145 | gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||
146 | |||
147 | if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||
148 | Int32.TryParse(args["destination_x"].AsString(), out x); | ||
149 | else | 112 | else |
150 | m_log.WarnFormat(" -- request didn't have destination_x"); | 113 | m_log.WarnFormat("[HOME AGENT HANDLER]: Wrong data type"); |
151 | if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||
152 | Int32.TryParse(args["destination_y"].AsString(), out y); | ||
153 | else | ||
154 | m_log.WarnFormat(" -- request didn't have destination_y"); | ||
155 | if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||
156 | UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||
157 | if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||
158 | regionname = args["destination_name"].ToString(); | ||
159 | |||
160 | if (args.ContainsKey("client_ip") && args["client_ip"] != null) | ||
161 | { | ||
162 | string ip_str = args["client_ip"].ToString(); | ||
163 | try | ||
164 | { | ||
165 | string callerIP = GetCallerIP(request); | ||
166 | // Verify if this caller has authority to send the client IP | ||
167 | if (callerIP == m_LoginServerIP) | ||
168 | client_ipaddress = new IPEndPoint(IPAddress.Parse(ip_str), 0); | ||
169 | else // leaving this for now, but this warning should be removed | ||
170 | m_log.WarnFormat("[HOME AGENT HANDLER]: Unauthorized machine {0} tried to set client ip to {1}", callerIP, ip_str); | ||
171 | } | ||
172 | catch | ||
173 | { | ||
174 | m_log.DebugFormat("[HOME AGENT HANDLER]: Exception parsing client ip address from {0}", ip_str); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | GridRegion destination = new GridRegion(); | ||
179 | destination.RegionID = uuid; | ||
180 | destination.RegionLocX = x; | ||
181 | destination.RegionLocY = y; | ||
182 | destination.RegionName = regionname; | ||
183 | destination.ServerURI = destination_serveruri; | ||
184 | |||
185 | AgentCircuitData aCircuit = new AgentCircuitData(); | ||
186 | try | ||
187 | { | ||
188 | aCircuit.UnpackAgentCircuitData(args); | ||
189 | } | ||
190 | catch (Exception ex) | ||
191 | { | ||
192 | m_log.InfoFormat("[HOME AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message); | ||
193 | responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||
194 | responsedata["str_response_string"] = "Bad request"; | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | OSDMap resp = new OSDMap(2); | ||
199 | string reason = String.Empty; | ||
200 | 114 | ||
201 | bool result = m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, client_ipaddress, out reason); | 115 | return null; |
202 | |||
203 | resp["reason"] = OSD.FromString(reason); | ||
204 | resp["success"] = OSD.FromBoolean(result); | ||
205 | |||
206 | // TODO: add reason if not String.Empty? | ||
207 | responsedata["int_response_code"] = HttpStatusCode.OK; | ||
208 | responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); | ||
209 | } | 116 | } |
210 | 117 | ||
211 | private string GetCallerIP(Hashtable request) | ||
212 | { | ||
213 | if (!m_Proxy) | ||
214 | return Util.GetCallerIP(request); | ||
215 | |||
216 | // We're behind a proxy | ||
217 | Hashtable headers = (Hashtable)request["headers"]; | ||
218 | string xff = "X-Forwarded-For"; | ||
219 | if (headers.ContainsKey(xff.ToLower())) | ||
220 | xff = xff.ToLower(); | ||
221 | 118 | ||
222 | if (!headers.ContainsKey(xff) || headers[xff] == null) | 119 | protected override bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason) |
223 | { | 120 | { |
224 | m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); | 121 | return m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, fromLogin, out reason); |
225 | return Util.GetCallerIP(request); | 122 | } |
226 | } | ||
227 | 123 | ||
228 | m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); | 124 | } |
229 | 125 | ||
230 | IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); | 126 | public class ExtendedAgentDestinationData : AgentDestinationData |
231 | if (ep != null) | 127 | { |
232 | return ep.Address.ToString(); | 128 | public string host; |
129 | public int port; | ||
130 | public string gatekeeperServerURI; | ||
131 | public string destinationServerURI; | ||
233 | 132 | ||
234 | // Oops | ||
235 | return Util.GetCallerIP(request); | ||
236 | } | ||
237 | } | 133 | } |
238 | 134 | ||
239 | } | 135 | } |
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index b20f467..d9c1bd3 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs | |||
@@ -108,7 +108,7 @@ namespace OpenSim.Server.Handlers.Hypergrid | |||
108 | server.AddXmlRPCHandler("get_uui", GetUUI, false); | 108 | server.AddXmlRPCHandler("get_uui", GetUUI, false); |
109 | server.AddXmlRPCHandler("get_uuid", GetUUID, false); | 109 | server.AddXmlRPCHandler("get_uuid", GetUUID, false); |
110 | 110 | ||
111 | server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); | 111 | server.AddStreamHandler(new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy)); |
112 | } | 112 | } |
113 | 113 | ||
114 | public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient) | 114 | public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient) |
diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index ae37ca7..71a9e6f 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | |||
@@ -328,31 +328,16 @@ namespace OpenSim.Server.Handlers.Simulation | |||
328 | return; | 328 | return; |
329 | } | 329 | } |
330 | 330 | ||
331 | // retrieve the input arguments | 331 | AgentDestinationData data = CreateAgentDestinationData(); |
332 | int x = 0, y = 0; | 332 | UnpackData(args, data, request); |
333 | UUID uuid = UUID.Zero; | ||
334 | string regionname = string.Empty; | ||
335 | uint teleportFlags = 0; | ||
336 | if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||
337 | Int32.TryParse(args["destination_x"].AsString(), out x); | ||
338 | else | ||
339 | m_log.WarnFormat(" -- request didn't have destination_x"); | ||
340 | if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||
341 | Int32.TryParse(args["destination_y"].AsString(), out y); | ||
342 | else | ||
343 | m_log.WarnFormat(" -- request didn't have destination_y"); | ||
344 | if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||
345 | UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||
346 | if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||
347 | regionname = args["destination_name"].ToString(); | ||
348 | if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null) | ||
349 | teleportFlags = args["teleport_flags"].AsUInteger(); | ||
350 | 333 | ||
351 | GridRegion destination = new GridRegion(); | 334 | GridRegion destination = new GridRegion(); |
352 | destination.RegionID = uuid; | 335 | destination.RegionID = data.uuid; |
353 | destination.RegionLocX = x; | 336 | destination.RegionLocX = data.x; |
354 | destination.RegionLocY = y; | 337 | destination.RegionLocY = data.y; |
355 | destination.RegionName = regionname; | 338 | destination.RegionName = data.name; |
339 | |||
340 | GridRegion gatekeeper = ExtractGatekeeper(data); | ||
356 | 341 | ||
357 | AgentCircuitData aCircuit = new AgentCircuitData(); | 342 | AgentCircuitData aCircuit = new AgentCircuitData(); |
358 | try | 343 | try |
@@ -373,7 +358,7 @@ namespace OpenSim.Server.Handlers.Simulation | |||
373 | // This is the meaning of POST agent | 358 | // This is the meaning of POST agent |
374 | //m_regionClient.AdjustUserInformation(aCircuit); | 359 | //m_regionClient.AdjustUserInformation(aCircuit); |
375 | //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | 360 | //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); |
376 | bool result = CreateAgent(destination, aCircuit, teleportFlags, out reason); | 361 | bool result = CreateAgent(gatekeeper, destination, aCircuit, data.flags, data.fromLogin, out reason); |
377 | 362 | ||
378 | resp["reason"] = OSD.FromString(reason); | 363 | resp["reason"] = OSD.FromString(reason); |
379 | resp["success"] = OSD.FromBoolean(result); | 364 | resp["success"] = OSD.FromBoolean(result); |
@@ -385,7 +370,36 @@ namespace OpenSim.Server.Handlers.Simulation | |||
385 | responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); | 370 | responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); |
386 | } | 371 | } |
387 | 372 | ||
388 | private string GetCallerIP(Hashtable request) | 373 | protected virtual AgentDestinationData CreateAgentDestinationData() |
374 | { | ||
375 | return new AgentDestinationData(); | ||
376 | } | ||
377 | |||
378 | protected virtual void UnpackData(OSDMap args, AgentDestinationData data, Hashtable request) | ||
379 | { | ||
380 | // retrieve the input arguments | ||
381 | if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||
382 | Int32.TryParse(args["destination_x"].AsString(), out data.x); | ||
383 | else | ||
384 | m_log.WarnFormat(" -- request didn't have destination_x"); | ||
385 | if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||
386 | Int32.TryParse(args["destination_y"].AsString(), out data.y); | ||
387 | else | ||
388 | m_log.WarnFormat(" -- request didn't have destination_y"); | ||
389 | if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||
390 | UUID.TryParse(args["destination_uuid"].AsString(), out data.uuid); | ||
391 | if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||
392 | data.name = args["destination_name"].ToString(); | ||
393 | if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null) | ||
394 | data.flags = args["teleport_flags"].AsUInteger(); | ||
395 | } | ||
396 | |||
397 | protected virtual GridRegion ExtractGatekeeper(AgentDestinationData data) | ||
398 | { | ||
399 | return null; | ||
400 | } | ||
401 | |||
402 | protected string GetCallerIP(Hashtable request) | ||
389 | { | 403 | { |
390 | if (!m_Proxy) | 404 | if (!m_Proxy) |
391 | return Util.GetCallerIP(request); | 405 | return Util.GetCallerIP(request); |
@@ -418,7 +432,7 @@ namespace OpenSim.Server.Handlers.Simulation | |||
418 | } | 432 | } |
419 | 433 | ||
420 | // subclasses can override this | 434 | // subclasses can override this |
421 | protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) | 435 | protected virtual bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason) |
422 | { | 436 | { |
423 | return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | 437 | return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); |
424 | } | 438 | } |
@@ -562,7 +576,6 @@ namespace OpenSim.Server.Handlers.Simulation | |||
562 | //agent.Dump(); | 576 | //agent.Dump(); |
563 | // This is one of the meanings of PUT agent | 577 | // This is one of the meanings of PUT agent |
564 | result = UpdateAgent(destination, agent); | 578 | result = UpdateAgent(destination, agent); |
565 | |||
566 | } | 579 | } |
567 | else if ("AgentPosition".Equals(messageType)) | 580 | else if ("AgentPosition".Equals(messageType)) |
568 | { | 581 | { |
@@ -593,4 +606,14 @@ namespace OpenSim.Server.Handlers.Simulation | |||
593 | return m_SimulationService.UpdateAgent(destination, agent); | 606 | return m_SimulationService.UpdateAgent(destination, agent); |
594 | } | 607 | } |
595 | } | 608 | } |
609 | |||
610 | public class AgentDestinationData | ||
611 | { | ||
612 | public int x; | ||
613 | public int y; | ||
614 | public string name; | ||
615 | public UUID uuid; | ||
616 | public uint flags; | ||
617 | public bool fromLogin; | ||
618 | } | ||
596 | } | 619 | } |
diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index 5bcff48..c9c6c31 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs | |||
@@ -53,7 +53,8 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
53 | 53 | ||
54 | private IAssetService m_AssetService; | 54 | private IAssetService m_AssetService; |
55 | 55 | ||
56 | public GatekeeperServiceConnector() : base() | 56 | public GatekeeperServiceConnector() |
57 | : base() | ||
57 | { | 58 | { |
58 | } | 59 | } |
59 | 60 | ||
@@ -123,11 +124,13 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
123 | realHandle = Convert.ToUInt64((string)hash["handle"]); | 124 | realHandle = Convert.ToUInt64((string)hash["handle"]); |
124 | //m_log.Debug(">> HERE, realHandle: " + realHandle); | 125 | //m_log.Debug(">> HERE, realHandle: " + realHandle); |
125 | } | 126 | } |
126 | if (hash["region_image"] != null) { | 127 | if (hash["region_image"] != null) |
128 | { | ||
127 | imageURL = (string)hash["region_image"]; | 129 | imageURL = (string)hash["region_image"]; |
128 | //m_log.Debug(">> HERE, imageURL: " + imageURL); | 130 | //m_log.Debug(">> HERE, imageURL: " + imageURL); |
129 | } | 131 | } |
130 | if (hash["external_name"] != null) { | 132 | if (hash["external_name"] != null) |
133 | { | ||
131 | externalName = (string)hash["external_name"]; | 134 | externalName = (string)hash["external_name"]; |
132 | //m_log.Debug(">> HERE, externalName: " + externalName); | 135 | //m_log.Debug(">> HERE, externalName: " + externalName); |
133 | } | 136 | } |
@@ -178,7 +181,7 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
178 | //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); | 181 | //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); |
179 | imageData = OpenJPEG.EncodeFromImage(bitmap, true); | 182 | imageData = OpenJPEG.EncodeFromImage(bitmap, true); |
180 | } | 183 | } |
181 | 184 | ||
182 | AssetBase ass = new AssetBase(UUID.Random(), "region " + name, (sbyte)AssetType.Texture, regionID.ToString()); | 185 | AssetBase ass = new AssetBase(UUID.Random(), "region " + name, (sbyte)AssetType.Texture, regionID.ToString()); |
183 | 186 | ||
184 | // !!! for now | 187 | // !!! for now |
@@ -257,7 +260,8 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
257 | region.RegionName = (string)hash["region_name"]; | 260 | region.RegionName = (string)hash["region_name"]; |
258 | //m_log.Debug(">> HERE, region_name: " + region.RegionName); | 261 | //m_log.Debug(">> HERE, region_name: " + region.RegionName); |
259 | } | 262 | } |
260 | if (hash["hostname"] != null) { | 263 | if (hash["hostname"] != null) |
264 | { | ||
261 | region.ExternalHostName = (string)hash["hostname"]; | 265 | region.ExternalHostName = (string)hash["hostname"]; |
262 | //m_log.Debug(">> HERE, hostname: " + region.ExternalHostName); | 266 | //m_log.Debug(">> HERE, hostname: " + region.ExternalHostName); |
263 | } | 267 | } |
@@ -275,10 +279,10 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
275 | region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); | 279 | region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); |
276 | //m_log.Debug(">> HERE, internal_port: " + region.InternalEndPoint); | 280 | //m_log.Debug(">> HERE, internal_port: " + region.InternalEndPoint); |
277 | } | 281 | } |
278 | 282 | ||
279 | if (hash["server_uri"] != null) | 283 | if (hash["server_uri"] != null) |
280 | { | 284 | { |
281 | region.ServerURI = (string) hash["server_uri"]; | 285 | region.ServerURI = (string)hash["server_uri"]; |
282 | //m_log.Debug(">> HERE, server_uri: " + region.ServerURI); | 286 | //m_log.Debug(">> HERE, server_uri: " + region.ServerURI); |
283 | } | 287 | } |
284 | 288 | ||
@@ -295,55 +299,5 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
295 | 299 | ||
296 | return null; | 300 | return null; |
297 | } | 301 | } |
298 | |||
299 | public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string myipaddress, out string reason) | ||
300 | { | ||
301 | // m_log.DebugFormat("[GATEKEEPER SERVICE CONNECTOR]: CreateAgent start"); | ||
302 | |||
303 | myipaddress = String.Empty; | ||
304 | reason = String.Empty; | ||
305 | |||
306 | if (destination == null) | ||
307 | { | ||
308 | m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Given destination is null"); | ||
309 | return false; | ||
310 | } | ||
311 | |||
312 | string uri = destination.ServerURI + AgentPath() + aCircuit.AgentID + "/"; | ||
313 | |||
314 | try | ||
315 | { | ||
316 | OSDMap args = aCircuit.PackAgentCircuitData(); | ||
317 | |||
318 | args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString()); | ||
319 | args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString()); | ||
320 | args["destination_name"] = OSD.FromString(destination.RegionName); | ||
321 | args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); | ||
322 | args["teleport_flags"] = OSD.FromString(flags.ToString()); | ||
323 | |||
324 | OSDMap result = WebUtil.PostToService(uri, args, 80000); | ||
325 | if (result["Success"].AsBoolean()) | ||
326 | { | ||
327 | OSDMap unpacked = (OSDMap)result["_Result"]; | ||
328 | |||
329 | if (unpacked != null) | ||
330 | { | ||
331 | reason = unpacked["reason"].AsString(); | ||
332 | myipaddress = unpacked["your_ip"].AsString(); | ||
333 | return unpacked["success"].AsBoolean(); | ||
334 | } | ||
335 | } | ||
336 | |||
337 | reason = result["Message"] != null ? result["Message"].AsString() : "error"; | ||
338 | return false; | ||
339 | } | ||
340 | catch (Exception e) | ||
341 | { | ||
342 | m_log.Warn("[REMOTE SIMULATION CONNECTOR]: CreateAgent failed with exception: " + e.ToString()); | ||
343 | reason = e.Message; | ||
344 | } | ||
345 | |||
346 | return false; | ||
347 | } | ||
348 | } | 302 | } |
349 | } | 303 | } |
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 47d0cce..d8a3184 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs | |||
@@ -44,13 +44,14 @@ using Nini.Config; | |||
44 | 44 | ||
45 | namespace OpenSim.Services.Connectors.Hypergrid | 45 | namespace OpenSim.Services.Connectors.Hypergrid |
46 | { | 46 | { |
47 | public class UserAgentServiceConnector : IUserAgentService | 47 | public class UserAgentServiceConnector : SimulationServiceConnector, IUserAgentService |
48 | { | 48 | { |
49 | private static readonly ILog m_log = | 49 | private static readonly ILog m_log = |
50 | LogManager.GetLogger( | 50 | LogManager.GetLogger( |
51 | MethodBase.GetCurrentMethod().DeclaringType); | 51 | MethodBase.GetCurrentMethod().DeclaringType); |
52 | 52 | ||
53 | string m_ServerURL; | 53 | private string m_ServerURL; |
54 | private GridRegion m_Gatekeeper; | ||
54 | 55 | ||
55 | public UserAgentServiceConnector(string url) : this(url, true) | 56 | public UserAgentServiceConnector(string url) : this(url, true) |
56 | { | 57 | { |
@@ -104,9 +105,15 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
104 | m_log.DebugFormat("[USER AGENT CONNECTOR]: UserAgentServiceConnector started for {0}", m_ServerURL); | 105 | m_log.DebugFormat("[USER AGENT CONNECTOR]: UserAgentServiceConnector started for {0}", m_ServerURL); |
105 | } | 106 | } |
106 | 107 | ||
108 | protected override string AgentPath() | ||
109 | { | ||
110 | return "homeagent/"; | ||
111 | } | ||
107 | 112 | ||
108 | // The Login service calls this interface with a non-null [client] ipaddress | 113 | // The Login service calls this interface with fromLogin=true |
109 | public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, IPEndPoint ipaddress, out string reason) | 114 | // Sims call it with fromLogin=false |
115 | // Either way, this is verified by the handler | ||
116 | public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, bool fromLogin, out string reason) | ||
110 | { | 117 | { |
111 | reason = String.Empty; | 118 | reason = String.Empty; |
112 | 119 | ||
@@ -117,119 +124,34 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
117 | return false; | 124 | return false; |
118 | } | 125 | } |
119 | 126 | ||
120 | string uri = m_ServerURL + "homeagent/" + aCircuit.AgentID + "/"; | 127 | GridRegion home = new GridRegion(); |
121 | 128 | home.ServerURI = m_ServerURL; | |
122 | Console.WriteLine(" >>> LoginAgentToGrid <<< " + uri); | 129 | home.RegionID = destination.RegionID; |
123 | 130 | home.RegionLocX = destination.RegionLocX; | |
124 | HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri); | 131 | home.RegionLocY = destination.RegionLocY; |
125 | AgentCreateRequest.Method = "POST"; | ||
126 | AgentCreateRequest.ContentType = "application/json"; | ||
127 | AgentCreateRequest.Timeout = 10000; | ||
128 | //AgentCreateRequest.KeepAlive = false; | ||
129 | //AgentCreateRequest.Headers.Add("Authorization", authKey); | ||
130 | |||
131 | // Fill it in | ||
132 | OSDMap args = PackCreateAgentArguments(aCircuit, gatekeeper, destination, ipaddress); | ||
133 | |||
134 | string strBuffer = ""; | ||
135 | byte[] buffer = new byte[1]; | ||
136 | try | ||
137 | { | ||
138 | strBuffer = OSDParser.SerializeJsonString(args); | ||
139 | Encoding str = Util.UTF8; | ||
140 | buffer = str.GetBytes(strBuffer); | ||
141 | |||
142 | } | ||
143 | catch (Exception e) | ||
144 | { | ||
145 | m_log.WarnFormat("[USER AGENT CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message); | ||
146 | // ignore. buffer will be empty, caller should check. | ||
147 | } | ||
148 | |||
149 | Stream os = null; | ||
150 | try | ||
151 | { // send the Post | ||
152 | AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send | ||
153 | os = AgentCreateRequest.GetRequestStream(); | ||
154 | os.Write(buffer, 0, strBuffer.Length); //Send it | ||
155 | m_log.InfoFormat("[USER AGENT CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}", | ||
156 | uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY); | ||
157 | } | ||
158 | //catch (WebException ex) | ||
159 | catch | ||
160 | { | ||
161 | //m_log.InfoFormat("[USER AGENT CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message); | ||
162 | reason = "cannot contact remote region"; | ||
163 | return false; | ||
164 | } | ||
165 | finally | ||
166 | { | ||
167 | if (os != null) | ||
168 | os.Close(); | ||
169 | } | ||
170 | |||
171 | // Let's wait for the response | ||
172 | //m_log.Info("[USER AGENT CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall"); | ||
173 | 132 | ||
174 | try | 133 | m_Gatekeeper = gatekeeper; |
175 | { | ||
176 | using (WebResponse webResponse = AgentCreateRequest.GetResponse()) | ||
177 | { | ||
178 | if (webResponse == null) | ||
179 | { | ||
180 | m_log.Info("[USER AGENT CONNECTOR]: Null reply on DoCreateChildAgentCall post"); | ||
181 | } | ||
182 | else | ||
183 | { | ||
184 | using (Stream s = webResponse.GetResponseStream()) | ||
185 | { | ||
186 | using (StreamReader sr = new StreamReader(s)) | ||
187 | { | ||
188 | string response = sr.ReadToEnd().Trim(); | ||
189 | m_log.InfoFormat("[USER AGENT CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response); | ||
190 | |||
191 | if (!String.IsNullOrEmpty(response)) | ||
192 | { | ||
193 | try | ||
194 | { | ||
195 | // we assume we got an OSDMap back | ||
196 | OSDMap r = Util.GetOSDMap(response); | ||
197 | bool success = r["success"].AsBoolean(); | ||
198 | reason = r["reason"].AsString(); | ||
199 | return success; | ||
200 | } | ||
201 | catch (NullReferenceException e) | ||
202 | { | ||
203 | m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message); | ||
204 | |||
205 | // check for old style response | ||
206 | if (response.ToLower().StartsWith("true")) | ||
207 | return true; | ||
208 | |||
209 | return false; | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | catch (WebException ex) | ||
218 | { | ||
219 | m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message); | ||
220 | reason = "Destination did not reply"; | ||
221 | return false; | ||
222 | } | ||
223 | 134 | ||
224 | return true; | 135 | Console.WriteLine(" >>> LoginAgentToGrid <<< " + home.ServerURI); |
225 | 136 | ||
137 | uint flags = fromLogin ? (uint)TeleportFlags.ViaLogin : (uint)TeleportFlags.ViaHome; | ||
138 | return CreateAgent(home, aCircuit, flags, out reason); | ||
226 | } | 139 | } |
227 | 140 | ||
228 | 141 | ||
229 | // The simulators call this interface | 142 | // The simulators call this interface |
230 | public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason) | 143 | public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason) |
231 | { | 144 | { |
232 | return LoginAgentToGrid(aCircuit, gatekeeper, destination, null, out reason); | 145 | return LoginAgentToGrid(aCircuit, gatekeeper, destination, false, out reason); |
146 | } | ||
147 | |||
148 | protected override void PackData(OSDMap args, AgentCircuitData aCircuit, GridRegion destination, uint flags) | ||
149 | { | ||
150 | base.PackData(args, aCircuit, destination, flags); | ||
151 | args["gatekeeper_serveruri"] = OSD.FromString(m_Gatekeeper.ServerURI); | ||
152 | args["gatekeeper_host"] = OSD.FromString(m_Gatekeeper.ExternalHostName); | ||
153 | args["gatekeeper_port"] = OSD.FromString(m_Gatekeeper.HttpPort.ToString()); | ||
154 | args["destination_serveruri"] = OSD.FromString(destination.ServerURI); | ||
233 | } | 155 | } |
234 | 156 | ||
235 | protected OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, IPEndPoint ipaddress) | 157 | protected OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, IPEndPoint ipaddress) |
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 57f2ffa..f51c809 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs | |||
@@ -79,11 +79,27 @@ namespace OpenSim.Services.Connectors.Simulation | |||
79 | return "agent/"; | 79 | return "agent/"; |
80 | } | 80 | } |
81 | 81 | ||
82 | protected virtual void PackData(OSDMap args, AgentCircuitData aCircuit, GridRegion destination, uint flags) | ||
83 | { | ||
84 | args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString()); | ||
85 | args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString()); | ||
86 | args["destination_name"] = OSD.FromString(destination.RegionName); | ||
87 | args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); | ||
88 | args["teleport_flags"] = OSD.FromString(flags.ToString()); | ||
89 | } | ||
90 | |||
82 | public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason) | 91 | public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason) |
83 | { | 92 | { |
84 | // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CreateAgent start"); | 93 | string tmp = String.Empty; |
85 | 94 | return CreateAgent(destination, aCircuit, flags, out tmp, out reason); | |
95 | } | ||
96 | |||
97 | public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string myipaddress, out string reason) | ||
98 | { | ||
99 | m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: Creating agent at {0}", destination.ServerURI); | ||
86 | reason = String.Empty; | 100 | reason = String.Empty; |
101 | myipaddress = String.Empty; | ||
102 | |||
87 | if (destination == null) | 103 | if (destination == null) |
88 | { | 104 | { |
89 | m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null"); | 105 | m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null"); |
@@ -95,12 +111,7 @@ namespace OpenSim.Services.Connectors.Simulation | |||
95 | try | 111 | try |
96 | { | 112 | { |
97 | OSDMap args = aCircuit.PackAgentCircuitData(); | 113 | OSDMap args = aCircuit.PackAgentCircuitData(); |
98 | 114 | PackData(args, aCircuit, destination, flags); | |
99 | args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString()); | ||
100 | args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString()); | ||
101 | args["destination_name"] = OSD.FromString(destination.RegionName); | ||
102 | args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); | ||
103 | args["teleport_flags"] = OSD.FromString(flags.ToString()); | ||
104 | 115 | ||
105 | OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000); | 116 | OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000); |
106 | bool success = result["success"].AsBoolean(); | 117 | bool success = result["success"].AsBoolean(); |
@@ -110,6 +121,7 @@ namespace OpenSim.Services.Connectors.Simulation | |||
110 | 121 | ||
111 | reason = data["reason"].AsString(); | 122 | reason = data["reason"].AsString(); |
112 | success = data["success"].AsBoolean(); | 123 | success = data["success"].AsBoolean(); |
124 | myipaddress = data["your_ip"].AsString(); | ||
113 | return success; | 125 | return success; |
114 | } | 126 | } |
115 | 127 | ||
@@ -124,6 +136,7 @@ namespace OpenSim.Services.Connectors.Simulation | |||
124 | 136 | ||
125 | reason = data["reason"].AsString(); | 137 | reason = data["reason"].AsString(); |
126 | success = data["success"].AsBoolean(); | 138 | success = data["success"].AsBoolean(); |
139 | myipaddress = data["your_ip"].AsString(); | ||
127 | m_log.WarnFormat( | 140 | m_log.WarnFormat( |
128 | "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); | 141 | "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); |
129 | return success; | 142 | return success; |
@@ -228,7 +241,7 @@ namespace OpenSim.Services.Connectors.Simulation | |||
228 | /// </summary> | 241 | /// </summary> |
229 | private bool UpdateAgent(GridRegion destination, IAgentData cAgentData, int timeout) | 242 | private bool UpdateAgent(GridRegion destination, IAgentData cAgentData, int timeout) |
230 | { | 243 | { |
231 | // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent start"); | 244 | // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent in {0}", destination.ServerURI); |
232 | 245 | ||
233 | // Eventually, we want to use a caps url instead of the agentID | 246 | // Eventually, we want to use a caps url instead of the agentID |
234 | string uri = destination.ServerURI + AgentPath() + cAgentData.AgentID + "/"; | 247 | string uri = destination.ServerURI + AgentPath() + cAgentData.AgentID + "/"; |
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 737e9c9..733993f 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs | |||
@@ -210,10 +210,10 @@ namespace OpenSim.Services.HypergridService | |||
210 | return home; | 210 | return home; |
211 | } | 211 | } |
212 | 212 | ||
213 | public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason) | 213 | public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason) |
214 | { | 214 | { |
215 | m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}", | 215 | m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}", |
216 | agentCircuit.firstname, agentCircuit.lastname, ((clientIP == null) ? "stored IP" : clientIP.Address.ToString()), gatekeeper.ServerURI); | 216 | agentCircuit.firstname, agentCircuit.lastname, (fromLogin ? agentCircuit.IPAddress : "stored IP"), gatekeeper.ServerURI); |
217 | 217 | ||
218 | string gridName = gatekeeper.ServerURI; | 218 | string gridName = gatekeeper.ServerURI; |
219 | 219 | ||
@@ -265,7 +265,7 @@ namespace OpenSim.Services.HypergridService | |||
265 | bool success = false; | 265 | bool success = false; |
266 | string myExternalIP = string.Empty; | 266 | string myExternalIP = string.Empty; |
267 | 267 | ||
268 | m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName); | 268 | m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID); |
269 | 269 | ||
270 | if (m_GridName == gridName) | 270 | if (m_GridName == gridName) |
271 | success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); | 271 | success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); |
@@ -296,8 +296,8 @@ namespace OpenSim.Services.HypergridService | |||
296 | 296 | ||
297 | m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP); | 297 | m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP); |
298 | // else set the IP addresses associated with this client | 298 | // else set the IP addresses associated with this client |
299 | if (clientIP != null) | 299 | if (fromLogin) |
300 | m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString(); | 300 | m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = agentCircuit.IPAddress; |
301 | m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP; | 301 | m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP; |
302 | 302 | ||
303 | return true; | 303 | return true; |
@@ -306,7 +306,7 @@ namespace OpenSim.Services.HypergridService | |||
306 | public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason) | 306 | public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason) |
307 | { | 307 | { |
308 | reason = string.Empty; | 308 | reason = string.Empty; |
309 | return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, null, out reason); | 309 | return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, false, out reason); |
310 | } | 310 | } |
311 | 311 | ||
312 | private void SetClientIP(UUID sessionID, string ip) | 312 | private void SetClientIP(UUID sessionID, string ip) |
diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs index 3dc877a..f9e7f08 100644 --- a/OpenSim/Services/Interfaces/IHypergridServices.cs +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs | |||
@@ -48,10 +48,7 @@ namespace OpenSim.Services.Interfaces | |||
48 | /// </summary> | 48 | /// </summary> |
49 | public interface IUserAgentService | 49 | public interface IUserAgentService |
50 | { | 50 | { |
51 | // called by login service only | 51 | bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason); |
52 | bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason); | ||
53 | // called by simulators | ||
54 | bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); | ||
55 | void LogoutAgent(UUID userID, UUID sessionID); | 52 | void LogoutAgent(UUID userID, UUID sessionID); |
56 | GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); | 53 | GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); |
57 | Dictionary<string, object> GetServerURLs(UUID userID); | 54 | Dictionary<string, object> GetServerURLs(UUID userID); |
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 10cf90f..fe43582 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs | |||
@@ -933,7 +933,7 @@ namespace OpenSim.Services.LLLoginService | |||
933 | private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason) | 933 | private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason) |
934 | { | 934 | { |
935 | m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName); | 935 | m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName); |
936 | if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, clientIP, out reason)) | 936 | if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, true, out reason)) |
937 | return true; | 937 | return true; |
938 | return false; | 938 | return false; |
939 | } | 939 | } |