diff options
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | 100 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | 95 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | 20 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs | 45 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 59 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 15 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 10 | ||||
-rw-r--r-- | OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | 134 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 | ||||
-rw-r--r-- | OpenSim/Services/InventoryService/XInventoryService.cs | 12 | ||||
-rw-r--r-- | OpenSim/Tools/pCampBot/pCampBot.cs | 3 | ||||
-rwxr-xr-x | bin/OpenSim.ini.example | 5 | ||||
-rw-r--r-- | bin/OpenSimDefaults.ini | 9 | ||||
-rw-r--r-- | bin/pCampBot.exe.config | 2 |
15 files changed, 388 insertions, 130 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index a38d231..01ce194 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -109,10 +109,11 @@ namespace OpenSim.Region.ClientStack.Linden | |||
109 | "Comms", | 109 | "Comms", |
110 | false, | 110 | false, |
111 | "debug eq", | 111 | "debug eq", |
112 | "debug eq [0|1]", | 112 | "debug eq [0|1|2]", |
113 | "Turn on event queue debugging", | 113 | "Turn on event queue debugging" |
114 | "debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n" | 114 | + "<= 0 - turns off all event queue logging" |
115 | + "debug eq 0 will turn off event queue debugging.", | 115 | + ">= 1 - turns on outgoing event logging" |
116 | + ">= 2 - turns on poll notification", | ||
116 | HandleDebugEq); | 117 | HandleDebugEq); |
117 | } | 118 | } |
118 | else | 119 | else |
@@ -235,19 +236,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
235 | // ClientClosed(client.AgentId); | 236 | // ClientClosed(client.AgentId); |
236 | // } | 237 | // } |
237 | 238 | ||
238 | private void ClientClosed(UUID AgentID, Scene scene) | 239 | private void ClientClosed(UUID agentID, Scene scene) |
239 | { | 240 | { |
240 | // m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); | 241 | // m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); |
241 | 242 | ||
242 | int count = 0; | 243 | int count = 0; |
243 | while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) | 244 | while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5) |
244 | { | 245 | { |
245 | Thread.Sleep(1000); | 246 | Thread.Sleep(1000); |
246 | } | 247 | } |
247 | 248 | ||
248 | lock (queues) | 249 | lock (queues) |
249 | { | 250 | { |
250 | queues.Remove(AgentID); | 251 | queues.Remove(agentID); |
251 | } | 252 | } |
252 | 253 | ||
253 | List<UUID> removeitems = new List<UUID>(); | 254 | List<UUID> removeitems = new List<UUID>(); |
@@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
256 | foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) | 257 | foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) |
257 | { | 258 | { |
258 | // m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); | 259 | // m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); |
259 | if (ky == AgentID) | 260 | if (ky == agentID) |
260 | { | 261 | { |
261 | removeitems.Add(ky); | 262 | removeitems.Add(ky); |
262 | } | 263 | } |
@@ -267,7 +268,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
267 | UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; | 268 | UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; |
268 | m_AvatarQueueUUIDMapping.Remove(ky); | 269 | m_AvatarQueueUUIDMapping.Remove(ky); |
269 | 270 | ||
270 | MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/"); | 271 | string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); |
272 | MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); | ||
273 | |||
274 | // m_log.DebugFormat( | ||
275 | // "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", | ||
276 | // eqgPath, agentID, m_scene.RegionInfo.RegionName); | ||
271 | } | 277 | } |
272 | } | 278 | } |
273 | 279 | ||
@@ -281,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
281 | { | 287 | { |
282 | searchval = m_QueueUUIDAvatarMapping[ky]; | 288 | searchval = m_QueueUUIDAvatarMapping[ky]; |
283 | 289 | ||
284 | if (searchval == AgentID) | 290 | if (searchval == agentID) |
285 | { | 291 | { |
286 | removeitems.Add(ky); | 292 | removeitems.Add(ky); |
287 | } | 293 | } |
@@ -305,6 +311,15 @@ namespace OpenSim.Region.ClientStack.Linden | |||
305 | //} | 311 | //} |
306 | } | 312 | } |
307 | 313 | ||
314 | /// <summary> | ||
315 | /// Generate an Event Queue Get handler path for the given eqg uuid. | ||
316 | /// </summary> | ||
317 | /// <param name='eqgUuid'></param> | ||
318 | private string GenerateEqgCapPath(UUID eqgUuid) | ||
319 | { | ||
320 | return string.Format("/CAPS/EQG/{0}/", eqgUuid); | ||
321 | } | ||
322 | |||
308 | public void OnRegisterCaps(UUID agentID, Caps caps) | 323 | public void OnRegisterCaps(UUID agentID, Caps caps) |
309 | { | 324 | { |
310 | // Register an event queue for the client | 325 | // Register an event queue for the client |
@@ -316,8 +331,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
316 | // Let's instantiate a Queue for this agent right now | 331 | // Let's instantiate a Queue for this agent right now |
317 | TryGetQueue(agentID); | 332 | TryGetQueue(agentID); |
318 | 333 | ||
319 | string capsBase = "/CAPS/EQG/"; | 334 | UUID eventQueueGetUUID; |
320 | UUID EventQueueGetUUID = UUID.Zero; | ||
321 | 335 | ||
322 | lock (m_AvatarQueueUUIDMapping) | 336 | lock (m_AvatarQueueUUIDMapping) |
323 | { | 337 | { |
@@ -325,37 +339,35 @@ namespace OpenSim.Region.ClientStack.Linden | |||
325 | if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | 339 | if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) |
326 | { | 340 | { |
327 | //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); | 341 | //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); |
328 | EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; | 342 | eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; |
329 | } | 343 | } |
330 | else | 344 | else |
331 | { | 345 | { |
332 | EventQueueGetUUID = UUID.Random(); | 346 | eventQueueGetUUID = UUID.Random(); |
333 | //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); | 347 | //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); |
334 | } | 348 | } |
335 | } | 349 | } |
336 | 350 | ||
337 | lock (m_QueueUUIDAvatarMapping) | 351 | lock (m_QueueUUIDAvatarMapping) |
338 | { | 352 | { |
339 | if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) | 353 | if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID)) |
340 | m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); | 354 | m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID); |
341 | } | 355 | } |
342 | 356 | ||
343 | lock (m_AvatarQueueUUIDMapping) | 357 | lock (m_AvatarQueueUUIDMapping) |
344 | { | 358 | { |
345 | if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | 359 | if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) |
346 | m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); | 360 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); |
347 | } | 361 | } |
348 | 362 | ||
363 | string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID); | ||
364 | |||
349 | // Register this as a caps handler | 365 | // Register this as a caps handler |
350 | // FIXME: Confusingly, we need to register separate as a capability so that the client is told about | 366 | // FIXME: Confusingly, we need to register separate as a capability so that the client is told about |
351 | // EventQueueGet when it receive capability information, but then we replace the rest handler immediately | 367 | // EventQueueGet when it receive capability information, but then we replace the rest handler immediately |
352 | // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but | 368 | // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but |
353 | // really it should be possible to directly register the poll handler as a capability. | 369 | // really it should be possible to directly register the poll handler as a capability. |
354 | caps.RegisterHandler( | 370 | caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null)); |
355 | "EventQueueGet", | ||
356 | new RestHTTPHandler( | ||
357 | "POST", capsBase + EventQueueGetUUID.ToString() + "/", null)); | ||
358 | |||
359 | // delegate(Hashtable m_dhttpMethod) | 371 | // delegate(Hashtable m_dhttpMethod) |
360 | // { | 372 | // { |
361 | // return ProcessQueue(m_dhttpMethod, agentID, caps); | 373 | // return ProcessQueue(m_dhttpMethod, agentID, caps); |
@@ -364,9 +376,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
364 | // This will persist this beyond the expiry of the caps handlers | 376 | // This will persist this beyond the expiry of the caps handlers |
365 | // TODO: Add EventQueueGet name/description for diagnostics | 377 | // TODO: Add EventQueueGet name/description for diagnostics |
366 | MainServer.Instance.AddPollServiceHTTPHandler( | 378 | MainServer.Instance.AddPollServiceHTTPHandler( |
367 | capsBase + EventQueueGetUUID.ToString() + "/", | 379 | eventQueueGetPath, |
368 | new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); | 380 | new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); |
369 | 381 | ||
382 | // m_log.DebugFormat( | ||
383 | // "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", | ||
384 | // eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); | ||
385 | |||
370 | Random rnd = new Random(Environment.TickCount); | 386 | Random rnd = new Random(Environment.TickCount); |
371 | lock (m_ids) | 387 | lock (m_ids) |
372 | { | 388 | { |
@@ -388,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden | |||
388 | return false; | 404 | return false; |
389 | } | 405 | } |
390 | 406 | ||
407 | /// <summary> | ||
408 | /// Logs a debug line for an outbound event queue message if appropriate. | ||
409 | /// </summary> | ||
410 | /// <param name='element'>Element containing message</param> | ||
411 | private void LogOutboundDebugMessage(OSD element, UUID agentId) | ||
412 | { | ||
413 | if (element is OSDMap) | ||
414 | { | ||
415 | OSDMap ev = (OSDMap)element; | ||
416 | m_log.DebugFormat( | ||
417 | "Eq OUT {0,-30} to {1,-20} {2,-20}", | ||
418 | ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName); | ||
419 | } | ||
420 | } | ||
421 | |||
391 | public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) | 422 | public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) |
392 | { | 423 | { |
393 | // m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId); | 424 | if (DebugLevel >= 2) |
425 | m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); | ||
394 | 426 | ||
395 | Queue<OSD> queue = TryGetQueue(pAgentId); | 427 | Queue<OSD> queue = TryGetQueue(pAgentId); |
396 | OSD element; | 428 | OSD element; |
@@ -414,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
414 | } | 446 | } |
415 | else | 447 | else |
416 | { | 448 | { |
417 | if (DebugLevel > 0 && element is OSDMap) | 449 | if (DebugLevel > 0) |
418 | { | 450 | LogOutboundDebugMessage(element, pAgentId); |
419 | OSDMap ev = (OSDMap)element; | ||
420 | m_log.DebugFormat( | ||
421 | "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", | ||
422 | ev["message"], m_scene.GetScenePresence(pAgentId).Name); | ||
423 | } | ||
424 | 451 | ||
425 | array.Add(element); | 452 | array.Add(element); |
426 | 453 | ||
@@ -430,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
430 | { | 457 | { |
431 | element = queue.Dequeue(); | 458 | element = queue.Dequeue(); |
432 | 459 | ||
433 | if (DebugLevel > 0 && element is OSDMap) | 460 | if (DebugLevel > 0) |
434 | { | 461 | LogOutboundDebugMessage(element, pAgentId); |
435 | OSDMap ev = (OSDMap)element; | ||
436 | m_log.DebugFormat( | ||
437 | "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", | ||
438 | ev["message"], m_scene.GetScenePresence(pAgentId).Name); | ||
439 | } | ||
440 | 462 | ||
441 | array.Add(element); | 463 | array.Add(element); |
442 | thisID++; | 464 | thisID++; |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 5679ad5..e54774b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -67,7 +67,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
67 | /// Determine whether this archive will save assets. Default is true. | 67 | /// Determine whether this archive will save assets. Default is true. |
68 | /// </summary> | 68 | /// </summary> |
69 | public bool SaveAssets { get; set; } | 69 | public bool SaveAssets { get; set; } |
70 | 70 | ||
71 | protected ArchiverModule m_module; | ||
71 | protected Scene m_scene; | 72 | protected Scene m_scene; |
72 | protected Stream m_saveStream; | 73 | protected Stream m_saveStream; |
73 | protected Guid m_requestId; | 74 | protected Guid m_requestId; |
@@ -75,13 +76,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
75 | /// <summary> | 76 | /// <summary> |
76 | /// Constructor | 77 | /// Constructor |
77 | /// </summary> | 78 | /// </summary> |
78 | /// <param name="scene"></param> | 79 | /// <param name="module">Calling module</param> |
79 | /// <param name="savePath">The path to which to save data.</param> | 80 | /// <param name="savePath">The path to which to save data.</param> |
80 | /// <param name="requestId">The id associated with this request</param> | 81 | /// <param name="requestId">The id associated with this request</param> |
81 | /// <exception cref="System.IO.IOException"> | 82 | /// <exception cref="System.IO.IOException"> |
82 | /// If there was a problem opening a stream for the file specified by the savePath | 83 | /// If there was a problem opening a stream for the file specified by the savePath |
83 | /// </exception> | 84 | /// </exception> |
84 | public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId) | 85 | public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId) |
85 | { | 86 | { |
86 | try | 87 | try |
87 | { | 88 | { |
@@ -99,17 +100,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
99 | /// <summary> | 100 | /// <summary> |
100 | /// Constructor. | 101 | /// Constructor. |
101 | /// </summary> | 102 | /// </summary> |
102 | /// <param name="scene"></param> | 103 | /// <param name="module">Calling module</param> |
103 | /// <param name="saveStream">The stream to which to save data.</param> | 104 | /// <param name="saveStream">The stream to which to save data.</param> |
104 | /// <param name="requestId">The id associated with this request</param> | 105 | /// <param name="requestId">The id associated with this request</param> |
105 | public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId) | 106 | public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId) |
106 | { | 107 | { |
107 | m_saveStream = saveStream; | 108 | m_saveStream = saveStream; |
108 | } | 109 | } |
109 | 110 | ||
110 | protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId) | 111 | protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId) |
111 | { | 112 | { |
112 | m_scene = scene; | 113 | m_module = module; |
114 | |||
115 | // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix | ||
116 | // this. | ||
117 | if (m_module != null) | ||
118 | m_scene = m_module.Scene; | ||
119 | |||
113 | m_requestId = requestId; | 120 | m_requestId = requestId; |
114 | 121 | ||
115 | SaveAssets = true; | 122 | SaveAssets = true; |
@@ -364,32 +371,56 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
364 | //if (majorVersion == 1) | 371 | //if (majorVersion == 1) |
365 | //{ | 372 | //{ |
366 | // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); | 373 | // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); |
367 | //} | 374 | //} |
375 | |||
376 | String s; | ||
368 | 377 | ||
369 | StringWriter sw = new StringWriter(); | 378 | using (StringWriter sw = new StringWriter()) |
370 | XmlTextWriter xtw = new XmlTextWriter(sw); | 379 | { |
371 | xtw.Formatting = Formatting.Indented; | 380 | using (XmlTextWriter xtw = new XmlTextWriter(sw)) |
372 | xtw.WriteStartDocument(); | 381 | { |
373 | xtw.WriteStartElement("archive"); | 382 | xtw.Formatting = Formatting.Indented; |
374 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); | 383 | xtw.WriteStartDocument(); |
375 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); | 384 | xtw.WriteStartElement("archive"); |
376 | 385 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); | |
377 | xtw.WriteStartElement("creation_info"); | 386 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); |
378 | DateTime now = DateTime.UtcNow; | 387 | |
379 | TimeSpan t = now - new DateTime(1970, 1, 1); | 388 | xtw.WriteStartElement("creation_info"); |
380 | xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); | 389 | DateTime now = DateTime.UtcNow; |
381 | xtw.WriteElementString("id", UUID.Random().ToString()); | 390 | TimeSpan t = now - new DateTime(1970, 1, 1); |
382 | xtw.WriteEndElement(); | 391 | xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); |
383 | 392 | xtw.WriteElementString("id", UUID.Random().ToString()); | |
384 | xtw.WriteElementString("assets_included", SaveAssets.ToString()); | 393 | xtw.WriteEndElement(); |
385 | 394 | ||
386 | xtw.WriteEndElement(); | 395 | xtw.WriteElementString("assets_included", SaveAssets.ToString()); |
387 | 396 | ||
388 | xtw.Flush(); | 397 | bool isMegaregion; |
389 | xtw.Close(); | 398 | |
390 | 399 | // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix | |
391 | String s = sw.ToString(); | 400 | // this, possibly by doing control file creation somewhere else. |
392 | sw.Close(); | 401 | if (m_module != null && m_module.RegionCombinerModule != null) |
402 | { | ||
403 | IRegionCombinerModule mod = m_module.RegionCombinerModule; | ||
404 | isMegaregion = mod.IsRootForMegaregion(m_scene.RegionInfo.RegionID); | ||
405 | } | ||
406 | else | ||
407 | { | ||
408 | isMegaregion = false; | ||
409 | } | ||
410 | |||
411 | xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); | ||
412 | |||
413 | xtw.WriteEndElement(); | ||
414 | |||
415 | xtw.Flush(); | ||
416 | xtw.Close(); | ||
417 | } | ||
418 | |||
419 | s = sw.ToString(); | ||
420 | } | ||
421 | |||
422 | // Console.WriteLine( | ||
423 | // "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); | ||
393 | 424 | ||
394 | return s; | 425 | return s; |
395 | } | 426 | } |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index f5a5a8d..bf3b124 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -45,7 +45,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
45 | private static readonly ILog m_log = | 45 | private static readonly ILog m_log = |
46 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | 47 | ||
48 | private Scene m_scene; | 48 | public Scene Scene { get; private set; } |
49 | public IRegionCombinerModule RegionCombinerModule { get; private set; } | ||
49 | 50 | ||
50 | /// <value> | 51 | /// <value> |
51 | /// The file used to load and save an opensimulator archive if no filename has been specified | 52 | /// The file used to load and save an opensimulator archive if no filename has been specified |
@@ -70,13 +71,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
70 | 71 | ||
71 | public void AddRegion(Scene scene) | 72 | public void AddRegion(Scene scene) |
72 | { | 73 | { |
73 | m_scene = scene; | 74 | Scene = scene; |
74 | m_scene.RegisterModuleInterface<IRegionArchiverModule>(this); | 75 | Scene.RegisterModuleInterface<IRegionArchiverModule>(this); |
75 | //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); | 76 | //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); |
76 | } | 77 | } |
77 | 78 | ||
78 | public void RegionLoaded(Scene scene) | 79 | public void RegionLoaded(Scene scene) |
79 | { | 80 | { |
81 | RegionCombinerModule = scene.RequestModuleInterface<IRegionCombinerModule>(); | ||
80 | } | 82 | } |
81 | 83 | ||
82 | public void RemoveRegion(Scene scene) | 84 | public void RemoveRegion(Scene scene) |
@@ -165,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
165 | public void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options) | 167 | public void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options) |
166 | { | 168 | { |
167 | m_log.InfoFormat( | 169 | m_log.InfoFormat( |
168 | "[ARCHIVER]: Writing archive for region {0} to {1}", m_scene.RegionInfo.RegionName, savePath); | 170 | "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); |
169 | 171 | ||
170 | new ArchiveWriteRequestPreparation(m_scene, savePath, requestId).ArchiveRegion(options); | 172 | new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); |
171 | } | 173 | } |
172 | 174 | ||
173 | public void ArchiveRegion(Stream saveStream) | 175 | public void ArchiveRegion(Stream saveStream) |
@@ -182,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
182 | 184 | ||
183 | public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) | 185 | public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) |
184 | { | 186 | { |
185 | new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options); | 187 | new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); |
186 | } | 188 | } |
187 | 189 | ||
188 | public void DearchiveRegion(string loadPath) | 190 | public void DearchiveRegion(string loadPath) |
@@ -193,9 +195,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
193 | public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) | 195 | public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) |
194 | { | 196 | { |
195 | m_log.InfoFormat( | 197 | m_log.InfoFormat( |
196 | "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath); | 198 | "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); |
197 | 199 | ||
198 | new ArchiveReadRequest(m_scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); | 200 | new ArchiveReadRequest(Scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); |
199 | } | 201 | } |
200 | 202 | ||
201 | public void DearchiveRegion(Stream loadStream) | 203 | public void DearchiveRegion(Stream loadStream) |
@@ -205,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
205 | 207 | ||
206 | public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) | 208 | public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) |
207 | { | 209 | { |
208 | new ArchiveReadRequest(m_scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); | 210 | new ArchiveReadRequest(Scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); |
209 | } | 211 | } |
210 | } | 212 | } |
211 | } | 213 | } |
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs new file mode 100644 index 0000000..ca4ed5c --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs | |||
@@ -0,0 +1,45 @@ | |||
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.Linq; | ||
31 | using System.Text; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using System.IO; | ||
34 | using OpenMetaverse; | ||
35 | |||
36 | namespace OpenSim.Region.Framework.Interfaces | ||
37 | { | ||
38 | public interface IRegionCombinerModule | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// Does the given id belong to the root region of a megaregion? | ||
42 | /// </summary> | ||
43 | bool IsRootForMegaregion(UUID sceneId); | ||
44 | } | ||
45 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3e11db3..e3bd527 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -591,13 +591,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
591 | get { return m_sceneGraph.Entities; } | 591 | get { return m_sceneGraph.Entities; } |
592 | } | 592 | } |
593 | 593 | ||
594 | // can be closest/random/sequence | 594 | |
595 | private string m_SpawnPointRouting = "closest"; | ||
596 | // used in sequence see: SpawnPoint() | 595 | // used in sequence see: SpawnPoint() |
597 | private int m_SpawnPoint; | 596 | private int m_SpawnPoint; |
597 | // can be closest/random/sequence | ||
598 | public string SpawnPointRouting | 598 | public string SpawnPointRouting |
599 | { | 599 | { |
600 | get { return m_SpawnPointRouting; } | 600 | get; private set; |
601 | } | ||
602 | // allow landmarks to pass | ||
603 | public bool TelehubAllowLandmarks | ||
604 | { | ||
605 | get; private set; | ||
601 | } | 606 | } |
602 | 607 | ||
603 | #endregion Properties | 608 | #endregion Properties |
@@ -737,7 +742,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
737 | m_maxPhys = RegionInfo.PhysPrimMax; | 742 | m_maxPhys = RegionInfo.PhysPrimMax; |
738 | } | 743 | } |
739 | 744 | ||
740 | m_SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); | 745 | SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); |
746 | TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); | ||
741 | 747 | ||
742 | // Here, if clamping is requested in either global or | 748 | // Here, if clamping is requested in either global or |
743 | // local config, it will be used | 749 | // local config, it will be used |
@@ -2794,7 +2800,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2794 | if (sp == null) | 2800 | if (sp == null) |
2795 | { | 2801 | { |
2796 | m_log.DebugFormat( | 2802 | m_log.DebugFormat( |
2797 | "[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos); | 2803 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", |
2804 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); | ||
2798 | 2805 | ||
2799 | m_clientManager.Add(client); | 2806 | m_clientManager.Add(client); |
2800 | SubscribeToClientEvents(client); | 2807 | SubscribeToClientEvents(client); |
@@ -4098,6 +4105,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4098 | return false; | 4105 | return false; |
4099 | } | 4106 | } |
4100 | 4107 | ||
4108 | // TODO: This check should probably be in QueryAccess(). | ||
4101 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); | 4109 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); |
4102 | if (nearestParcel == null) | 4110 | if (nearestParcel == null) |
4103 | { | 4111 | { |
@@ -4108,14 +4116,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4108 | return false; | 4116 | return false; |
4109 | } | 4117 | } |
4110 | 4118 | ||
4111 | int num = m_sceneGraph.GetNumberOfScenePresences(); | 4119 | // We have to wait until the viewer contacts this region after receiving EAC. |
4112 | 4120 | // That calls AddNewClient, which finally creates the ScenePresence | |
4113 | if (num >= RegionInfo.RegionSettings.AgentLimit) | ||
4114 | { | ||
4115 | if (!Permissions.IsAdministrator(cAgentData.AgentID)) | ||
4116 | return false; | ||
4117 | } | ||
4118 | |||
4119 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); | 4121 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); |
4120 | 4122 | ||
4121 | if (childAgentUpdate != null) | 4123 | if (childAgentUpdate != null) |
@@ -4159,14 +4161,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
4159 | return false; | 4161 | return false; |
4160 | } | 4162 | } |
4161 | 4163 | ||
4164 | /// <summary> | ||
4165 | /// Poll until the requested ScenePresence appears or we timeout. | ||
4166 | /// </summary> | ||
4167 | /// <returns>The scene presence is found, else null.</returns> | ||
4168 | /// <param name='agentID'></param> | ||
4162 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) | 4169 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) |
4163 | { | 4170 | { |
4164 | int ntimes = 10; | 4171 | int ntimes = 10; |
4165 | ScenePresence childAgentUpdate = null; | 4172 | ScenePresence sp = null; |
4166 | while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0)) | 4173 | while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) |
4167 | Thread.Sleep(1000); | 4174 | Thread.Sleep(1000); |
4168 | return childAgentUpdate; | ||
4169 | 4175 | ||
4176 | if (sp == null) | ||
4177 | m_log.WarnFormat( | ||
4178 | "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", | ||
4179 | agentID, RegionInfo.RegionName); | ||
4180 | // else | ||
4181 | // m_log.DebugFormat( | ||
4182 | // "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits", | ||
4183 | // sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes); | ||
4184 | |||
4185 | return sp; | ||
4170 | } | 4186 | } |
4171 | 4187 | ||
4172 | public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) | 4188 | public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) |
@@ -5493,13 +5509,22 @@ Environment.Exit(1); | |||
5493 | return true; | 5509 | return true; |
5494 | } | 5510 | } |
5495 | 5511 | ||
5496 | int num = m_sceneGraph.GetNumberOfScenePresences(); | 5512 | // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. |
5513 | // However, the long term fix is to make sure root agent count is always accurate. | ||
5514 | m_sceneGraph.RecalculateStats(); | ||
5515 | |||
5516 | int num = m_sceneGraph.GetRootAgentCount(); | ||
5497 | 5517 | ||
5498 | if (num >= RegionInfo.RegionSettings.AgentLimit) | 5518 | if (num >= RegionInfo.RegionSettings.AgentLimit) |
5499 | { | 5519 | { |
5500 | if (!Permissions.IsAdministrator(agentID)) | 5520 | if (!Permissions.IsAdministrator(agentID)) |
5501 | { | 5521 | { |
5502 | reason = "The region is full"; | 5522 | reason = "The region is full"; |
5523 | |||
5524 | m_log.DebugFormat( | ||
5525 | "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}", | ||
5526 | agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit); | ||
5527 | |||
5503 | return false; | 5528 | return false; |
5504 | } | 5529 | } |
5505 | } | 5530 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 00f76e0..23a0550 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -860,11 +860,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
860 | return m_scenePresenceArray; | 860 | return m_scenePresenceArray; |
861 | } | 861 | } |
862 | 862 | ||
863 | public int GetNumberOfScenePresences() | ||
864 | { | ||
865 | return m_scenePresenceArray.Count; | ||
866 | } | ||
867 | |||
868 | /// <summary> | 863 | /// <summary> |
869 | /// Request a scene presence by UUID. Fast, indexed lookup. | 864 | /// Request a scene presence by UUID. Fast, indexed lookup. |
870 | /// </summary> | 865 | /// </summary> |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 913942f..e0872d0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1299,6 +1299,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1299 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); | 1299 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); |
1300 | m_callbackURI = null; | 1300 | m_callbackURI = null; |
1301 | } | 1301 | } |
1302 | // else | ||
1303 | // { | ||
1304 | // m_log.DebugFormat( | ||
1305 | // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", | ||
1306 | // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); | ||
1307 | // } | ||
1302 | 1308 | ||
1303 | ValidateAndSendAppearanceAndAgentData(); | 1309 | ValidateAndSendAppearanceAndAgentData(); |
1304 | 1310 | ||
@@ -2691,7 +2697,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2691 | // If we are using the the cached appearance then send it out to everyone | 2697 | // If we are using the the cached appearance then send it out to everyone |
2692 | if (cachedappearance) | 2698 | if (cachedappearance) |
2693 | { | 2699 | { |
2694 | m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); | 2700 | m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); |
2695 | 2701 | ||
2696 | // If the avatars baked textures are all in the cache, then we have a | 2702 | // If the avatars baked textures are all in the cache, then we have a |
2697 | // complete appearance... send it out, if not, then we'll send it when | 2703 | // complete appearance... send it out, if not, then we'll send it when |
@@ -3153,7 +3159,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3153 | 3159 | ||
3154 | public void ChildAgentDataUpdate(AgentData cAgentData) | 3160 | public void ChildAgentDataUpdate(AgentData cAgentData) |
3155 | { | 3161 | { |
3156 | //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); | 3162 | // m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); |
3157 | if (!IsChildAgent) | 3163 | if (!IsChildAgent) |
3158 | return; | 3164 | return; |
3159 | 3165 | ||
@@ -3297,6 +3303,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3297 | m_originRegionID = cAgent.RegionID; | 3303 | m_originRegionID = cAgent.RegionID; |
3298 | 3304 | ||
3299 | m_callbackURI = cAgent.CallbackURI; | 3305 | m_callbackURI = cAgent.CallbackURI; |
3306 | // m_log.DebugFormat( | ||
3307 | // "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", | ||
3308 | // Name, m_scene.RegionInfo.RegionName, m_callbackURI); | ||
3300 | 3309 | ||
3301 | m_pos = cAgent.Position; | 3310 | m_pos = cAgent.Position; |
3302 | m_velocity = cAgent.Velocity; | 3311 | m_velocity = cAgent.Velocity; |
@@ -4120,7 +4129,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4120 | { | 4129 | { |
4121 | if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == | 4130 | if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == |
4122 | (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || | 4131 | (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || |
4123 | (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || | 4132 | (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) || |
4124 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || | 4133 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || |
4125 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) | 4134 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) |
4126 | { | 4135 | { |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 8397eb4..54b69a2 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | |||
@@ -1261,14 +1261,20 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1261 | { | 1261 | { |
1262 | m_requestedUpdateFrequency = ms; | 1262 | m_requestedUpdateFrequency = ms; |
1263 | m_eventsubscription = ms; | 1263 | m_eventsubscription = ms; |
1264 | CollisionEventsThisFrame.Clear(); | 1264 | |
1265 | // Don't clear collision event reporting here. This is called directly from scene code and so can lead | ||
1266 | // to a race condition with the simulate loop | ||
1267 | |||
1265 | _parent_scene.AddCollisionEventReporting(this); | 1268 | _parent_scene.AddCollisionEventReporting(this); |
1266 | } | 1269 | } |
1267 | 1270 | ||
1268 | public override void UnSubscribeEvents() | 1271 | public override void UnSubscribeEvents() |
1269 | { | 1272 | { |
1270 | CollisionEventsThisFrame.Clear(); | 1273 | CollisionEventsThisFrame.Clear(); |
1271 | _parent_scene.RemoveCollisionEventReporting(this); | 1274 | |
1275 | // Don't clear collision event reporting here. This is called directly from scene code and so can lead | ||
1276 | // to a race condition with the simulate loop | ||
1277 | |||
1272 | m_requestedUpdateFrequency = 0; | 1278 | m_requestedUpdateFrequency = 0; |
1273 | m_eventsubscription = 0; | 1279 | m_eventsubscription = 0; |
1274 | } | 1280 | } |
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index d8d9554..fadc30d 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | |||
@@ -43,9 +43,8 @@ using Mono.Addins; | |||
43 | [assembly: AddinDependency("OpenSim", "0.5")] | 43 | [assembly: AddinDependency("OpenSim", "0.5")] |
44 | namespace OpenSim.Region.RegionCombinerModule | 44 | namespace OpenSim.Region.RegionCombinerModule |
45 | { | 45 | { |
46 | |||
47 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] | 46 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] |
48 | public class RegionCombinerModule : ISharedRegionModule | 47 | public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule |
49 | { | 48 | { |
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 50 | ||
@@ -59,8 +58,22 @@ namespace OpenSim.Region.RegionCombinerModule | |||
59 | get { return null; } | 58 | get { return null; } |
60 | } | 59 | } |
61 | 60 | ||
61 | /// <summary> | ||
62 | /// This holds the root regions for the megaregions. | ||
63 | /// </summary> | ||
64 | /// <remarks> | ||
65 | /// Usually there is only ever one megaregion (and hence only one entry here). | ||
66 | /// </remarks> | ||
62 | private Dictionary<UUID, RegionConnections> m_regions = new Dictionary<UUID, RegionConnections>(); | 67 | private Dictionary<UUID, RegionConnections> m_regions = new Dictionary<UUID, RegionConnections>(); |
68 | |||
69 | /// <summary> | ||
70 | /// Is this module enabled? | ||
71 | /// </summary> | ||
63 | private bool enabledYN = false; | 72 | private bool enabledYN = false; |
73 | |||
74 | /// <summary> | ||
75 | /// The scenes that comprise the megaregion. | ||
76 | /// </summary> | ||
64 | private Dictionary<UUID, Scene> m_startingScenes = new Dictionary<UUID, Scene>(); | 77 | private Dictionary<UUID, Scene> m_startingScenes = new Dictionary<UUID, Scene>(); |
65 | 78 | ||
66 | public void Initialise(IConfigSource source) | 79 | public void Initialise(IConfigSource source) |
@@ -69,9 +82,11 @@ namespace OpenSim.Region.RegionCombinerModule | |||
69 | enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false); | 82 | enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false); |
70 | 83 | ||
71 | if (enabledYN) | 84 | if (enabledYN) |
85 | { | ||
72 | MainConsole.Instance.Commands.AddCommand( | 86 | MainConsole.Instance.Commands.AddCommand( |
73 | "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", | 87 | "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", |
74 | "Fixes phantom objects after an import to megaregions", FixPhantoms); | 88 | "Fixes phantom objects after an import to megaregions", FixPhantoms); |
89 | } | ||
75 | } | 90 | } |
76 | 91 | ||
77 | public void Close() | 92 | public void Close() |
@@ -80,6 +95,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
80 | 95 | ||
81 | public void AddRegion(Scene scene) | 96 | public void AddRegion(Scene scene) |
82 | { | 97 | { |
98 | if (enabledYN) | ||
99 | scene.RegisterModuleInterface<IRegionCombinerModule>(this); | ||
83 | } | 100 | } |
84 | 101 | ||
85 | public void RemoveRegion(Scene scene) | 102 | public void RemoveRegion(Scene scene) |
@@ -89,7 +106,95 @@ namespace OpenSim.Region.RegionCombinerModule | |||
89 | public void RegionLoaded(Scene scene) | 106 | public void RegionLoaded(Scene scene) |
90 | { | 107 | { |
91 | if (enabledYN) | 108 | if (enabledYN) |
109 | { | ||
92 | RegionLoadedDoWork(scene); | 110 | RegionLoadedDoWork(scene); |
111 | |||
112 | scene.EventManager.OnNewPresence += NewPresence; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | public bool IsRootForMegaregion(UUID sceneId) | ||
117 | { | ||
118 | lock (m_regions) | ||
119 | return m_regions.ContainsKey(sceneId); | ||
120 | } | ||
121 | |||
122 | private void NewPresence(ScenePresence presence) | ||
123 | { | ||
124 | if (presence.IsChildAgent) | ||
125 | { | ||
126 | byte[] throttleData; | ||
127 | |||
128 | try | ||
129 | { | ||
130 | throttleData = presence.ControllingClient.GetThrottlesPacked(1); | ||
131 | } | ||
132 | catch (NotImplementedException) | ||
133 | { | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | if (throttleData == null) | ||
138 | return; | ||
139 | |||
140 | if (throttleData.Length == 0) | ||
141 | return; | ||
142 | |||
143 | if (throttleData.Length != 28) | ||
144 | return; | ||
145 | |||
146 | byte[] adjData; | ||
147 | int pos = 0; | ||
148 | |||
149 | if (!BitConverter.IsLittleEndian) | ||
150 | { | ||
151 | byte[] newData = new byte[7 * 4]; | ||
152 | Buffer.BlockCopy(throttleData, 0, newData, 0, 7 * 4); | ||
153 | |||
154 | for (int i = 0; i < 7; i++) | ||
155 | Array.Reverse(newData, i * 4, 4); | ||
156 | |||
157 | adjData = newData; | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | adjData = throttleData; | ||
162 | } | ||
163 | |||
164 | // 0.125f converts from bits to bytes | ||
165 | int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | ||
166 | int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | ||
167 | int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | ||
168 | int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | ||
169 | int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | ||
170 | int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | ||
171 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); | ||
172 | // State is a subcategory of task that we allocate a percentage to | ||
173 | |||
174 | |||
175 | //int total = resend + land + wind + cloud + task + texture + asset; | ||
176 | |||
177 | byte[] data = new byte[7 * 4]; | ||
178 | int ii = 0; | ||
179 | |||
180 | Buffer.BlockCopy(Utils.FloatToBytes(resend), 0, data, ii, 4); ii += 4; | ||
181 | Buffer.BlockCopy(Utils.FloatToBytes(land * 50), 0, data, ii, 4); ii += 4; | ||
182 | Buffer.BlockCopy(Utils.FloatToBytes(wind), 0, data, ii, 4); ii += 4; | ||
183 | Buffer.BlockCopy(Utils.FloatToBytes(cloud), 0, data, ii, 4); ii += 4; | ||
184 | Buffer.BlockCopy(Utils.FloatToBytes(task), 0, data, ii, 4); ii += 4; | ||
185 | Buffer.BlockCopy(Utils.FloatToBytes(texture), 0, data, ii, 4); ii += 4; | ||
186 | Buffer.BlockCopy(Utils.FloatToBytes(asset), 0, data, ii, 4); | ||
187 | |||
188 | try | ||
189 | { | ||
190 | presence.ControllingClient.SetChildAgentThrottle(data); | ||
191 | } | ||
192 | catch (NotImplementedException) | ||
193 | { | ||
194 | return; | ||
195 | } | ||
196 | |||
197 | } | ||
93 | } | 198 | } |
94 | 199 | ||
95 | private void RegionLoadedDoWork(Scene scene) | 200 | private void RegionLoadedDoWork(Scene scene) |
@@ -348,9 +453,9 @@ namespace OpenSim.Region.RegionCombinerModule | |||
348 | if (!connectedYN) | 453 | if (!connectedYN) |
349 | { | 454 | { |
350 | DoWorkForRootRegion(regionConnections, scene); | 455 | DoWorkForRootRegion(regionConnections, scene); |
351 | |||
352 | } | 456 | } |
353 | } | 457 | } |
458 | |||
354 | // Set up infinite borders around the entire AABB of the combined ConnectedRegions | 459 | // Set up infinite borders around the entire AABB of the combined ConnectedRegions |
355 | AdjustLargeRegionBounds(); | 460 | AdjustLargeRegionBounds(); |
356 | } | 461 | } |
@@ -369,9 +474,10 @@ namespace OpenSim.Region.RegionCombinerModule | |||
369 | 474 | ||
370 | conn.UpdateExtents(extents); | 475 | conn.UpdateExtents(extents); |
371 | 476 | ||
372 | m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}", | 477 | m_log.DebugFormat( |
373 | conn.RegionScene.RegionInfo.RegionName, | 478 | "[REGION COMBINER MODULE]: Scene {0} to the west of Scene {1}, Offset: {2}, Extents: {3}", |
374 | regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); | 479 | conn.RegionScene.RegionInfo.RegionName, |
480 | regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); | ||
375 | 481 | ||
376 | scene.BordersLocked = true; | 482 | scene.BordersLocked = true; |
377 | conn.RegionScene.BordersLocked = true; | 483 | conn.RegionScene.BordersLocked = true; |
@@ -447,9 +553,10 @@ namespace OpenSim.Region.RegionCombinerModule | |||
447 | ConnectedRegion.RegionScene = scene; | 553 | ConnectedRegion.RegionScene = scene; |
448 | conn.ConnectedRegions.Add(ConnectedRegion); | 554 | conn.ConnectedRegions.Add(ConnectedRegion); |
449 | 555 | ||
450 | m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}", | 556 | m_log.DebugFormat( |
451 | conn.RegionScene.RegionInfo.RegionName, | 557 | "[REGION COMBINER MODULE]: Scene: {0} to the northeast of Scene {1}, Offset: {2}, Extents: {3}", |
452 | regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); | 558 | conn.RegionScene.RegionInfo.RegionName, |
559 | regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); | ||
453 | 560 | ||
454 | conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); | 561 | conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); |
455 | scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 562 | scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
@@ -502,9 +609,10 @@ namespace OpenSim.Region.RegionCombinerModule | |||
502 | 609 | ||
503 | conn.ConnectedRegions.Add(ConnectedRegion); | 610 | conn.ConnectedRegions.Add(ConnectedRegion); |
504 | 611 | ||
505 | m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", | 612 | m_log.DebugFormat( |
506 | conn.RegionScene.RegionInfo.RegionName, | 613 | "[REGION COMBINER MODULE]: Scene: {0} to the NorthEast of Scene {1}, Offset: {2}, Extents: {3}", |
507 | regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); | 614 | conn.RegionScene.RegionInfo.RegionName, |
615 | regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); | ||
508 | 616 | ||
509 | conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); | 617 | conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); |
510 | scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 618 | scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
@@ -581,6 +689,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
581 | 689 | ||
582 | private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) | 690 | private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) |
583 | { | 691 | { |
692 | m_log.DebugFormat("[REGION COMBINER MODULE]: Adding root region {0}", scene.RegionInfo.RegionName); | ||
693 | |||
584 | RegionData rdata = new RegionData(); | 694 | RegionData rdata = new RegionData(); |
585 | rdata.Offset = Vector3.Zero; | 695 | rdata.Offset = Vector3.Zero; |
586 | rdata.RegionId = scene.RegionInfo.originRegionID; | 696 | rdata.RegionId = scene.RegionInfo.originRegionID; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2533002..0cc3e8c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -10373,7 +10373,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10373 | m_host.TaskInventory.LockItemsForRead(false); | 10373 | m_host.TaskInventory.LockItemsForRead(false); |
10374 | 10374 | ||
10375 | // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); | 10375 | // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); |
10376 | ScenePresence presence = World.GetScenePresence(agentID); | 10376 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); |
10377 | if (presence != null) | 10377 | if (presence != null) |
10378 | { | 10378 | { |
10379 | LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); | 10379 | LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); |
@@ -10397,7 +10397,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10397 | m_host.TaskInventory.LockItemsForRead(false); | 10397 | m_host.TaskInventory.LockItemsForRead(false); |
10398 | 10398 | ||
10399 | // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); | 10399 | // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); |
10400 | ScenePresence presence = World.GetScenePresence(agentID); | 10400 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); |
10401 | if (presence != null) | 10401 | if (presence != null) |
10402 | { | 10402 | { |
10403 | return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); | 10403 | return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); |
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 15156d0..eed88bd 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs | |||
@@ -307,14 +307,20 @@ namespace OpenSim.Services.InventoryService | |||
307 | if (check != null) | 307 | if (check != null) |
308 | return false; | 308 | return false; |
309 | 309 | ||
310 | if (folder.Type == (short)AssetType.Folder || folder.Type == (short)AssetType.Unknown || | 310 | if (folder.Type == (short)AssetType.Folder |
311 | GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null) | 311 | || folder.Type == (short)AssetType.Unknown |
312 | || folder.Type == (short)AssetType.OutfitFolder | ||
313 | || GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null) | ||
312 | { | 314 | { |
313 | XInventoryFolder xFolder = ConvertFromOpenSim(folder); | 315 | XInventoryFolder xFolder = ConvertFromOpenSim(folder); |
314 | return m_Database.StoreFolder(xFolder); | 316 | return m_Database.StoreFolder(xFolder); |
315 | } | 317 | } |
316 | else | 318 | else |
317 | m_log.DebugFormat("[XINVENTORY]: Folder {0} of type {1} already exists", folder.Name, folder.Type); | 319 | { |
320 | m_log.WarnFormat( | ||
321 | "[XINVENTORY]: Folder of type {0} already exists when tried to add {1} to {2} for {3}", | ||
322 | folder.Type, folder.Name, folder.ParentID, folder.Owner); | ||
323 | } | ||
318 | 324 | ||
319 | return false; | 325 | return false; |
320 | } | 326 | } |
diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index 52e7501..9e82577 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using System.Threading; | 30 | using System.Threading; |
31 | using log4net; | 31 | using log4net; |
32 | using log4net.Config; | ||
32 | using Nini.Config; | 33 | using Nini.Config; |
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Console; | 35 | using OpenSim.Framework.Console; |
@@ -52,6 +53,8 @@ namespace pCampBot | |||
52 | [STAThread] | 53 | [STAThread] |
53 | public static void Main(string[] args) | 54 | public static void Main(string[] args) |
54 | { | 55 | { |
56 | XmlConfigurator.Configure(); | ||
57 | |||
55 | IConfig config = ParseConfig(args); | 58 | IConfig config = ParseConfig(args); |
56 | if (config.Get("help") != null || config.Get("loginuri") == null) | 59 | if (config.Get("help") != null || config.Get("loginuri") == null) |
57 | { | 60 | { |
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 9f418a4..aa29c07 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -249,6 +249,11 @@ | |||
249 | ;; "sequence" will place the avatar on the next sequential SpawnPoint | 249 | ;; "sequence" will place the avatar on the next sequential SpawnPoint |
250 | ; SpawnPointRouting = closest | 250 | ; SpawnPointRouting = closest |
251 | 251 | ||
252 | ;# {TelehubAllowLandmark} {} {Allow users with landmarks to override telehub routing} {true false} false | ||
253 | ;; TelehubAllowLandmark allows users with landmarks to override telehub routing and land at the landmark coordinates when set to true | ||
254 | ;; default is false | ||
255 | ; TelehubAllowLandmark = false | ||
256 | |||
252 | [Estates] | 257 | [Estates] |
253 | ; If these values are commented out then the user will be asked for estate details when required (this is the normal case). | 258 | ; If these values are commented out then the user will be asked for estate details when required (this is the normal case). |
254 | ; If these values are uncommented then they will be used to create a default estate as necessary. | 259 | ; If these values are uncommented then they will be used to create a default estate as necessary. |
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index d159960..ea83f91 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -601,13 +601,12 @@ | |||
601 | Cap_ViewerStartAuction = "" | 601 | Cap_ViewerStartAuction = "" |
602 | Cap_ViewerStats = "" | 602 | Cap_ViewerStats = "" |
603 | 603 | ||
604 | ; The various fetch inventory caps are supported by OpenSim, but may | 604 | ; Capabilities for fetching inventory over HTTP rather than UDP |
605 | ; lead to poor sim performance if served by the simulators, | ||
606 | ; so they are currently disabled by default. | ||
607 | ; FetchInventoryDescendents2 and FetchInventory2 are the ones used in the latest Linden Lab viewers (from some point in the v2 series and above) | 605 | ; FetchInventoryDescendents2 and FetchInventory2 are the ones used in the latest Linden Lab viewers (from some point in the v2 series and above) |
606 | ; It appears that Linden Lab viewer 3.3.1 onwards will not work properly if FetchInventoryDescendents2 and FetchInventory2 are not enabled | ||
608 | Cap_WebFetchInventoryDescendents = "" | 607 | Cap_WebFetchInventoryDescendents = "" |
609 | Cap_FetchInventoryDescendents2 = "" | 608 | Cap_FetchInventoryDescendents2 = "localhost" |
610 | Cap_FetchInventory2 = "" | 609 | Cap_FetchInventory2 = "localhost" |
611 | 610 | ||
612 | 611 | ||
613 | [Chat] | 612 | [Chat] |
diff --git a/bin/pCampBot.exe.config b/bin/pCampBot.exe.config index 3f19ee8..9cfb7e9 100644 --- a/bin/pCampBot.exe.config +++ b/bin/pCampBot.exe.config | |||
@@ -8,7 +8,7 @@ | |||
8 | <log4net> | 8 | <log4net> |
9 | <appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console"> | 9 | <appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console"> |
10 | <layout type="log4net.Layout.PatternLayout"> | 10 | <layout type="log4net.Layout.PatternLayout"> |
11 | <conversionPattern value="%date{HH:mm:ss} - %message%newline" /> | 11 | <conversionPattern value="%date{HH:mm:ss.fff} - %message%newline" /> |
12 | </layout> | 12 | </layout> |
13 | </appender> | 13 | </appender> |
14 | <appender name="LogFileAppender" type="log4net.Appender.FileAppender"> | 14 | <appender name="LogFileAppender" type="log4net.Appender.FileAppender"> |