diff options
Diffstat (limited to '')
34 files changed, 669 insertions, 104 deletions
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index 4642b2a..7d48516 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs | |||
@@ -623,10 +623,13 @@ namespace OpenSim.Groups | |||
623 | if (agent != null) | 623 | if (agent != null) |
624 | break; | 624 | break; |
625 | } | 625 | } |
626 | if (agent == null) // oops | 626 | if (agent != null) |
627 | return AgentID.ToString(); | 627 | return Util.ProduceUserUniversalIdentifier(agent); |
628 | |||
629 | // we don't know anything about this foreign user | ||
630 | // try asking the user management module, which may know more | ||
631 | return m_UserManagement.GetUserUUI(AgentID); | ||
628 | 632 | ||
629 | return Util.ProduceUserUniversalIdentifier(agent); | ||
630 | } | 633 | } |
631 | 634 | ||
632 | private string AgentUUIForOutside(string AgentIDStr) | 635 | private string AgentUUIForOutside(string AgentIDStr) |
diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs index 70e1065..463c621 100644 --- a/OpenSim/Data/IRegionData.cs +++ b/OpenSim/Data/IRegionData.cs | |||
@@ -81,6 +81,7 @@ namespace OpenSim.Data | |||
81 | bool Delete(UUID regionID); | 81 | bool Delete(UUID regionID); |
82 | 82 | ||
83 | List<RegionData> GetDefaultRegions(UUID scopeID); | 83 | List<RegionData> GetDefaultRegions(UUID scopeID); |
84 | List<RegionData> GetDefaultHypergridRegions(UUID scopeID); | ||
84 | List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y); | 85 | List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y); |
85 | List<RegionData> GetHyperlinks(UUID scopeID); | 86 | List<RegionData> GetHyperlinks(UUID scopeID); |
86 | } | 87 | } |
diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 0d89706..c0589df 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs | |||
@@ -315,6 +315,11 @@ namespace OpenSim.Data.MSSQL | |||
315 | return Get((int)RegionFlags.DefaultRegion, scopeID); | 315 | return Get((int)RegionFlags.DefaultRegion, scopeID); |
316 | } | 316 | } |
317 | 317 | ||
318 | public List<RegionData> GetDefaultHypergridRegions(UUID scopeID) | ||
319 | { | ||
320 | return Get((int)RegionFlags.DefaultHGRegion, scopeID); | ||
321 | } | ||
322 | |||
318 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) | 323 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) |
319 | { | 324 | { |
320 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); | 325 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); |
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index a2d4ae4..2ad7590 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs | |||
@@ -310,6 +310,11 @@ namespace OpenSim.Data.MySQL | |||
310 | return Get((int)RegionFlags.DefaultRegion, scopeID); | 310 | return Get((int)RegionFlags.DefaultRegion, scopeID); |
311 | } | 311 | } |
312 | 312 | ||
313 | public List<RegionData> GetDefaultHypergridRegions(UUID scopeID) | ||
314 | { | ||
315 | return Get((int)RegionFlags.DefaultHGRegion, scopeID); | ||
316 | } | ||
317 | |||
313 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) | 318 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) |
314 | { | 319 | { |
315 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); | 320 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); |
diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs index f707d98..d28cd99 100644 --- a/OpenSim/Data/Null/NullRegionData.cs +++ b/OpenSim/Data/Null/NullRegionData.cs | |||
@@ -239,6 +239,11 @@ namespace OpenSim.Data.Null | |||
239 | return Get((int)RegionFlags.DefaultRegion, scopeID); | 239 | return Get((int)RegionFlags.DefaultRegion, scopeID); |
240 | } | 240 | } |
241 | 241 | ||
242 | public List<RegionData> GetDefaultHypergridRegions(UUID scopeID) | ||
243 | { | ||
244 | return Get((int)RegionFlags.DefaultHGRegion, scopeID); | ||
245 | } | ||
246 | |||
242 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) | 247 | public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y) |
243 | { | 248 | { |
244 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); | 249 | List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID); |
diff --git a/OpenSim/Framework/RegionFlags.cs b/OpenSim/Framework/RegionFlags.cs index a3089b0..7c6569e 100644 --- a/OpenSim/Framework/RegionFlags.cs +++ b/OpenSim/Framework/RegionFlags.cs | |||
@@ -48,6 +48,7 @@ namespace OpenSim.Framework | |||
48 | NoMove = 64, // Don't allow moving this region | 48 | NoMove = 64, // Don't allow moving this region |
49 | Reservation = 128, // This is an inactive reservation | 49 | Reservation = 128, // This is an inactive reservation |
50 | Authenticate = 256, // Require authentication | 50 | Authenticate = 256, // Require authentication |
51 | Hyperlink = 512 // Record represents a HG link | 51 | Hyperlink = 512, // Record represents a HG link |
52 | DefaultHGRegion = 1024 // Record represents a default region for hypergrid teleports only. | ||
52 | } | 53 | } |
53 | } \ No newline at end of file | 54 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 7398b37..7db575b 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -130,7 +130,7 @@ namespace OpenSim.Framework | |||
130 | private static SmartThreadPool m_ThreadPool; | 130 | private static SmartThreadPool m_ThreadPool; |
131 | 131 | ||
132 | // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. | 132 | // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. |
133 | private static readonly DateTime unixEpoch = | 133 | public static readonly DateTime UnixEpoch = |
134 | DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime(); | 134 | DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime(); |
135 | 135 | ||
136 | private static readonly string rawUUIDPattern | 136 | private static readonly string rawUUIDPattern |
@@ -521,20 +521,18 @@ namespace OpenSim.Framework | |||
521 | 521 | ||
522 | public static int ToUnixTime(DateTime stamp) | 522 | public static int ToUnixTime(DateTime stamp) |
523 | { | 523 | { |
524 | TimeSpan t = stamp.ToUniversalTime() - unixEpoch; | 524 | TimeSpan t = stamp.ToUniversalTime() - UnixEpoch; |
525 | return (int) t.TotalSeconds; | 525 | return (int)t.TotalSeconds; |
526 | } | 526 | } |
527 | 527 | ||
528 | public static DateTime ToDateTime(ulong seconds) | 528 | public static DateTime ToDateTime(ulong seconds) |
529 | { | 529 | { |
530 | DateTime epoch = unixEpoch; | 530 | return UnixEpoch.AddSeconds(seconds); |
531 | return epoch.AddSeconds(seconds); | ||
532 | } | 531 | } |
533 | 532 | ||
534 | public static DateTime ToDateTime(int seconds) | 533 | public static DateTime ToDateTime(int seconds) |
535 | { | 534 | { |
536 | DateTime epoch = unixEpoch; | 535 | return UnixEpoch.AddSeconds(seconds); |
537 | return epoch.AddSeconds(seconds); | ||
538 | } | 536 | } |
539 | 537 | ||
540 | /// <summary> | 538 | /// <summary> |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index 626932f..b3b0b8a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | |||
@@ -76,7 +76,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
76 | } | 76 | } |
77 | 77 | ||
78 | [Test] | 78 | [Test] |
79 | public void AddForClient() | 79 | public void TestAddForClient() |
80 | { | 80 | { |
81 | TestHelpers.InMethod(); | 81 | TestHelpers.InMethod(); |
82 | // log4net.Config.XmlConfigurator.Configure(); | 82 | // log4net.Config.XmlConfigurator.Configure(); |
@@ -88,7 +88,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
88 | } | 88 | } |
89 | 89 | ||
90 | [Test] | 90 | [Test] |
91 | public void RemoveForClient() | 91 | public void TestRemoveForClient() |
92 | { | 92 | { |
93 | TestHelpers.InMethod(); | 93 | TestHelpers.InMethod(); |
94 | // TestHelpers.EnableLogging(); | 94 | // TestHelpers.EnableLogging(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 174642d..917f164 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -372,21 +372,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
372 | UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, | 372 | UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, |
373 | string message, ChatSourceType src, bool ignoreDistance) | 373 | string message, ChatSourceType src, bool ignoreDistance) |
374 | { | 374 | { |
375 | // don't send chat to child agents | 375 | if (presence.LifecycleState != ScenePresenceState.Running) |
376 | if (presence.IsChildAgent) return false; | 376 | return false; |
377 | |||
378 | Vector3 fromRegionPos = fromPos + regionPos; | ||
379 | Vector3 toRegionPos = presence.AbsolutePosition + | ||
380 | new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, | ||
381 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | ||
382 | 377 | ||
383 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); | 378 | if (!ignoreDistance) |
384 | |||
385 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | ||
386 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
387 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
388 | { | 379 | { |
389 | return false; | 380 | Vector3 fromRegionPos = fromPos + regionPos; |
381 | Vector3 toRegionPos = presence.AbsolutePosition + | ||
382 | new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, | ||
383 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | ||
384 | |||
385 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); | ||
386 | |||
387 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | ||
388 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
389 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
390 | { | ||
391 | return false; | ||
392 | } | ||
390 | } | 393 | } |
391 | 394 | ||
392 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView | 395 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView |
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index bf1cffb..56ff2bd 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | |||
@@ -1212,7 +1212,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1212 | json.Add("jsonrpc", OSD.FromString("2.0")); | 1212 | json.Add("jsonrpc", OSD.FromString("2.0")); |
1213 | json.Add("id", OSD.FromString(jsonId)); | 1213 | json.Add("id", OSD.FromString(jsonId)); |
1214 | json.Add("method", OSD.FromString(method)); | 1214 | json.Add("method", OSD.FromString(method)); |
1215 | // Experiment | 1215 | |
1216 | json.Add("params", OSD.SerializeMembers(parameters)); | 1216 | json.Add("params", OSD.SerializeMembers(parameters)); |
1217 | 1217 | ||
1218 | string jsonRequestData = OSDParser.SerializeJsonString(json); | 1218 | string jsonRequestData = OSDParser.SerializeJsonString(json); |
@@ -1240,8 +1240,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | Stream rstream = webResponse.GetResponseStream(); | 1242 | Stream rstream = webResponse.GetResponseStream(); |
1243 | if (rstream.Length < 1) | ||
1244 | return false; | ||
1245 | 1243 | ||
1246 | OSDMap mret = new OSDMap(); | 1244 | OSDMap mret = new OSDMap(); |
1247 | try | 1245 | try |
@@ -1318,8 +1316,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1318 | } | 1316 | } |
1319 | 1317 | ||
1320 | Stream rstream = webResponse.GetResponseStream(); | 1318 | Stream rstream = webResponse.GetResponseStream(); |
1321 | if (rstream.Length < 1) | ||
1322 | return false; | ||
1323 | 1319 | ||
1324 | OSDMap response = new OSDMap(); | 1320 | OSDMap response = new OSDMap(); |
1325 | try | 1321 | try |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 1f3e7a1..ed14c12 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -925,6 +925,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
925 | 925 | ||
926 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 926 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
927 | { | 927 | { |
928 | if (!sp.Scene.IncomingPreCloseAgent(sp)) | ||
929 | return; | ||
930 | |||
928 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before | 931 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before |
929 | // they regard the new region as the current region after receiving the AgentMovementComplete | 932 | // they regard the new region as the current region after receiving the AgentMovementComplete |
930 | // response. If close is sent before then, it will cause the viewer to quit instead. | 933 | // response. If close is sent before then, it will cause the viewer to quit instead. |
@@ -1087,6 +1090,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1087 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 1090 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
1088 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 1091 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
1089 | { | 1092 | { |
1093 | if (!sp.Scene.IncomingPreCloseAgent(sp)) | ||
1094 | return; | ||
1095 | |||
1090 | // RED ALERT!!!! | 1096 | // RED ALERT!!!! |
1091 | // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. | 1097 | // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. |
1092 | // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion | 1098 | // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion |
@@ -1100,6 +1106,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1100 | // then this will be handled in IncomingCloseAgent under lock conditions | 1106 | // then this will be handled in IncomingCloseAgent under lock conditions |
1101 | m_log.DebugFormat( | 1107 | m_log.DebugFormat( |
1102 | "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); | 1108 | "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); |
1109 | |||
1103 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 1110 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
1104 | } | 1111 | } |
1105 | else | 1112 | else |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 7adb203..8c983e6 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -481,14 +481,20 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
481 | 481 | ||
482 | public string GetUserUUI(UUID userID) | 482 | public string GetUserUUI(UUID userID) |
483 | { | 483 | { |
484 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID); | ||
485 | if (account != null) | ||
486 | return userID.ToString(); | ||
487 | |||
488 | UserData ud; | 484 | UserData ud; |
489 | lock (m_UserCache) | 485 | lock (m_UserCache) |
490 | m_UserCache.TryGetValue(userID, out ud); | 486 | m_UserCache.TryGetValue(userID, out ud); |
491 | 487 | ||
488 | if (ud == null) // It's not in the cache | ||
489 | { | ||
490 | string[] names = new string[2]; | ||
491 | // This will pull the data from either UserAccounts or GridUser | ||
492 | // and stick it into the cache | ||
493 | TryGetUserNamesFromServices(userID, names); | ||
494 | lock (m_UserCache) | ||
495 | m_UserCache.TryGetValue(userID, out ud); | ||
496 | } | ||
497 | |||
492 | if (ud != null) | 498 | if (ud != null) |
493 | { | 499 | { |
494 | string homeURL = ud.HomeURL; | 500 | string homeURL = ud.HomeURL; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 3849a3f..31ef79b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | |||
@@ -235,6 +235,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
235 | return m_GridService.GetDefaultRegions(scopeID); | 235 | return m_GridService.GetDefaultRegions(scopeID); |
236 | } | 236 | } |
237 | 237 | ||
238 | public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID) | ||
239 | { | ||
240 | return m_GridService.GetDefaultHypergridRegions(scopeID); | ||
241 | } | ||
242 | |||
238 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) | 243 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) |
239 | { | 244 | { |
240 | return m_GridService.GetFallbackRegions(scopeID, x, y); | 245 | return m_GridService.GetFallbackRegions(scopeID, x, y); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs index b2646ba..6a57d1f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs | |||
@@ -277,6 +277,26 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
277 | return rinfo; | 277 | return rinfo; |
278 | } | 278 | } |
279 | 279 | ||
280 | public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID) | ||
281 | { | ||
282 | List<GridRegion> rinfo = m_LocalGridService.GetDefaultHypergridRegions(scopeID); | ||
283 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetDefaultHypergridRegions {0} found {1} regions", name, rinfo.Count); | ||
284 | List<GridRegion> grinfo = m_RemoteGridService.GetDefaultHypergridRegions(scopeID); | ||
285 | |||
286 | if (grinfo != null) | ||
287 | { | ||
288 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultHypergridRegions {0} found {1} regions", name, grinfo.Count); | ||
289 | foreach (GridRegion r in grinfo) | ||
290 | { | ||
291 | m_RegionInfoCache.Cache(r); | ||
292 | if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) | ||
293 | rinfo.Add(r); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | return rinfo; | ||
298 | } | ||
299 | |||
280 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) | 300 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) |
281 | { | 301 | { |
282 | List<GridRegion> rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y); | 302 | List<GridRegion> rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y); |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f864392..18e7eb8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -3854,10 +3854,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3854 | 3854 | ||
3855 | // We need to ensure that we are not already removing the scene presence before we ask it not to be | 3855 | // We need to ensure that we are not already removing the scene presence before we ask it not to be |
3856 | // closed. | 3856 | // closed. |
3857 | if (sp != null && sp.IsChildAgent && sp.LifecycleState == ScenePresenceState.Running) | 3857 | if (sp != null && sp.IsChildAgent |
3858 | && (sp.LifecycleState == ScenePresenceState.Running | ||
3859 | || sp.LifecycleState == ScenePresenceState.PreRemove)) | ||
3858 | { | 3860 | { |
3859 | m_log.DebugFormat( | 3861 | m_log.DebugFormat( |
3860 | "[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name); | 3862 | "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}", |
3863 | sp.Name, sp.LifecycleState, Name); | ||
3861 | 3864 | ||
3862 | // In the case where, for example, an A B C D region layout, an avatar may | 3865 | // In the case where, for example, an A B C D region layout, an avatar may |
3863 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C | 3866 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C |
@@ -3879,6 +3882,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3879 | // } | 3882 | // } |
3880 | // else if (EntityTransferModule.IsInTransit(sp.UUID)) | 3883 | // else if (EntityTransferModule.IsInTransit(sp.UUID)) |
3881 | 3884 | ||
3885 | sp.LifecycleState = ScenePresenceState.Running; | ||
3886 | |||
3882 | if (EntityTransferModule.IsInTransit(sp.UUID)) | 3887 | if (EntityTransferModule.IsInTransit(sp.UUID)) |
3883 | { | 3888 | { |
3884 | sp.DoNotCloseAfterTeleport = true; | 3889 | sp.DoNotCloseAfterTeleport = true; |
@@ -4018,6 +4023,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
4018 | // uses down the line. | 4023 | // uses down the line. |
4019 | sp.TeleportFlags = (TPFlags)teleportFlags; | 4024 | sp.TeleportFlags = (TPFlags)teleportFlags; |
4020 | 4025 | ||
4026 | // We must carry out a further authorization check if there's an | ||
4027 | // attempt to make a child agent into a root agent, since SeeIntoRegion may have allowed a child | ||
4028 | // agent to login to a region where a full avatar would not be allowed. | ||
4029 | // | ||
4030 | // We determine whether this is a CreateAgent for a future non-child agent by inspecting | ||
4031 | // TeleportFlags, which will be default for a child connection. This relies on input from the source | ||
4032 | // region. | ||
4033 | if (sp.TeleportFlags != TPFlags.Default) | ||
4034 | { | ||
4035 | if (!AuthorizeUser(acd, false, out reason)) | ||
4036 | return false; | ||
4037 | } | ||
4038 | |||
4021 | if (sp.IsChildAgent) | 4039 | if (sp.IsChildAgent) |
4022 | { | 4040 | { |
4023 | m_log.DebugFormat( | 4041 | m_log.DebugFormat( |
@@ -4526,10 +4544,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4526 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); | 4544 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); |
4527 | if (childAgentUpdate != null) | 4545 | if (childAgentUpdate != null) |
4528 | { | 4546 | { |
4529 | if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) | 4547 | // if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) |
4530 | // Only warn for now | 4548 | // // Only warn for now |
4531 | m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", | 4549 | // m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", |
4532 | childAgentUpdate.UUID, cAgentData.SessionID); | 4550 | // childAgentUpdate.UUID, cAgentData.SessionID); |
4533 | 4551 | ||
4534 | // I can't imagine *yet* why we would get an update if the agent is a root agent.. | 4552 | // I can't imagine *yet* why we would get an update if the agent is a root agent.. |
4535 | // however to avoid a race condition crossing borders.. | 4553 | // however to avoid a race condition crossing borders.. |
@@ -4631,6 +4649,50 @@ namespace OpenSim.Region.Framework.Scenes | |||
4631 | } | 4649 | } |
4632 | 4650 | ||
4633 | /// <summary> | 4651 | /// <summary> |
4652 | /// Tell a single agent to prepare to close. | ||
4653 | /// </summary> | ||
4654 | /// <remarks> | ||
4655 | /// This should only be called if we may close the agent but there will be some delay in so doing. Meant for | ||
4656 | /// internal use - other callers should almost certainly called IncomingCloseAgent(). | ||
4657 | /// </remarks> | ||
4658 | /// <param name="sp"></param> | ||
4659 | /// <returns>true if pre-close state notification was successful. false if the agent | ||
4660 | /// was not in a state where it could transition to pre-close.</returns> | ||
4661 | public bool IncomingPreCloseAgent(ScenePresence sp) | ||
4662 | { | ||
4663 | lock (m_removeClientLock) | ||
4664 | { | ||
4665 | // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may | ||
4666 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not | ||
4667 | // want to obey this close since C may have renewed the child agent lease on B. | ||
4668 | if (sp.DoNotCloseAfterTeleport) | ||
4669 | { | ||
4670 | m_log.DebugFormat( | ||
4671 | "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection", | ||
4672 | sp.IsChildAgent ? "child" : "root", sp.Name, Name); | ||
4673 | |||
4674 | // Need to reset the flag so that a subsequent close after another teleport can succeed. | ||
4675 | sp.DoNotCloseAfterTeleport = false; | ||
4676 | |||
4677 | return false; | ||
4678 | } | ||
4679 | |||
4680 | if (sp.LifecycleState != ScenePresenceState.Running) | ||
4681 | { | ||
4682 | m_log.DebugFormat( | ||
4683 | "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}", | ||
4684 | sp.Name, Name, sp.LifecycleState); | ||
4685 | |||
4686 | return false; | ||
4687 | } | ||
4688 | |||
4689 | sp.LifecycleState = ScenePresenceState.PreRemove; | ||
4690 | |||
4691 | return true; | ||
4692 | } | ||
4693 | } | ||
4694 | |||
4695 | /// <summary> | ||
4634 | /// Tell a single agent to disconnect from the region. | 4696 | /// Tell a single agent to disconnect from the region. |
4635 | /// </summary> | 4697 | /// </summary> |
4636 | /// <param name="agentID"></param> | 4698 | /// <param name="agentID"></param> |
@@ -4649,16 +4711,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
4649 | if (sp == null) | 4711 | if (sp == null) |
4650 | { | 4712 | { |
4651 | m_log.DebugFormat( | 4713 | m_log.DebugFormat( |
4652 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}", | 4714 | "[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}", |
4653 | agentID, Name); | 4715 | agentID, Name); |
4654 | 4716 | ||
4655 | return false; | 4717 | return false; |
4656 | } | 4718 | } |
4657 | 4719 | ||
4658 | if (sp.LifecycleState != ScenePresenceState.Running) | 4720 | if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) |
4659 | { | 4721 | { |
4660 | m_log.DebugFormat( | 4722 | m_log.DebugFormat( |
4661 | "[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}", | 4723 | "[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}", |
4662 | sp.Name, Name, sp.LifecycleState); | 4724 | sp.Name, Name, sp.LifecycleState); |
4663 | 4725 | ||
4664 | return false; | 4726 | return false; |
@@ -6025,7 +6087,7 @@ Environment.Exit(1); | |||
6025 | { | 6087 | { |
6026 | if (!AuthorizeUser(aCircuit, false, out reason)) | 6088 | if (!AuthorizeUser(aCircuit, false, out reason)) |
6027 | { | 6089 | { |
6028 | // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); | 6090 | //m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); |
6029 | return false; | 6091 | return false; |
6030 | } | 6092 | } |
6031 | } | 6093 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs index dc3a212..cae7fe5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs | |||
@@ -37,7 +37,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
37 | /// This is a state machine. | 37 | /// This is a state machine. |
38 | /// | 38 | /// |
39 | /// [Entry] => Running | 39 | /// [Entry] => Running |
40 | /// Running => Removing | 40 | /// Running => PreRemove, Removing |
41 | /// PreRemove => Running, Removing | ||
41 | /// Removing => Removed | 42 | /// Removing => Removed |
42 | /// | 43 | /// |
43 | /// All other methods should only see the scene presence in running state - this is the normal operational state | 44 | /// All other methods should only see the scene presence in running state - this is the normal operational state |
@@ -46,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
46 | public enum ScenePresenceState | 47 | public enum ScenePresenceState |
47 | { | 48 | { |
48 | Running, // Normal operation state. The scene presence is available. | 49 | Running, // Normal operation state. The scene presence is available. |
50 | PreRemove, // The presence is due to be removed but can still be returning to running. | ||
49 | Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient. | 51 | Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient. |
50 | Removed, // The presence has been removed from the scene and is effectively dead. | 52 | Removed, // The presence has been removed from the scene and is effectively dead. |
51 | // There is no exit from this state. | 53 | // There is no exit from this state. |
@@ -80,8 +82,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
80 | 82 | ||
81 | lock (this) | 83 | lock (this) |
82 | { | 84 | { |
83 | if (newState == ScenePresenceState.Removing && m_state == ScenePresenceState.Running) | 85 | if (newState == m_state) |
86 | return; | ||
87 | else if (newState == ScenePresenceState.Running && m_state == ScenePresenceState.PreRemove) | ||
84 | transitionOkay = true; | 88 | transitionOkay = true; |
89 | else if (newState == ScenePresenceState.PreRemove && m_state == ScenePresenceState.Running) | ||
90 | transitionOkay = true; | ||
91 | else if (newState == ScenePresenceState.Removing) | ||
92 | { | ||
93 | if (m_state == ScenePresenceState.Running || m_state == ScenePresenceState.PreRemove) | ||
94 | transitionOkay = true; | ||
95 | } | ||
85 | else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing) | 96 | else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing) |
86 | transitionOkay = true; | 97 | transitionOkay = true; |
87 | } | 98 | } |
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index 15dea17..1eb0a6b 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs | |||
@@ -624,9 +624,16 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
624 | int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); | 624 | int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); |
625 | avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); | 625 | avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); |
626 | 626 | ||
627 | string childAgentStatus; | ||
628 | |||
629 | if (llClient.SceneAgent != null) | ||
630 | childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y"; | ||
631 | else | ||
632 | childAgentStatus = "Off!"; | ||
633 | |||
627 | m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", | 634 | m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", |
628 | scene.RegionInfo.RegionName, llClient.Name, | 635 | scene.RegionInfo.RegionName, llClient.Name, |
629 | llClient.SceneAgent.IsChildAgent ? "N" : "Y", | 636 | childAgentStatus, |
630 | (DateTime.Now - cinfo.StartedTime).Minutes, | 637 | (DateTime.Now - cinfo.StartedTime).Minutes, |
631 | avg_reqs, | 638 | avg_reqs, |
632 | string.Format( | 639 | string.Format( |
diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index 89cba8a..c63b409 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs | |||
@@ -106,6 +106,9 @@ namespace OpenSim.Server.Handlers.Grid | |||
106 | case "get_default_regions": | 106 | case "get_default_regions": |
107 | return GetDefaultRegions(request); | 107 | return GetDefaultRegions(request); |
108 | 108 | ||
109 | case "get_default_hypergrid_regions": | ||
110 | return GetDefaultHypergridRegions(request); | ||
111 | |||
109 | case "get_fallback_regions": | 112 | case "get_fallback_regions": |
110 | return GetFallbackRegions(request); | 113 | return GetFallbackRegions(request); |
111 | 114 | ||
@@ -444,6 +447,36 @@ namespace OpenSim.Server.Handlers.Grid | |||
444 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | 447 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); |
445 | } | 448 | } |
446 | 449 | ||
450 | byte[] GetDefaultHypergridRegions(Dictionary<string, object> request) | ||
451 | { | ||
452 | //m_log.DebugFormat("[GRID HANDLER]: GetDefaultRegions"); | ||
453 | UUID scopeID = UUID.Zero; | ||
454 | if (request.ContainsKey("SCOPEID")) | ||
455 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); | ||
456 | else | ||
457 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region range"); | ||
458 | |||
459 | List<GridRegion> rinfos = m_GridService.GetDefaultHypergridRegions(scopeID); | ||
460 | |||
461 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
462 | if ((rinfos == null) || ((rinfos != null) && (rinfos.Count == 0))) | ||
463 | result["result"] = "null"; | ||
464 | else | ||
465 | { | ||
466 | int i = 0; | ||
467 | foreach (GridRegion rinfo in rinfos) | ||
468 | { | ||
469 | Dictionary<string, object> rinfoDict = rinfo.ToKeyValuePairs(); | ||
470 | result["region" + i] = rinfoDict; | ||
471 | i++; | ||
472 | } | ||
473 | } | ||
474 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
475 | |||
476 | //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); | ||
477 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
478 | } | ||
479 | |||
447 | byte[] GetFallbackRegions(Dictionary<string, object> request) | 480 | byte[] GetFallbackRegions(Dictionary<string, object> request) |
448 | { | 481 | { |
449 | //m_log.DebugFormat("[GRID HANDLER]: GetRegionRange"); | 482 | //m_log.DebugFormat("[GRID HANDLER]: GetRegionRange"); |
diff --git a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs index f982cc1..af91cdb 100644 --- a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs | |||
@@ -525,6 +525,57 @@ namespace OpenSim.Services.Connectors | |||
525 | return rinfos; | 525 | return rinfos; |
526 | } | 526 | } |
527 | 527 | ||
528 | public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID) | ||
529 | { | ||
530 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
531 | |||
532 | sendData["SCOPEID"] = scopeID.ToString(); | ||
533 | |||
534 | sendData["METHOD"] = "get_default_hypergrid_regions"; | ||
535 | |||
536 | List<GridRegion> rinfos = new List<GridRegion>(); | ||
537 | string reply = string.Empty; | ||
538 | string uri = m_ServerURI + "/grid"; | ||
539 | try | ||
540 | { | ||
541 | reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
542 | uri, | ||
543 | ServerUtils.BuildQueryString(sendData)); | ||
544 | |||
545 | //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); | ||
546 | } | ||
547 | catch (Exception e) | ||
548 | { | ||
549 | m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); | ||
550 | return rinfos; | ||
551 | } | ||
552 | |||
553 | if (reply != string.Empty) | ||
554 | { | ||
555 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
556 | |||
557 | if (replyData != null) | ||
558 | { | ||
559 | Dictionary<string, object>.ValueCollection rinfosList = replyData.Values; | ||
560 | foreach (object r in rinfosList) | ||
561 | { | ||
562 | if (r is Dictionary<string, object>) | ||
563 | { | ||
564 | GridRegion rinfo = new GridRegion((Dictionary<string, object>)r); | ||
565 | rinfos.Add(rinfo); | ||
566 | } | ||
567 | } | ||
568 | } | ||
569 | else | ||
570 | m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions {0} received null response", | ||
571 | scopeID); | ||
572 | } | ||
573 | else | ||
574 | m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions received null reply"); | ||
575 | |||
576 | return rinfos; | ||
577 | } | ||
578 | |||
528 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) | 579 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) |
529 | { | 580 | { |
530 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | 581 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index 043d131..36a5182 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs | |||
@@ -341,6 +341,12 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
341 | return new List<GridRegion>(0); | 341 | return new List<GridRegion>(0); |
342 | } | 342 | } |
343 | 343 | ||
344 | public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID) | ||
345 | { | ||
346 | // TODO: Allow specifying the default grid location | ||
347 | return GetDefaultRegions(scopeID); | ||
348 | } | ||
349 | |||
344 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) | 350 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) |
345 | { | 351 | { |
346 | GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true); | 352 | GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true); |
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index a1485c8..e72b7f9 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs | |||
@@ -265,8 +265,9 @@ namespace OpenSim.Services.GridService | |||
265 | m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); | 265 | m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); |
266 | } | 266 | } |
267 | 267 | ||
268 | m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", | 268 | m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3} with flags {4}", |
269 | regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY); | 269 | regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY, |
270 | (OpenSim.Framework.RegionFlags)flags); | ||
270 | 271 | ||
271 | return String.Empty; | 272 | return String.Empty; |
272 | } | 273 | } |
@@ -478,6 +479,33 @@ namespace OpenSim.Services.GridService | |||
478 | return ret; | 479 | return ret; |
479 | } | 480 | } |
480 | 481 | ||
482 | public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID) | ||
483 | { | ||
484 | List<GridRegion> ret = new List<GridRegion>(); | ||
485 | |||
486 | List<RegionData> regions = m_Database.GetDefaultHypergridRegions(scopeID); | ||
487 | |||
488 | foreach (RegionData r in regions) | ||
489 | { | ||
490 | if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0) | ||
491 | ret.Add(RegionData2RegionInfo(r)); | ||
492 | } | ||
493 | |||
494 | int hgDefaultRegionsFoundOnline = regions.Count; | ||
495 | |||
496 | // For now, hypergrid default regions will always be given precedence but we will also return simple default | ||
497 | // regions in case no specific hypergrid regions are specified. | ||
498 | ret.AddRange(GetDefaultRegions(scopeID)); | ||
499 | |||
500 | int normalDefaultRegionsFoundOnline = ret.Count - hgDefaultRegionsFoundOnline; | ||
501 | |||
502 | m_log.DebugFormat( | ||
503 | "[GRID SERVICE]: GetDefaultHypergridRegions returning {0} hypergrid default and {1} normal default regions", | ||
504 | hgDefaultRegionsFoundOnline, normalDefaultRegionsFoundOnline); | ||
505 | |||
506 | return ret; | ||
507 | } | ||
508 | |||
481 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) | 509 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) |
482 | { | 510 | { |
483 | List<GridRegion> ret = new List<GridRegion>(); | 511 | List<GridRegion> ret = new List<GridRegion>(); |
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index 8335724..4024295 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs | |||
@@ -79,7 +79,7 @@ namespace OpenSim.Services.GridService | |||
79 | { | 79 | { |
80 | if (m_DefaultRegion == null) | 80 | if (m_DefaultRegion == null) |
81 | { | 81 | { |
82 | List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID); | 82 | List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID); |
83 | if (defs != null && defs.Count > 0) | 83 | if (defs != null && defs.Count > 0) |
84 | m_DefaultRegion = defs[0]; | 84 | m_DefaultRegion = defs[0]; |
85 | else | 85 | else |
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index e10c4cb..f6136b5 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs | |||
@@ -171,7 +171,7 @@ namespace OpenSim.Services.HypergridService | |||
171 | m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName); | 171 | m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName); |
172 | if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty) | 172 | if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty) |
173 | { | 173 | { |
174 | List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID); | 174 | List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID); |
175 | if (defs != null && defs.Count > 0) | 175 | if (defs != null && defs.Count > 0) |
176 | { | 176 | { |
177 | region = defs[0]; | 177 | region = defs[0]; |
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index cecbe9e..e3c70d3 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs | |||
@@ -97,6 +97,7 @@ namespace OpenSim.Services.Interfaces | |||
97 | List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax); | 97 | List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax); |
98 | 98 | ||
99 | List<GridRegion> GetDefaultRegions(UUID scopeID); | 99 | List<GridRegion> GetDefaultRegions(UUID scopeID); |
100 | List<GridRegion> GetDefaultHypergridRegions(UUID scopeID); | ||
100 | List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y); | 101 | List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y); |
101 | List<GridRegion> GetHyperlinks(UUID scopeID); | 102 | List<GridRegion> GetHyperlinks(UUID scopeID); |
102 | 103 | ||
diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs index b1cdd45..944411f 100644 --- a/OpenSim/Services/UserAccountService/GridUserService.cs +++ b/OpenSim/Services/UserAccountService/GridUserService.cs | |||
@@ -47,6 +47,44 @@ namespace OpenSim.Services.UserAccountService | |||
47 | public GridUserService(IConfigSource config) : base(config) | 47 | public GridUserService(IConfigSource config) : base(config) |
48 | { | 48 | { |
49 | m_log.Debug("[GRID USER SERVICE]: Starting user grid service"); | 49 | m_log.Debug("[GRID USER SERVICE]: Starting user grid service"); |
50 | |||
51 | MainConsole.Instance.Commands.AddCommand( | ||
52 | "Users", false, | ||
53 | "show grid users online", | ||
54 | "show grid users online", | ||
55 | "Show number of grid users registered as online.", | ||
56 | "This number may not be accurate as a region may crash or not be cleanly shutdown and leave grid users shown as online\n." | ||
57 | + "For this reason, users online for more than 5 days are not currently counted", | ||
58 | HandleShowGridUsersOnline); | ||
59 | } | ||
60 | |||
61 | protected void HandleShowGridUsersOnline(string module, string[] cmdparams) | ||
62 | { | ||
63 | // if (cmdparams.Length != 4) | ||
64 | // { | ||
65 | // MainConsole.Instance.Output("Usage: show grid users online"); | ||
66 | // return; | ||
67 | // } | ||
68 | |||
69 | // int onlineCount; | ||
70 | int onlineRecentlyCount = 0; | ||
71 | |||
72 | DateTime now = DateTime.UtcNow; | ||
73 | |||
74 | foreach (GridUserData gu in m_Database.GetAll("")) | ||
75 | { | ||
76 | if (bool.Parse(gu.Data["Online"])) | ||
77 | { | ||
78 | // onlineCount++; | ||
79 | |||
80 | int unixLoginTime = int.Parse(gu.Data["Login"]); | ||
81 | |||
82 | if ((now - Util.ToDateTime(unixLoginTime)).Days < 5) | ||
83 | onlineRecentlyCount++; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | MainConsole.Instance.OutputFormat("Users online: {0}", onlineRecentlyCount); | ||
50 | } | 88 | } |
51 | 89 | ||
52 | public virtual GridUserInfo GetGridUserInfo(string userID) | 90 | public virtual GridUserInfo GetGridUserInfo(string userID) |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs index 9a9371d..9bc8512 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs | |||
@@ -35,6 +35,11 @@ namespace pCampBot | |||
35 | { | 35 | { |
36 | public class AbstractBehaviour : IBehaviour | 36 | public class AbstractBehaviour : IBehaviour |
37 | { | 37 | { |
38 | /// <summary> | ||
39 | /// Abbreviated name of this behaviour. | ||
40 | /// </summary> | ||
41 | public string AbbreviatedName { get; protected set; } | ||
42 | |||
38 | public string Name { get; protected set; } | 43 | public string Name { get; protected set; } |
39 | 44 | ||
40 | public Bot Bot { get; protected set; } | 45 | public Bot Bot { get; protected set; } |
@@ -45,5 +50,7 @@ namespace pCampBot | |||
45 | { | 50 | { |
46 | Bot = bot; | 51 | Bot = bot; |
47 | } | 52 | } |
53 | |||
54 | public virtual void Close() {} | ||
48 | } | 55 | } |
49 | } | 56 | } |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs index 1e01c64..4d806fc 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs | |||
@@ -47,7 +47,11 @@ namespace pCampBot | |||
47 | 47 | ||
48 | public const int m_regionCrossingTimeout = 1000 * 60; | 48 | public const int m_regionCrossingTimeout = 1000 * 60; |
49 | 49 | ||
50 | public CrossBehaviour() { Name = "Cross"; } | 50 | public CrossBehaviour() |
51 | { | ||
52 | AbbreviatedName = "c"; | ||
53 | Name = "Cross"; | ||
54 | } | ||
51 | 55 | ||
52 | public override void Action() | 56 | public override void Action() |
53 | { | 57 | { |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs index 66a336a..59f6244 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs | |||
@@ -29,6 +29,7 @@ using OpenMetaverse; | |||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Linq; | 31 | using System.Linq; |
32 | using System.Threading; | ||
32 | using pCampBot.Interfaces; | 33 | using pCampBot.Interfaces; |
33 | 34 | ||
34 | namespace pCampBot | 35 | namespace pCampBot |
@@ -41,7 +42,11 @@ namespace pCampBot | |||
41 | /// </remarks> | 42 | /// </remarks> |
42 | public class GrabbingBehaviour : AbstractBehaviour | 43 | public class GrabbingBehaviour : AbstractBehaviour |
43 | { | 44 | { |
44 | public GrabbingBehaviour() { Name = "Grabbing"; } | 45 | public GrabbingBehaviour() |
46 | { | ||
47 | AbbreviatedName = "g"; | ||
48 | Name = "Grabbing"; | ||
49 | } | ||
45 | 50 | ||
46 | public override void Action() | 51 | public override void Action() |
47 | { | 52 | { |
@@ -56,6 +61,8 @@ namespace pCampBot | |||
56 | Bot.Client.Self.Grab(prim.LocalID); | 61 | Bot.Client.Self.Grab(prim.LocalID); |
57 | Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero); | 62 | Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero); |
58 | Bot.Client.Self.DeGrab(prim.LocalID); | 63 | Bot.Client.Self.DeGrab(prim.LocalID); |
64 | |||
65 | Thread.Sleep(1000); | ||
59 | } | 66 | } |
60 | } | 67 | } |
61 | } \ No newline at end of file | 68 | } \ No newline at end of file |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs index 9cf8a54..9a3075c 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs | |||
@@ -38,6 +38,10 @@ namespace pCampBot | |||
38 | /// </summary> | 38 | /// </summary> |
39 | public class NoneBehaviour : AbstractBehaviour | 39 | public class NoneBehaviour : AbstractBehaviour |
40 | { | 40 | { |
41 | public NoneBehaviour() { Name = "None"; } | 41 | public NoneBehaviour() |
42 | { | ||
43 | AbbreviatedName = "n"; | ||
44 | Name = "None"; | ||
45 | } | ||
42 | } | 46 | } |
43 | } \ No newline at end of file | 47 | } \ No newline at end of file |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs index daa7485..6fd2b7c 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs | |||
@@ -46,6 +46,7 @@ namespace pCampBot | |||
46 | 46 | ||
47 | public PhysicsBehaviour() | 47 | public PhysicsBehaviour() |
48 | { | 48 | { |
49 | AbbreviatedName = "p"; | ||
49 | Name = "Physics"; | 50 | Name = "Physics"; |
50 | talkarray = readexcuses(); | 51 | talkarray = readexcuses(); |
51 | } | 52 | } |
@@ -77,6 +78,12 @@ namespace pCampBot | |||
77 | Bot.Client.Self.Chat(randomf, 0, ChatType.Normal); | 78 | Bot.Client.Self.Chat(randomf, 0, ChatType.Normal); |
78 | } | 79 | } |
79 | 80 | ||
81 | public override void Close() | ||
82 | { | ||
83 | if (Bot.ConnectionState == ConnectionState.Connected) | ||
84 | Bot.Client.Self.Jump(false); | ||
85 | } | ||
86 | |||
80 | private string[] readexcuses() | 87 | private string[] readexcuses() |
81 | { | 88 | { |
82 | string allexcuses = ""; | 89 | string allexcuses = ""; |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs index fbb4e96..81f250d 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | 30 | using System.Linq; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | ||
32 | using log4net; | 33 | using log4net; |
33 | using OpenMetaverse; | 34 | using OpenMetaverse; |
34 | using pCampBot.Interfaces; | 35 | using pCampBot.Interfaces; |
@@ -42,7 +43,11 @@ namespace pCampBot | |||
42 | { | 43 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | 45 | ||
45 | public TeleportBehaviour() { Name = "Teleport"; } | 46 | public TeleportBehaviour() |
47 | { | ||
48 | AbbreviatedName = "t"; | ||
49 | Name = "Teleport"; | ||
50 | } | ||
46 | 51 | ||
47 | public override void Action() | 52 | public override void Action() |
48 | { | 53 | { |
@@ -70,6 +75,8 @@ namespace pCampBot | |||
70 | Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition); | 75 | Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition); |
71 | 76 | ||
72 | Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition); | 77 | Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition); |
78 | |||
79 | Thread.Sleep(Bot.Random.Next(3000, 10000)); | ||
73 | } | 80 | } |
74 | } | 81 | } |
75 | } \ No newline at end of file | 82 | } \ No newline at end of file |
diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index d418288..d0a4ef3 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs | |||
@@ -72,9 +72,10 @@ namespace pCampBot | |||
72 | /// Behaviours implemented by this bot. | 72 | /// Behaviours implemented by this bot. |
73 | /// </summary> | 73 | /// </summary> |
74 | /// <remarks> | 74 | /// <remarks> |
75 | /// Lock this list before manipulating it. | 75 | /// Indexed by abbreviated name. There can only be one instance of a particular behaviour. |
76 | /// Lock this structure before manipulating it. | ||
76 | /// </remarks> | 77 | /// </remarks> |
77 | public List<IBehaviour> Behaviours { get; private set; } | 78 | public Dictionary<string, IBehaviour> Behaviours { get; private set; } |
78 | 79 | ||
79 | /// <summary> | 80 | /// <summary> |
80 | /// Objects that the bot has discovered. | 81 | /// Objects that the bot has discovered. |
@@ -165,8 +166,6 @@ namespace pCampBot | |||
165 | { | 166 | { |
166 | ConnectionState = ConnectionState.Disconnected; | 167 | ConnectionState = ConnectionState.Disconnected; |
167 | 168 | ||
168 | behaviours.ForEach(b => b.Initialize(this)); | ||
169 | |||
170 | Random = new Random(Environment.TickCount);// We do stuff randomly here | 169 | Random = new Random(Environment.TickCount);// We do stuff randomly here |
171 | FirstName = firstName; | 170 | FirstName = firstName; |
172 | LastName = lastName; | 171 | LastName = lastName; |
@@ -176,12 +175,53 @@ namespace pCampBot | |||
176 | StartLocation = startLocation; | 175 | StartLocation = startLocation; |
177 | 176 | ||
178 | Manager = bm; | 177 | Manager = bm; |
179 | Behaviours = behaviours; | 178 | |
179 | Behaviours = new Dictionary<string, IBehaviour>(); | ||
180 | foreach (IBehaviour behaviour in behaviours) | ||
181 | AddBehaviour(behaviour); | ||
180 | 182 | ||
181 | // Only calling for use as a template. | 183 | // Only calling for use as a template. |
182 | CreateLibOmvClient(); | 184 | CreateLibOmvClient(); |
183 | } | 185 | } |
184 | 186 | ||
187 | public bool TryGetBehaviour(string abbreviatedName, out IBehaviour behaviour) | ||
188 | { | ||
189 | lock (Behaviours) | ||
190 | return Behaviours.TryGetValue(abbreviatedName, out behaviour); | ||
191 | } | ||
192 | |||
193 | public bool AddBehaviour(IBehaviour behaviour) | ||
194 | { | ||
195 | lock (Behaviours) | ||
196 | { | ||
197 | if (!Behaviours.ContainsKey(behaviour.AbbreviatedName)) | ||
198 | { | ||
199 | behaviour.Initialize(this); | ||
200 | Behaviours.Add(behaviour.AbbreviatedName, behaviour); | ||
201 | |||
202 | return true; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | return false; | ||
207 | } | ||
208 | |||
209 | public bool RemoveBehaviour(string abbreviatedName) | ||
210 | { | ||
211 | lock (Behaviours) | ||
212 | { | ||
213 | IBehaviour behaviour; | ||
214 | |||
215 | if (!Behaviours.TryGetValue(abbreviatedName, out behaviour)) | ||
216 | return false; | ||
217 | |||
218 | behaviour.Close(); | ||
219 | Behaviours.Remove(abbreviatedName); | ||
220 | |||
221 | return true; | ||
222 | } | ||
223 | } | ||
224 | |||
185 | private void CreateLibOmvClient() | 225 | private void CreateLibOmvClient() |
186 | { | 226 | { |
187 | GridClient newClient = new GridClient(); | 227 | GridClient newClient = new GridClient(); |
@@ -237,16 +277,25 @@ namespace pCampBot | |||
237 | private void Action() | 277 | private void Action() |
238 | { | 278 | { |
239 | while (ConnectionState != ConnectionState.Disconnecting) | 279 | while (ConnectionState != ConnectionState.Disconnecting) |
280 | { | ||
240 | lock (Behaviours) | 281 | lock (Behaviours) |
241 | Behaviours.ForEach( | 282 | { |
242 | b => | 283 | foreach (IBehaviour behaviour in Behaviours.Values) |
243 | { | 284 | { |
244 | Thread.Sleep(Random.Next(3000, 10000)); | 285 | // Thread.Sleep(Random.Next(3000, 10000)); |
245 | 286 | ||
246 | // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); | 287 | // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); |
247 | b.Action(); | 288 | behaviour.Action(); |
248 | } | 289 | } |
249 | ); | 290 | } |
291 | |||
292 | // XXX: This is a really shitty way of yielding so that behaviours can be added/removed | ||
293 | Thread.Sleep(100); | ||
294 | } | ||
295 | |||
296 | lock (Behaviours) | ||
297 | foreach (IBehaviour b in Behaviours.Values) | ||
298 | b.Close(); | ||
250 | } | 299 | } |
251 | 300 | ||
252 | /// <summary> | 301 | /// <summary> |
diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 5c3835b..3c1b11e 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs | |||
@@ -140,7 +140,7 @@ namespace pCampBot | |||
140 | /// <summary> | 140 | /// <summary> |
141 | /// Behaviour switches for bots. | 141 | /// Behaviour switches for bots. |
142 | /// </summary> | 142 | /// </summary> |
143 | private HashSet<string> m_behaviourSwitches = new HashSet<string>(); | 143 | private HashSet<string> m_defaultBehaviourSwitches = new HashSet<string>(); |
144 | 144 | ||
145 | /// <summary> | 145 | /// <summary> |
146 | /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data | 146 | /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data |
@@ -195,6 +195,20 @@ namespace pCampBot | |||
195 | HandleDisconnect); | 195 | HandleDisconnect); |
196 | 196 | ||
197 | m_console.Commands.AddCommand( | 197 | m_console.Commands.AddCommand( |
198 | "bot", false, "add behaviour", "add behaviour <abbreviated-name> [<bot-number>]", | ||
199 | "Add a behaviour to a bot", | ||
200 | "If no bot number is specified then behaviour is added to all bots.\n" | ||
201 | + "Can be performed on connected or disconnected bots.", | ||
202 | HandleAddBehaviour); | ||
203 | |||
204 | m_console.Commands.AddCommand( | ||
205 | "bot", false, "remove behaviour", "remove behaviour <abbreviated-name> [<bot-number>]", | ||
206 | "Remove a behaviour from a bot", | ||
207 | "If no bot number is specified then behaviour is added to all bots.\n" | ||
208 | + "Can be performed on connected or disconnected bots.", | ||
209 | HandleRemoveBehaviour); | ||
210 | |||
211 | m_console.Commands.AddCommand( | ||
198 | "bot", false, "sit", "sit", "Sit all bots on the ground.", | 212 | "bot", false, "sit", "sit", "Sit all bots on the ground.", |
199 | HandleSit); | 213 | HandleSit); |
200 | 214 | ||
@@ -212,7 +226,7 @@ namespace pCampBot | |||
212 | "bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus); | 226 | "bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus); |
213 | 227 | ||
214 | m_console.Commands.AddCommand( | 228 | m_console.Commands.AddCommand( |
215 | "bot", false, "show bot", "show bot <n>", | 229 | "bot", false, "show bot", "show bot <bot-number>", |
216 | "Shows the detailed status and settings of a particular bot.", HandleShowBotStatus); | 230 | "Shows the detailed status and settings of a particular bot.", HandleShowBotStatus); |
217 | 231 | ||
218 | m_bots = new List<Bot>(); | 232 | m_bots = new List<Bot>(); |
@@ -235,7 +249,7 @@ namespace pCampBot | |||
235 | m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last")); | 249 | m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last")); |
236 | 250 | ||
237 | Array.ForEach<string>( | 251 | Array.ForEach<string>( |
238 | startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b)); | 252 | startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_defaultBehaviourSwitches.Add(b)); |
239 | 253 | ||
240 | for (int i = 0; i < botcount; i++) | 254 | for (int i = 0; i < botcount; i++) |
241 | { | 255 | { |
@@ -243,28 +257,50 @@ namespace pCampBot | |||
243 | { | 257 | { |
244 | string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); | 258 | string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); |
245 | 259 | ||
246 | // We must give each bot its own list of instantiated behaviours since they store state. | 260 | CreateBot( |
247 | List<IBehaviour> behaviours = new List<IBehaviour>(); | 261 | this, |
248 | 262 | CreateBehavioursFromAbbreviatedNames(m_defaultBehaviourSwitches), | |
249 | // Hard-coded for now | 263 | m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); |
250 | if (m_behaviourSwitches.Contains("c")) | 264 | } |
251 | behaviours.Add(new CrossBehaviour()); | 265 | } |
266 | } | ||
267 | |||
268 | private List<IBehaviour> CreateBehavioursFromAbbreviatedNames(HashSet<string> abbreviatedNames) | ||
269 | { | ||
270 | // We must give each bot its own list of instantiated behaviours since they store state. | ||
271 | List<IBehaviour> behaviours = new List<IBehaviour>(); | ||
272 | |||
273 | // Hard-coded for now | ||
274 | foreach (string abName in abbreviatedNames) | ||
275 | { | ||
276 | IBehaviour newBehaviour = null; | ||
252 | 277 | ||
253 | if (m_behaviourSwitches.Contains("g")) | 278 | if (abName == "c") |
254 | behaviours.Add(new GrabbingBehaviour()); | 279 | newBehaviour = new CrossBehaviour(); |
255 | 280 | ||
256 | if (m_behaviourSwitches.Contains("n")) | 281 | if (abName == "g") |
257 | behaviours.Add(new NoneBehaviour()); | 282 | newBehaviour = new GrabbingBehaviour(); |
258 | 283 | ||
259 | if (m_behaviourSwitches.Contains("p")) | 284 | if (abName == "n") |
260 | behaviours.Add(new PhysicsBehaviour()); | 285 | newBehaviour = new NoneBehaviour(); |
261 | |||
262 | if (m_behaviourSwitches.Contains("t")) | ||
263 | behaviours.Add(new TeleportBehaviour()); | ||
264 | 286 | ||
265 | CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); | 287 | if (abName == "p") |
288 | newBehaviour = new PhysicsBehaviour(); | ||
289 | |||
290 | if (abName == "t") | ||
291 | newBehaviour = new TeleportBehaviour(); | ||
292 | |||
293 | if (newBehaviour != null) | ||
294 | { | ||
295 | behaviours.Add(newBehaviour); | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | MainConsole.Instance.OutputFormat("No behaviour with abbreviated name {0} found", abName); | ||
266 | } | 300 | } |
267 | } | 301 | } |
302 | |||
303 | return behaviours; | ||
268 | } | 304 | } |
269 | 305 | ||
270 | public void ConnectBots(int botcount) | 306 | public void ConnectBots(int botcount) |
@@ -453,6 +489,118 @@ namespace pCampBot | |||
453 | } | 489 | } |
454 | } | 490 | } |
455 | 491 | ||
492 | private void HandleAddBehaviour(string module, string[] cmd) | ||
493 | { | ||
494 | if (cmd.Length < 3 || cmd.Length > 4) | ||
495 | { | ||
496 | MainConsole.Instance.OutputFormat("Usage: add behaviour <abbreviated-behaviour> [<bot-number>]"); | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | string rawBehaviours = cmd[2]; | ||
501 | |||
502 | List<Bot> botsToEffect = new List<Bot>(); | ||
503 | |||
504 | if (cmd.Length == 3) | ||
505 | { | ||
506 | lock (m_bots) | ||
507 | botsToEffect.AddRange(m_bots); | ||
508 | } | ||
509 | else | ||
510 | { | ||
511 | int botNumber; | ||
512 | if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) | ||
513 | return; | ||
514 | |||
515 | Bot bot = GetBotFromNumber(botNumber); | ||
516 | |||
517 | if (bot == null) | ||
518 | { | ||
519 | MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); | ||
520 | return; | ||
521 | } | ||
522 | |||
523 | botsToEffect.Add(bot); | ||
524 | } | ||
525 | |||
526 | |||
527 | HashSet<string> rawAbbreviatedSwitchesToAdd = new HashSet<string>(); | ||
528 | Array.ForEach<string>(rawBehaviours.Split(new char[] { ',' }), b => rawAbbreviatedSwitchesToAdd.Add(b)); | ||
529 | |||
530 | foreach (Bot bot in botsToEffect) | ||
531 | { | ||
532 | List<IBehaviour> behavioursAdded = new List<IBehaviour>(); | ||
533 | |||
534 | foreach (IBehaviour behaviour in CreateBehavioursFromAbbreviatedNames(rawAbbreviatedSwitchesToAdd)) | ||
535 | { | ||
536 | if (bot.AddBehaviour(behaviour)) | ||
537 | behavioursAdded.Add(behaviour); | ||
538 | } | ||
539 | |||
540 | MainConsole.Instance.OutputFormat( | ||
541 | "Added behaviours {0} to bot {1}", | ||
542 | string.Join(", ", behavioursAdded.ConvertAll<string>(b => b.Name).ToArray()), bot.Name); | ||
543 | } | ||
544 | } | ||
545 | |||
546 | private void HandleRemoveBehaviour(string module, string[] cmd) | ||
547 | { | ||
548 | if (cmd.Length < 3 || cmd.Length > 4) | ||
549 | { | ||
550 | MainConsole.Instance.OutputFormat("Usage: remove behaviour <abbreviated-behaviour> [<bot-number>]"); | ||
551 | return; | ||
552 | } | ||
553 | |||
554 | string rawBehaviours = cmd[2]; | ||
555 | |||
556 | List<Bot> botsToEffect = new List<Bot>(); | ||
557 | |||
558 | if (cmd.Length == 3) | ||
559 | { | ||
560 | lock (m_bots) | ||
561 | botsToEffect.AddRange(m_bots); | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | int botNumber; | ||
566 | if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) | ||
567 | return; | ||
568 | |||
569 | Bot bot = GetBotFromNumber(botNumber); | ||
570 | |||
571 | if (bot == null) | ||
572 | { | ||
573 | MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); | ||
574 | return; | ||
575 | } | ||
576 | |||
577 | botsToEffect.Add(bot); | ||
578 | } | ||
579 | |||
580 | HashSet<string> abbreviatedBehavioursToRemove = new HashSet<string>(); | ||
581 | Array.ForEach<string>(rawBehaviours.Split(new char[] { ',' }), b => abbreviatedBehavioursToRemove.Add(b)); | ||
582 | |||
583 | foreach (Bot bot in botsToEffect) | ||
584 | { | ||
585 | List<IBehaviour> behavioursRemoved = new List<IBehaviour>(); | ||
586 | |||
587 | foreach (string b in abbreviatedBehavioursToRemove) | ||
588 | { | ||
589 | IBehaviour behaviour; | ||
590 | |||
591 | if (bot.TryGetBehaviour(b, out behaviour)) | ||
592 | { | ||
593 | bot.RemoveBehaviour(b); | ||
594 | behavioursRemoved.Add(behaviour); | ||
595 | } | ||
596 | } | ||
597 | |||
598 | MainConsole.Instance.OutputFormat( | ||
599 | "Removed behaviours {0} to bot {1}", | ||
600 | string.Join(", ", behavioursRemoved.ConvertAll<string>(b => b.Name).ToArray()), bot.Name); | ||
601 | } | ||
602 | } | ||
603 | |||
456 | private void HandleDisconnect(string module, string[] cmd) | 604 | private void HandleDisconnect(string module, string[] cmd) |
457 | { | 605 | { |
458 | lock (m_bots) | 606 | lock (m_bots) |
@@ -572,10 +720,11 @@ namespace pCampBot | |||
572 | private void HandleShowBotsStatus(string module, string[] cmd) | 720 | private void HandleShowBotsStatus(string module, string[] cmd) |
573 | { | 721 | { |
574 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | 722 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); |
575 | cdt.AddColumn("Name", 30); | 723 | cdt.AddColumn("Name", 24); |
576 | cdt.AddColumn("Region", 30); | 724 | cdt.AddColumn("Region", 24); |
577 | cdt.AddColumn("Status", 14); | 725 | cdt.AddColumn("Status", 13); |
578 | cdt.AddColumn("Connections", 11); | 726 | cdt.AddColumn("Conns", 5); |
727 | cdt.AddColumn("Behaviours", 20); | ||
579 | 728 | ||
580 | Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>(); | 729 | Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>(); |
581 | foreach (object o in Enum.GetValues(typeof(ConnectionState))) | 730 | foreach (object o in Enum.GetValues(typeof(ConnectionState))) |
@@ -583,13 +732,17 @@ namespace pCampBot | |||
583 | 732 | ||
584 | lock (m_bots) | 733 | lock (m_bots) |
585 | { | 734 | { |
586 | foreach (Bot pb in m_bots) | 735 | foreach (Bot bot in m_bots) |
587 | { | 736 | { |
588 | Simulator currentSim = pb.Client.Network.CurrentSim; | 737 | Simulator currentSim = bot.Client.Network.CurrentSim; |
589 | totals[pb.ConnectionState]++; | 738 | totals[bot.ConnectionState]++; |
590 | 739 | ||
591 | cdt.AddRow( | 740 | cdt.AddRow( |
592 | pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState, pb.SimulatorsCount); | 741 | bot.Name, |
742 | currentSim != null ? currentSim.Name : "(none)", | ||
743 | bot.ConnectionState, | ||
744 | bot.SimulatorsCount, | ||
745 | string.Join(",", bot.Behaviours.Keys.ToArray())); | ||
593 | } | 746 | } |
594 | } | 747 | } |
595 | 748 | ||
@@ -616,16 +769,11 @@ namespace pCampBot | |||
616 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber)) | 769 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber)) |
617 | return; | 770 | return; |
618 | 771 | ||
619 | string name = string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); | 772 | Bot bot = GetBotFromNumber(botNumber); |
620 | |||
621 | Bot bot; | ||
622 | |||
623 | lock (m_bots) | ||
624 | bot = m_bots.Find(b => b.Name == name); | ||
625 | 773 | ||
626 | if (bot == null) | 774 | if (bot == null) |
627 | { | 775 | { |
628 | MainConsole.Instance.Output("No bot found with name {0}", name); | 776 | MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); |
629 | return; | 777 | return; |
630 | } | 778 | } |
631 | 779 | ||
@@ -645,12 +793,39 @@ namespace pCampBot | |||
645 | MainConsole.Instance.Output("Settings"); | 793 | MainConsole.Instance.Output("Settings"); |
646 | 794 | ||
647 | ConsoleDisplayList statusCdl = new ConsoleDisplayList(); | 795 | ConsoleDisplayList statusCdl = new ConsoleDisplayList(); |
796 | |||
797 | statusCdl.AddRow( | ||
798 | "Behaviours", | ||
799 | string.Join(", ", bot.Behaviours.Values.ToList().ConvertAll<string>(b => b.Name).ToArray())); | ||
800 | |||
648 | GridClient botClient = bot.Client; | 801 | GridClient botClient = bot.Client; |
649 | statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); | 802 | statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); |
650 | 803 | ||
651 | MainConsole.Instance.Output(statusCdl.ToString()); | 804 | MainConsole.Instance.Output(statusCdl.ToString()); |
652 | } | 805 | } |
653 | 806 | ||
807 | /// <summary> | ||
808 | /// Get a specific bot from its number. | ||
809 | /// </summary> | ||
810 | /// <returns>null if no bot was found</returns> | ||
811 | /// <param name='botNumber'></param> | ||
812 | private Bot GetBotFromNumber(int botNumber) | ||
813 | { | ||
814 | string name = GenerateBotNameFromNumber(botNumber); | ||
815 | |||
816 | Bot bot; | ||
817 | |||
818 | lock (m_bots) | ||
819 | bot = m_bots.Find(b => b.Name == name); | ||
820 | |||
821 | return bot; | ||
822 | } | ||
823 | |||
824 | private string GenerateBotNameFromNumber(int botNumber) | ||
825 | { | ||
826 | return string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); | ||
827 | } | ||
828 | |||
654 | internal void Grid_GridRegion(object o, GridRegionEventArgs args) | 829 | internal void Grid_GridRegion(object o, GridRegionEventArgs args) |
655 | { | 830 | { |
656 | lock (RegionsKnown) | 831 | lock (RegionsKnown) |
diff --git a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs index 9c984be..0ed4825 100644 --- a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs | |||
@@ -32,6 +32,11 @@ namespace pCampBot.Interfaces | |||
32 | public interface IBehaviour | 32 | public interface IBehaviour |
33 | { | 33 | { |
34 | /// <summary> | 34 | /// <summary> |
35 | /// Abbreviated name of this behaviour. | ||
36 | /// </summary> | ||
37 | string AbbreviatedName { get; } | ||
38 | |||
39 | /// <summary> | ||
35 | /// Name of this behaviour. | 40 | /// Name of this behaviour. |
36 | /// </summary> | 41 | /// </summary> |
37 | string Name { get; } | 42 | string Name { get; } |
@@ -46,6 +51,14 @@ namespace pCampBot.Interfaces | |||
46 | void Initialize(Bot bot); | 51 | void Initialize(Bot bot); |
47 | 52 | ||
48 | /// <summary> | 53 | /// <summary> |
54 | /// Close down this behaviour. | ||
55 | /// </summary> | ||
56 | /// <remarks> | ||
57 | /// This is triggered if a behaviour is removed via explicit command and when a bot is disconnected | ||
58 | /// </remarks> | ||
59 | void Close(); | ||
60 | |||
61 | /// <summary> | ||
49 | /// Action to take when this behaviour is invoked. | 62 | /// Action to take when this behaviour is invoked. |
50 | /// </summary> | 63 | /// </summary> |
51 | /// <param name="bot"></param> | 64 | /// <param name="bot"></param> |