diff options
Diffstat (limited to 'OpenSim')
21 files changed, 938 insertions, 296 deletions
diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs index c0ff454..794bfaf 100644 --- a/OpenSim/Framework/Console/ConsoleUtil.cs +++ b/OpenSim/Framework/Console/ConsoleUtil.cs | |||
@@ -179,8 +179,8 @@ namespace OpenSim.Framework.Console | |||
179 | /// Convert a console integer to an int, automatically complaining if a console is given. | 179 | /// Convert a console integer to an int, automatically complaining if a console is given. |
180 | /// </summary> | 180 | /// </summary> |
181 | /// <param name='console'>Can be null if no console is available.</param> | 181 | /// <param name='console'>Can be null if no console is available.</param> |
182 | /// <param name='rawConsoleVector'>/param> | 182 | /// <param name='rawConsoleInt'>/param> |
183 | /// <param name='vector'></param> | 183 | /// <param name='i'></param> |
184 | /// <returns></returns> | 184 | /// <returns></returns> |
185 | public static bool TryParseConsoleInt(ICommandConsole console, string rawConsoleInt, out int i) | 185 | public static bool TryParseConsoleInt(ICommandConsole console, string rawConsoleInt, out int i) |
186 | { | 186 | { |
@@ -194,6 +194,31 @@ namespace OpenSim.Framework.Console | |||
194 | 194 | ||
195 | return true; | 195 | return true; |
196 | } | 196 | } |
197 | |||
198 | /// <summary> | ||
199 | /// Convert a console integer to a natural int, automatically complaining if a console is given. | ||
200 | /// </summary> | ||
201 | /// <param name='console'>Can be null if no console is available.</param> | ||
202 | /// <param name='rawConsoleInt'>/param> | ||
203 | /// <param name='i'></param> | ||
204 | /// <returns></returns> | ||
205 | public static bool TryParseConsoleNaturalInt(ICommandConsole console, string rawConsoleInt, out int i) | ||
206 | { | ||
207 | if (TryParseConsoleInt(console, rawConsoleInt, out i)) | ||
208 | { | ||
209 | if (i < 0) | ||
210 | { | ||
211 | if (console != null) | ||
212 | console.OutputFormat("ERROR: {0} is not a positive integer", rawConsoleInt); | ||
213 | |||
214 | return false; | ||
215 | } | ||
216 | |||
217 | return true; | ||
218 | } | ||
219 | |||
220 | return false; | ||
221 | } | ||
197 | 222 | ||
198 | /// <summary> | 223 | /// <summary> |
199 | /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3 | 224 | /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3 |
diff --git a/OpenSim/Framework/Monitoring/StatsLogger.cs b/OpenSim/Framework/Monitoring/StatsLogger.cs index fa2e1b6..1e4fa11 100644 --- a/OpenSim/Framework/Monitoring/StatsLogger.cs +++ b/OpenSim/Framework/Monitoring/StatsLogger.cs | |||
@@ -67,7 +67,7 @@ namespace OpenSim.Framework.Monitoring | |||
67 | if (cmd[3] == "start") | 67 | if (cmd[3] == "start") |
68 | { | 68 | { |
69 | Start(); | 69 | Start(); |
70 | con.OutputFormat("Now recording all stats very {0}ms to file", m_statsLogIntervalMs); | 70 | con.OutputFormat("Now recording all stats to file every {0}ms", m_statsLogIntervalMs); |
71 | } | 71 | } |
72 | else if (cmd[3] == "stop") | 72 | else if (cmd[3] == "stop") |
73 | { | 73 | { |
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index 3e93638..bc7ecb7 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs | |||
@@ -201,11 +201,11 @@ namespace OpenSim | |||
201 | 201 | ||
202 | envConfigSource.LoadEnv(); | 202 | envConfigSource.LoadEnv(); |
203 | m_config.Source.Merge(envConfigSource); | 203 | m_config.Source.Merge(envConfigSource); |
204 | m_config.Source.ExpandKeyValues(); | ||
205 | } | 204 | } |
206 | 205 | ||
207 | |||
208 | ReadConfigSettings(); | 206 | ReadConfigSettings(); |
207 | |||
208 | m_config.Source.ExpandKeyValues(); | ||
209 | 209 | ||
210 | return m_config; | 210 | return m_config; |
211 | } | 211 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8cbbfd9..dc28be8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -6777,6 +6777,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6777 | } | 6777 | } |
6778 | #endregion | 6778 | #endregion |
6779 | 6779 | ||
6780 | if (SceneAgent.IsChildAgent) | ||
6781 | { | ||
6782 | SendCantSitBecauseChildAgentResponse(); | ||
6783 | return true; | ||
6784 | } | ||
6785 | |||
6780 | AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; | 6786 | AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; |
6781 | 6787 | ||
6782 | if (handlerAgentRequestSit != null) | 6788 | if (handlerAgentRequestSit != null) |
@@ -6801,6 +6807,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6801 | } | 6807 | } |
6802 | #endregion | 6808 | #endregion |
6803 | 6809 | ||
6810 | if (SceneAgent.IsChildAgent) | ||
6811 | { | ||
6812 | SendCantSitBecauseChildAgentResponse(); | ||
6813 | return true; | ||
6814 | } | ||
6815 | |||
6804 | AgentSit handlerAgentSit = OnAgentSit; | 6816 | AgentSit handlerAgentSit = OnAgentSit; |
6805 | if (handlerAgentSit != null) | 6817 | if (handlerAgentSit != null) |
6806 | { | 6818 | { |
@@ -6810,6 +6822,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6810 | return true; | 6822 | return true; |
6811 | } | 6823 | } |
6812 | 6824 | ||
6825 | /// <summary> | ||
6826 | /// Used when a child agent gets a sit response which should not be fulfilled. | ||
6827 | /// </summary> | ||
6828 | private void SendCantSitBecauseChildAgentResponse() | ||
6829 | { | ||
6830 | SendAlertMessage("Try moving closer. Can't sit on object because it is not in the same region as you."); | ||
6831 | } | ||
6832 | |||
6813 | private bool HandleSoundTrigger(IClientAPI sender, Packet Pack) | 6833 | private bool HandleSoundTrigger(IClientAPI sender, Packet Pack) |
6814 | { | 6834 | { |
6815 | SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack; | 6835 | SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack; |
@@ -12934,7 +12954,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12934 | { | 12954 | { |
12935 | if (p is ScenePresence) | 12955 | if (p is ScenePresence) |
12936 | { | 12956 | { |
12937 | ScenePresence presence = p as ScenePresence; | ||
12938 | // It turns out to get the agent to stop flying, you have to feed it stop flying velocities | 12957 | // It turns out to get the agent to stop flying, you have to feed it stop flying velocities |
12939 | // There's no explicit message to send the client to tell it to stop flying.. it relies on the | 12958 | // There's no explicit message to send the client to tell it to stop flying.. it relies on the |
12940 | // velocity, collision plane and avatar height | 12959 | // velocity, collision plane and avatar height |
@@ -12942,15 +12961,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12942 | // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air | 12961 | // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air |
12943 | // when the avatar stands up | 12962 | // when the avatar stands up |
12944 | 12963 | ||
12945 | Vector3 pos = presence.AbsolutePosition; | ||
12946 | |||
12947 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = | 12964 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = |
12948 | CreateImprovedTerseBlock(p, false); | 12965 | CreateImprovedTerseBlock(p, false); |
12949 | 12966 | ||
12950 | const float TIME_DILATION = 1.0f; | 12967 | const float TIME_DILATION = 1.0f; |
12951 | ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); | 12968 | ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); |
12952 | 12969 | ||
12953 | |||
12954 | ImprovedTerseObjectUpdatePacket packet | 12970 | ImprovedTerseObjectUpdatePacket packet |
12955 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( | 12971 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( |
12956 | PacketType.ImprovedTerseObjectUpdate); | 12972 | PacketType.ImprovedTerseObjectUpdate); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index cef6177..ea660bd 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -538,7 +538,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
538 | } | 538 | } |
539 | catch (Exception e) | 539 | catch (Exception e) |
540 | { | 540 | { |
541 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message); | 541 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e); |
542 | return null; | 542 | return null; |
543 | } | 543 | } |
544 | */ | 544 | */ |
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 966a05c..bf1cffb 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | |||
@@ -309,6 +309,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
309 | string serverURI = string.Empty; | 309 | string serverURI = string.Empty; |
310 | GetUserProfileServerURI(targetID, out serverURI); | 310 | GetUserProfileServerURI(targetID, out serverURI); |
311 | UUID creatorId = UUID.Zero; | 311 | UUID creatorId = UUID.Zero; |
312 | Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>(); | ||
312 | 313 | ||
313 | OSDMap parameters= new OSDMap(); | 314 | OSDMap parameters= new OSDMap(); |
314 | UUID.TryParse(args[0], out creatorId); | 315 | UUID.TryParse(args[0], out creatorId); |
@@ -316,15 +317,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
316 | OSD Params = (OSD)parameters; | 317 | OSD Params = (OSD)parameters; |
317 | if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString())) | 318 | if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString())) |
318 | { | 319 | { |
319 | // Error Handling here! | 320 | remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds); |
320 | // if(parameters.ContainsKey("message") | 321 | return; |
321 | } | 322 | } |
322 | 323 | ||
323 | parameters = (OSDMap)Params; | 324 | parameters = (OSDMap)Params; |
324 | 325 | ||
325 | OSDArray list = (OSDArray)parameters["result"]; | 326 | OSDArray list = (OSDArray)parameters["result"]; |
326 | 327 | ||
327 | Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>(); | ||
328 | 328 | ||
329 | foreach(OSD map in list) | 329 | foreach(OSD map in list) |
330 | { | 330 | { |
@@ -441,7 +441,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
441 | Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; | 441 | Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; |
442 | ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); | 442 | ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); |
443 | ScenePresence p = FindPresence(remoteClient.AgentId); | 443 | ScenePresence p = FindPresence(remoteClient.AgentId); |
444 | // Vector3 avaPos = p.AbsolutePosition; | ||
445 | 444 | ||
446 | string serverURI = string.Empty; | 445 | string serverURI = string.Empty; |
447 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | 446 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); |
@@ -542,14 +541,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
542 | 541 | ||
543 | string serverURI = string.Empty; | 542 | string serverURI = string.Empty; |
544 | GetUserProfileServerURI(targetId, out serverURI); | 543 | GetUserProfileServerURI(targetId, out serverURI); |
544 | |||
545 | Dictionary<UUID, string> picks = new Dictionary<UUID, string>(); | ||
545 | 546 | ||
546 | OSDMap parameters= new OSDMap(); | 547 | OSDMap parameters= new OSDMap(); |
547 | parameters.Add("creatorId", OSD.FromUUID(targetId)); | 548 | parameters.Add("creatorId", OSD.FromUUID(targetId)); |
548 | OSD Params = (OSD)parameters; | 549 | OSD Params = (OSD)parameters; |
549 | if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString())) | 550 | if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString())) |
550 | { | 551 | { |
551 | remoteClient.SendAgentAlertMessage( | 552 | remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks); |
552 | "Error requesting picks", false); | ||
553 | return; | 553 | return; |
554 | } | 554 | } |
555 | 555 | ||
@@ -557,8 +557,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
557 | 557 | ||
558 | OSDArray list = (OSDArray)parameters["result"]; | 558 | OSDArray list = (OSDArray)parameters["result"]; |
559 | 559 | ||
560 | Dictionary<UUID, string> picks = new Dictionary<UUID, string>(); | ||
561 | |||
562 | foreach(OSD map in list) | 560 | foreach(OSD map in list) |
563 | { | 561 | { |
564 | OSDMap m = (OSDMap)map; | 562 | OSDMap m = (OSDMap)map; |
@@ -762,8 +760,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
762 | object Note = (object)note; | 760 | object Note = (object)note; |
763 | if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString())) | 761 | if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString())) |
764 | { | 762 | { |
765 | remoteClient.SendAgentAlertMessage( | 763 | remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes); |
766 | "Error requesting note", false); | 764 | return; |
767 | } | 765 | } |
768 | note = (UserProfileNotes) Note; | 766 | note = (UserProfileNotes) Note; |
769 | 767 | ||
@@ -796,8 +794,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
796 | object Note = note; | 794 | object Note = note; |
797 | if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) | 795 | if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) |
798 | { | 796 | { |
799 | remoteClient.SendAgentAlertMessage( | 797 | return; |
800 | "Error updating note", false); | ||
801 | } | 798 | } |
802 | } | 799 | } |
803 | #endregion Notes | 800 | #endregion Notes |
@@ -1033,8 +1030,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1033 | OSD Params = (OSD)parameters; | 1030 | OSD Params = (OSD)parameters; |
1034 | if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString())) | 1031 | if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString())) |
1035 | { | 1032 | { |
1036 | // Error Handling here! | ||
1037 | // if(parameters.ContainsKey("message") | ||
1038 | return false; | 1033 | return false; |
1039 | } | 1034 | } |
1040 | 1035 | ||
@@ -1224,7 +1219,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1224 | byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); | 1219 | byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); |
1225 | 1220 | ||
1226 | HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); | 1221 | HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); |
1227 | // webRequest.Credentials = new NetworkCredential(rpcUser, rpcPass); | 1222 | |
1228 | webRequest.ContentType = "application/json-rpc"; | 1223 | webRequest.ContentType = "application/json-rpc"; |
1229 | webRequest.Method = "POST"; | 1224 | webRequest.Method = "POST"; |
1230 | 1225 | ||
@@ -1245,7 +1240,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1245 | } | 1240 | } |
1246 | 1241 | ||
1247 | Stream rstream = webResponse.GetResponseStream(); | 1242 | Stream rstream = webResponse.GetResponseStream(); |
1248 | OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); | 1243 | if (rstream.Length < 1) |
1244 | return false; | ||
1245 | |||
1246 | OSDMap mret = new OSDMap(); | ||
1247 | try | ||
1248 | { | ||
1249 | mret = (OSDMap)OSDParser.DeserializeJson(rstream); | ||
1250 | } | ||
1251 | catch (Exception e) | ||
1252 | { | ||
1253 | m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message); | ||
1254 | return false; | ||
1255 | } | ||
1256 | |||
1249 | 1257 | ||
1250 | if (mret.ContainsKey("error")) | 1258 | if (mret.ContainsKey("error")) |
1251 | return false; | 1259 | return false; |
@@ -1310,6 +1318,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1310 | } | 1318 | } |
1311 | 1319 | ||
1312 | Stream rstream = webResponse.GetResponseStream(); | 1320 | Stream rstream = webResponse.GetResponseStream(); |
1321 | if (rstream.Length < 1) | ||
1322 | return false; | ||
1313 | 1323 | ||
1314 | OSDMap response = new OSDMap(); | 1324 | OSDMap response = new OSDMap(); |
1315 | try | 1325 | try |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 6ff9988..1f3e7a1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -837,8 +837,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
837 | } | 837 | } |
838 | 838 | ||
839 | m_log.WarnFormat( | 839 | m_log.WarnFormat( |
840 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", | 840 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}", |
841 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 841 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
842 | 842 | ||
843 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); | 843 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); |
844 | return; | 844 | return; |
@@ -1058,8 +1058,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | m_log.WarnFormat( | 1060 | m_log.WarnFormat( |
1061 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", | 1061 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}", |
1062 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 1062 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
1063 | 1063 | ||
1064 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); | 1064 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); |
1065 | return; | 1065 | return; |
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs index 9c441ed..0c74b49 100644 --- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs +++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs | |||
@@ -48,8 +48,8 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")] | 48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")] |
49 | public class RestartModule : INonSharedRegionModule, IRestartModule | 49 | public class RestartModule : INonSharedRegionModule, IRestartModule |
50 | { | 50 | { |
51 | // private static readonly ILog m_log = | 51 | private static readonly ILog m_log = |
52 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | 53 | ||
54 | protected Scene m_Scene; | 54 | protected Scene m_Scene; |
55 | protected Timer m_CountdownTimer = null; | 55 | protected Timer m_CountdownTimer = null; |
@@ -223,11 +223,25 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
223 | 223 | ||
224 | public void SetTimer(int intervalSeconds) | 224 | public void SetTimer(int intervalSeconds) |
225 | { | 225 | { |
226 | m_CountdownTimer = new Timer(); | 226 | if (intervalSeconds > 0) |
227 | m_CountdownTimer.AutoReset = false; | 227 | { |
228 | m_CountdownTimer.Interval = intervalSeconds * 1000; | 228 | m_CountdownTimer = new Timer(); |
229 | m_CountdownTimer.Elapsed += OnTimer; | 229 | m_CountdownTimer.AutoReset = false; |
230 | m_CountdownTimer.Start(); | 230 | m_CountdownTimer.Interval = intervalSeconds * 1000; |
231 | m_CountdownTimer.Elapsed += OnTimer; | ||
232 | m_CountdownTimer.Start(); | ||
233 | } | ||
234 | else if (m_CountdownTimer != null) | ||
235 | { | ||
236 | m_CountdownTimer.Stop(); | ||
237 | m_CountdownTimer = null; | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | m_log.WarnFormat( | ||
242 | "[RESTART MODULE]: Tried to set restart timer to {0} in {1}, which is not a valid interval", | ||
243 | intervalSeconds, m_Scene.Name); | ||
244 | } | ||
231 | } | 245 | } |
232 | 246 | ||
233 | private void OnTimer(object source, ElapsedEventArgs e) | 247 | private void OnTimer(object source, ElapsedEventArgs e) |
@@ -332,4 +346,4 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
332 | } | 346 | } |
333 | } | 347 | } |
334 | } | 348 | } |
335 | } \ No newline at end of file | 349 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 56bdc63..f864392 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -3986,7 +3986,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3986 | 3986 | ||
3987 | try | 3987 | try |
3988 | { | 3988 | { |
3989 | if (!AuthorizeUser(acd, SeeIntoRegion, out reason)) | 3989 | if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason)) |
3990 | { | 3990 | { |
3991 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); | 3991 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3992 | return false; | 3992 | return false; |
@@ -4596,10 +4596,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
4596 | 4596 | ||
4597 | // Check that the auth_token is valid | 4597 | // Check that the auth_token is valid |
4598 | AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID); | 4598 | AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID); |
4599 | if (acd != null && acd.SessionID.ToString() == auth_token) | 4599 | |
4600 | if (acd == null) | ||
4601 | { | ||
4602 | m_log.DebugFormat( | ||
4603 | "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.", | ||
4604 | agentID, Name); | ||
4605 | |||
4606 | return false; | ||
4607 | } | ||
4608 | |||
4609 | if (acd.SessionID.ToString() == auth_token) | ||
4610 | { | ||
4600 | return IncomingCloseAgent(agentID, force); | 4611 | return IncomingCloseAgent(agentID, force); |
4612 | } | ||
4601 | else | 4613 | else |
4602 | m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token); | 4614 | { |
4615 | m_log.WarnFormat( | ||
4616 | "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}", | ||
4617 | agentID, auth_token, Name); | ||
4618 | } | ||
4619 | |||
4603 | return false; | 4620 | return false; |
4604 | } | 4621 | } |
4605 | 4622 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e599e90..b0f8991 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -631,40 +631,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
631 | protected internal ScenePresence CreateAndAddChildScenePresence( | 631 | protected internal ScenePresence CreateAndAddChildScenePresence( |
632 | IClientAPI client, AvatarAppearance appearance, PresenceType type) | 632 | IClientAPI client, AvatarAppearance appearance, PresenceType type) |
633 | { | 633 | { |
634 | ScenePresence newAvatar = null; | ||
635 | |||
636 | // ScenePresence always defaults to child agent | 634 | // ScenePresence always defaults to child agent |
637 | newAvatar = new ScenePresence(client, m_parentScene, appearance, type); | 635 | ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type); |
638 | |||
639 | AddScenePresence(newAvatar); | ||
640 | |||
641 | return newAvatar; | ||
642 | } | ||
643 | |||
644 | /// <summary> | ||
645 | /// Add a presence to the scene | ||
646 | /// </summary> | ||
647 | /// <param name="presence"></param> | ||
648 | protected internal void AddScenePresence(ScenePresence presence) | ||
649 | { | ||
650 | // Always a child when added to the scene | ||
651 | bool child = presence.IsChildAgent; | ||
652 | |||
653 | if (child) | ||
654 | { | ||
655 | m_numChildAgents++; | ||
656 | } | ||
657 | else | ||
658 | { | ||
659 | m_numRootAgents++; | ||
660 | presence.AddToPhysicalScene(false); | ||
661 | } | ||
662 | 636 | ||
663 | Entities[presence.UUID] = presence; | 637 | Entities[presence.UUID] = presence; |
664 | 638 | ||
665 | m_scenePresencesLock.EnterWriteLock(); | 639 | m_scenePresencesLock.EnterWriteLock(); |
666 | try | 640 | try |
667 | { | 641 | { |
642 | m_numChildAgents++; | ||
643 | |||
668 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | 644 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
669 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 645 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
670 | 646 | ||
@@ -675,7 +651,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
675 | } | 651 | } |
676 | else | 652 | else |
677 | { | 653 | { |
678 | // Remember the old presene reference from the dictionary | 654 | // Remember the old presence reference from the dictionary |
679 | ScenePresence oldref = newmap[presence.UUID]; | 655 | ScenePresence oldref = newmap[presence.UUID]; |
680 | // Replace the presence reference in the dictionary with the new value | 656 | // Replace the presence reference in the dictionary with the new value |
681 | newmap[presence.UUID] = presence; | 657 | newmap[presence.UUID] = presence; |
@@ -691,6 +667,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
691 | { | 667 | { |
692 | m_scenePresencesLock.ExitWriteLock(); | 668 | m_scenePresencesLock.ExitWriteLock(); |
693 | } | 669 | } |
670 | |||
671 | return presence; | ||
694 | } | 672 | } |
695 | 673 | ||
696 | /// <summary> | 674 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 59a453a..cf03d7c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -4522,7 +4522,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4522 | // For now, we use the NINJA naming scheme for identifying joints. | 4522 | // For now, we use the NINJA naming scheme for identifying joints. |
4523 | // In the future, we can support other joint specification schemes such as a | 4523 | // In the future, we can support other joint specification schemes such as a |
4524 | // custom checkbox in the viewer GUI. | 4524 | // custom checkbox in the viewer GUI. |
4525 | if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) | 4525 | if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) |
4526 | { | 4526 | { |
4527 | return IsHingeJoint() || IsBallJoint(); | 4527 | return IsHingeJoint() || IsBallJoint(); |
4528 | } | 4528 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3f4979e..88ecda2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -2707,6 +2707,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2707 | 2707 | ||
2708 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) | 2708 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) |
2709 | { | 2709 | { |
2710 | if (IsChildAgent) | ||
2711 | return; | ||
2712 | |||
2710 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 2713 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
2711 | 2714 | ||
2712 | if (part != null) | 2715 | if (part != null) |
@@ -2793,6 +2796,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2793 | 2796 | ||
2794 | public void HandleAgentSitOnGround() | 2797 | public void HandleAgentSitOnGround() |
2795 | { | 2798 | { |
2799 | if (IsChildAgent) | ||
2800 | return; | ||
2801 | |||
2796 | // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. | 2802 | // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. |
2797 | m_AngularVelocity = Vector3.Zero; | 2803 | m_AngularVelocity = Vector3.Zero; |
2798 | Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); | 2804 | Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); |
@@ -3451,11 +3457,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3451 | } | 3457 | } |
3452 | } | 3458 | } |
3453 | 3459 | ||
3454 | public void RestoreInCurrentScene() | ||
3455 | { | ||
3456 | AddToPhysicalScene(false); // not exactly false | ||
3457 | } | ||
3458 | |||
3459 | public void Reset() | 3460 | public void Reset() |
3460 | { | 3461 | { |
3461 | // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); | 3462 | // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); |
diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs new file mode 100644 index 0000000..5a6b284 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs | |||
@@ -0,0 +1,220 @@ | |||
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.Reflection; | ||
32 | using System.Text; | ||
33 | using System.Text.RegularExpressions; | ||
34 | using log4net; | ||
35 | using Mono.Addins; | ||
36 | using NDesk.Options; | ||
37 | using Nini.Config; | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Framework.Console; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | |||
44 | namespace OpenSim.Region.OptionalModules.Avatar.SitStand | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// A module that just holds commands for changing avatar sitting and standing states. | ||
48 | /// </summary> | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")] | ||
50 | public class SitStandCommandModule : INonSharedRegionModule | ||
51 | { | ||
52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | private Scene m_scene; | ||
55 | |||
56 | public string Name { get { return "SitStand Command Module"; } } | ||
57 | |||
58 | public Type ReplaceableInterface { get { return null; } } | ||
59 | |||
60 | public void Initialise(IConfigSource source) | ||
61 | { | ||
62 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE"); | ||
63 | } | ||
64 | |||
65 | public void PostInitialise() | ||
66 | { | ||
67 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE"); | ||
68 | } | ||
69 | |||
70 | public void Close() | ||
71 | { | ||
72 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE"); | ||
73 | } | ||
74 | |||
75 | public void AddRegion(Scene scene) | ||
76 | { | ||
77 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
78 | } | ||
79 | |||
80 | public void RemoveRegion(Scene scene) | ||
81 | { | ||
82 | // m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
83 | } | ||
84 | |||
85 | public void RegionLoaded(Scene scene) | ||
86 | { | ||
87 | // m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
88 | |||
89 | m_scene = scene; | ||
90 | |||
91 | scene.AddCommand( | ||
92 | "Users", this, "sit user name", | ||
93 | "sit user name [--regex] <first-name> <last-name>", | ||
94 | "Sit the named user on an unoccupied object with a sit target.", | ||
95 | "If there are no such objects then nothing happens.\n" | ||
96 | + "If --regex is specified then the names are treated as regular expressions.", | ||
97 | HandleSitUserNameCommand); | ||
98 | |||
99 | scene.AddCommand( | ||
100 | "Users", this, "stand user name", | ||
101 | "stand user name [--regex] <first-name> <last-name>", | ||
102 | "Stand the named user.", | ||
103 | "If --regex is specified then the names are treated as regular expressions.", | ||
104 | HandleStandUserNameCommand); | ||
105 | } | ||
106 | |||
107 | private void HandleSitUserNameCommand(string module, string[] cmd) | ||
108 | { | ||
109 | if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) | ||
110 | return; | ||
111 | |||
112 | if (cmd.Length < 5) | ||
113 | { | ||
114 | MainConsole.Instance.Output("Usage: sit user name [--regex] <first-name> <last-name>"); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | List<ScenePresence> scenePresences = GetScenePresences(cmd); | ||
119 | |||
120 | foreach (ScenePresence sp in scenePresences) | ||
121 | { | ||
122 | if (sp.SitGround || sp.IsSatOnObject) | ||
123 | continue; | ||
124 | |||
125 | SceneObjectPart sitPart = null; | ||
126 | List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups(); | ||
127 | |||
128 | foreach (SceneObjectGroup sceneObject in sceneObjects) | ||
129 | { | ||
130 | if (sceneObject.IsAttachment) | ||
131 | continue; | ||
132 | |||
133 | foreach (SceneObjectPart part in sceneObject.Parts) | ||
134 | { | ||
135 | if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) | ||
136 | { | ||
137 | sitPart = part; | ||
138 | break; | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
143 | if (sitPart != null) | ||
144 | { | ||
145 | MainConsole.Instance.OutputFormat( | ||
146 | "Sitting {0} on {1} {2} in {3}", | ||
147 | sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name); | ||
148 | |||
149 | sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero); | ||
150 | sp.HandleAgentSit(sp.ControllingClient, sp.UUID); | ||
151 | } | ||
152 | else | ||
153 | { | ||
154 | MainConsole.Instance.OutputFormat( | ||
155 | "Could not find any unoccupied set seat on which to sit {0} in {1}. Aborting", | ||
156 | sp.Name, m_scene.Name); | ||
157 | |||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | private void HandleStandUserNameCommand(string module, string[] cmd) | ||
164 | { | ||
165 | if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) | ||
166 | return; | ||
167 | |||
168 | if (cmd.Length < 5) | ||
169 | { | ||
170 | MainConsole.Instance.Output("Usage: stand user name [--regex] <first-name> <last-name>"); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | List<ScenePresence> scenePresences = GetScenePresences(cmd); | ||
175 | |||
176 | foreach (ScenePresence sp in scenePresences) | ||
177 | { | ||
178 | if (sp.SitGround || sp.IsSatOnObject) | ||
179 | { | ||
180 | MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name); | ||
181 | sp.StandUp(); | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | private List<ScenePresence> GetScenePresences(string[] cmdParams) | ||
187 | { | ||
188 | bool useRegex = false; | ||
189 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | ||
190 | |||
191 | List<string> mainParams = options.Parse(cmdParams); | ||
192 | |||
193 | string firstName = mainParams[3]; | ||
194 | string lastName = mainParams[4]; | ||
195 | |||
196 | List<ScenePresence> scenePresencesMatched = new List<ScenePresence>(); | ||
197 | |||
198 | if (useRegex) | ||
199 | { | ||
200 | Regex nameRegex = new Regex(string.Format("{0} {1}", firstName, lastName)); | ||
201 | List<ScenePresence> scenePresences = m_scene.GetScenePresences(); | ||
202 | |||
203 | foreach (ScenePresence sp in scenePresences) | ||
204 | { | ||
205 | if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name)) | ||
206 | scenePresencesMatched.Add(sp); | ||
207 | } | ||
208 | } | ||
209 | else | ||
210 | { | ||
211 | ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); | ||
212 | |||
213 | if (sp != null && !sp.IsChildAgent) | ||
214 | scenePresencesMatched.Add(sp); | ||
215 | } | ||
216 | |||
217 | return scenePresencesMatched; | ||
218 | } | ||
219 | } | ||
220 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 6db5f5e..2a820be 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | |||
@@ -1221,6 +1221,50 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1221 | //BSParam.TerrainImplementation = 0; | 1221 | //BSParam.TerrainImplementation = 0; |
1222 | world.SetGravity(new IndexedVector3(0,0,p.gravity)); | 1222 | world.SetGravity(new IndexedVector3(0,0,p.gravity)); |
1223 | 1223 | ||
1224 | // Turn off Pooling since globals and pooling are bad for threading. | ||
1225 | BulletGlobals.VoronoiSimplexSolverPool.SetPoolingEnabled(false); | ||
1226 | BulletGlobals.SubSimplexConvexCastPool.SetPoolingEnabled(false); | ||
1227 | BulletGlobals.ManifoldPointPool.SetPoolingEnabled(false); | ||
1228 | BulletGlobals.CastResultPool.SetPoolingEnabled(false); | ||
1229 | BulletGlobals.SphereShapePool.SetPoolingEnabled(false); | ||
1230 | BulletGlobals.DbvtNodePool.SetPoolingEnabled(false); | ||
1231 | BulletGlobals.SingleRayCallbackPool.SetPoolingEnabled(false); | ||
1232 | BulletGlobals.SubSimplexClosestResultPool.SetPoolingEnabled(false); | ||
1233 | BulletGlobals.GjkPairDetectorPool.SetPoolingEnabled(false); | ||
1234 | BulletGlobals.DbvtTreeColliderPool.SetPoolingEnabled(false); | ||
1235 | BulletGlobals.SingleSweepCallbackPool.SetPoolingEnabled(false); | ||
1236 | BulletGlobals.BroadphaseRayTesterPool.SetPoolingEnabled(false); | ||
1237 | BulletGlobals.ClosestNotMeConvexResultCallbackPool.SetPoolingEnabled(false); | ||
1238 | BulletGlobals.GjkEpaPenetrationDepthSolverPool.SetPoolingEnabled(false); | ||
1239 | BulletGlobals.ContinuousConvexCollisionPool.SetPoolingEnabled(false); | ||
1240 | BulletGlobals.DbvtStackDataBlockPool.SetPoolingEnabled(false); | ||
1241 | |||
1242 | BulletGlobals.BoxBoxCollisionAlgorithmPool.SetPoolingEnabled(false); | ||
1243 | BulletGlobals.CompoundCollisionAlgorithmPool.SetPoolingEnabled(false); | ||
1244 | BulletGlobals.ConvexConcaveCollisionAlgorithmPool.SetPoolingEnabled(false); | ||
1245 | BulletGlobals.ConvexConvexAlgorithmPool.SetPoolingEnabled(false); | ||
1246 | BulletGlobals.ConvexPlaneAlgorithmPool.SetPoolingEnabled(false); | ||
1247 | BulletGlobals.SphereBoxCollisionAlgorithmPool.SetPoolingEnabled(false); | ||
1248 | BulletGlobals.SphereSphereCollisionAlgorithmPool.SetPoolingEnabled(false); | ||
1249 | BulletGlobals.SphereTriangleCollisionAlgorithmPool.SetPoolingEnabled(false); | ||
1250 | BulletGlobals.GImpactCollisionAlgorithmPool.SetPoolingEnabled(false); | ||
1251 | BulletGlobals.GjkEpaSolver2MinkowskiDiffPool.SetPoolingEnabled(false); | ||
1252 | BulletGlobals.PersistentManifoldPool.SetPoolingEnabled(false); | ||
1253 | BulletGlobals.ManifoldResultPool.SetPoolingEnabled(false); | ||
1254 | BulletGlobals.GJKPool.SetPoolingEnabled(false); | ||
1255 | BulletGlobals.GIM_ShapeRetrieverPool.SetPoolingEnabled(false); | ||
1256 | BulletGlobals.TriangleShapePool.SetPoolingEnabled(false); | ||
1257 | BulletGlobals.SphereTriangleDetectorPool.SetPoolingEnabled(false); | ||
1258 | BulletGlobals.CompoundLeafCallbackPool.SetPoolingEnabled(false); | ||
1259 | BulletGlobals.GjkConvexCastPool.SetPoolingEnabled(false); | ||
1260 | BulletGlobals.LocalTriangleSphereCastCallbackPool.SetPoolingEnabled(false); | ||
1261 | BulletGlobals.BridgeTriangleRaycastCallbackPool.SetPoolingEnabled(false); | ||
1262 | BulletGlobals.BridgeTriangleConcaveRaycastCallbackPool.SetPoolingEnabled(false); | ||
1263 | BulletGlobals.BridgeTriangleConvexcastCallbackPool.SetPoolingEnabled(false); | ||
1264 | BulletGlobals.MyNodeOverlapCallbackPool.SetPoolingEnabled(false); | ||
1265 | BulletGlobals.ClosestRayResultCallbackPool.SetPoolingEnabled(false); | ||
1266 | BulletGlobals.DebugDrawcallbackPool.SetPoolingEnabled(false); | ||
1267 | |||
1224 | return world; | 1268 | return world; |
1225 | } | 1269 | } |
1226 | //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL | 1270 | //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL |
@@ -1914,7 +1958,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1914 | heightMap, scaleFactor, | 1958 | heightMap, scaleFactor, |
1915 | minHeight, maxHeight, upAxis, | 1959 | minHeight, maxHeight, upAxis, |
1916 | false); | 1960 | false); |
1917 | terrainShape.SetMargin(collisionMargin + 0.5f); | 1961 | terrainShape.SetMargin(collisionMargin); |
1918 | terrainShape.SetUseDiamondSubdivision(true); | 1962 | terrainShape.SetUseDiamondSubdivision(true); |
1919 | terrainShape.SetUserPointer(id); | 1963 | terrainShape.SetUserPointer(id); |
1920 | return new BulletShapeXNA(terrainShape, BSPhysicsShapeType.SHAPE_TERRAIN); | 1964 | return new BulletShapeXNA(terrainShape, BSPhysicsShapeType.SHAPE_TERRAIN); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 88d50b4..c92c9b9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -946,7 +946,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
946 | 946 | ||
947 | private void ProcessRegularTaints() | 947 | private void ProcessRegularTaints() |
948 | { | 948 | { |
949 | if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process | 949 | if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process |
950 | { | 950 | { |
951 | // swizzle a new list into the list location so we can process what's there | 951 | // swizzle a new list into the list location so we can process what's there |
952 | List<TaintCallbackEntry> oldList; | 952 | List<TaintCallbackEntry> oldList; |
@@ -989,7 +989,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
989 | // Taints that happen after the normal taint processing but before the simulation step. | 989 | // Taints that happen after the normal taint processing but before the simulation step. |
990 | private void ProcessPostTaintTaints() | 990 | private void ProcessPostTaintTaints() |
991 | { | 991 | { |
992 | if (_postTaintOperations.Count > 0) | 992 | if (m_initialized && _postTaintOperations.Count > 0) |
993 | { | 993 | { |
994 | Dictionary<string, TaintCallbackEntry> oldList; | 994 | Dictionary<string, TaintCallbackEntry> oldList; |
995 | lock (_taintLock) | 995 | lock (_taintLock) |
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index daebf8b..a1485c8 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs | |||
@@ -86,7 +86,7 @@ namespace OpenSim.Services.GridService | |||
86 | { | 86 | { |
87 | MainConsole.Instance.Commands.AddCommand("Regions", true, | 87 | MainConsole.Instance.Commands.AddCommand("Regions", true, |
88 | "deregister region id", | 88 | "deregister region id", |
89 | "deregister region id <Region UUID>", | 89 | "deregister region id <region-id>+", |
90 | "Deregister a region manually.", | 90 | "Deregister a region manually.", |
91 | String.Empty, | 91 | String.Empty, |
92 | HandleDeregisterRegion); | 92 | HandleDeregisterRegion); |
@@ -526,40 +526,41 @@ namespace OpenSim.Services.GridService | |||
526 | 526 | ||
527 | private void HandleDeregisterRegion(string module, string[] cmd) | 527 | private void HandleDeregisterRegion(string module, string[] cmd) |
528 | { | 528 | { |
529 | if (cmd.Length != 4) | 529 | if (cmd.Length < 4) |
530 | { | 530 | { |
531 | MainConsole.Instance.Output("Syntax: degregister region id <Region UUID>"); | 531 | MainConsole.Instance.Output("Usage: degregister region id <region-id>+"); |
532 | return; | 532 | return; |
533 | } | 533 | } |
534 | 534 | ||
535 | string rawRegionUuid = cmd[3]; | 535 | for (int i = 3; i < cmd.Length; i++) |
536 | UUID regionUuid; | ||
537 | |||
538 | if (!UUID.TryParse(rawRegionUuid, out regionUuid)) | ||
539 | { | 536 | { |
540 | MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid); | 537 | string rawRegionUuid = cmd[i]; |
541 | return; | 538 | UUID regionUuid; |
542 | } | ||
543 | 539 | ||
544 | GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid); | 540 | if (!UUID.TryParse(rawRegionUuid, out regionUuid)) |
541 | { | ||
542 | MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid); | ||
543 | return; | ||
544 | } | ||
545 | 545 | ||
546 | if (region == null) | 546 | GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid); |
547 | { | ||
548 | MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid); | ||
549 | return; | ||
550 | } | ||
551 | 547 | ||
552 | if (DeregisterRegion(regionUuid)) | 548 | if (region == null) |
553 | { | 549 | { |
554 | MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid); | 550 | MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid); |
555 | } | 551 | return; |
556 | else | 552 | } |
557 | { | ||
558 | // I don't think this can ever occur if we know that the region exists. | ||
559 | MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid); | ||
560 | } | ||
561 | 553 | ||
562 | return; | 554 | if (DeregisterRegion(regionUuid)) |
555 | { | ||
556 | MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid); | ||
557 | } | ||
558 | else | ||
559 | { | ||
560 | // I don't think this can ever occur if we know that the region exists. | ||
561 | MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid); | ||
562 | } | ||
563 | } | ||
563 | } | 564 | } |
564 | 565 | ||
565 | private void HandleShowRegions(string module, string[] cmd) | 566 | private void HandleShowRegions(string module, string[] cmd) |
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 0a3e70b..e10c4cb 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs | |||
@@ -326,7 +326,7 @@ namespace OpenSim.Services.HypergridService | |||
326 | return false; | 326 | return false; |
327 | } | 327 | } |
328 | 328 | ||
329 | m_log.DebugFormat("[GATEKEEPER SERVICE]: User is OK"); | 329 | m_log.DebugFormat("[GATEKEEPER SERVICE]: User {0} is ok", aCircuit.Name); |
330 | 330 | ||
331 | bool isFirstLogin = false; | 331 | bool isFirstLogin = false; |
332 | // | 332 | // |
@@ -345,7 +345,8 @@ namespace OpenSim.Services.HypergridService | |||
345 | aCircuit.firstname, aCircuit.lastname); | 345 | aCircuit.firstname, aCircuit.lastname); |
346 | return false; | 346 | return false; |
347 | } | 347 | } |
348 | m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence ok"); | 348 | |
349 | m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name); | ||
349 | 350 | ||
350 | // Also login foreigners with GridUser service | 351 | // Also login foreigners with GridUser service |
351 | if (m_GridUserService != null && account == null) | 352 | if (m_GridUserService != null && account == null) |
@@ -376,7 +377,9 @@ namespace OpenSim.Services.HypergridService | |||
376 | reason = "Destination region not found"; | 377 | reason = "Destination region not found"; |
377 | return false; | 378 | return false; |
378 | } | 379 | } |
379 | m_log.DebugFormat("[GATEKEEPER SERVICE]: destination ok: {0}", destination.RegionName); | 380 | |
381 | m_log.DebugFormat( | ||
382 | "[GATEKEEPER SERVICE]: Destination {0} is ok for {1}", destination.RegionName, aCircuit.Name); | ||
380 | 383 | ||
381 | // | 384 | // |
382 | // Adjust the visible name | 385 | // Adjust the visible name |
@@ -410,7 +413,8 @@ namespace OpenSim.Services.HypergridService | |||
410 | // Preserve our TeleportFlags we have gathered so-far | 413 | // Preserve our TeleportFlags we have gathered so-far |
411 | loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags; | 414 | loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags; |
412 | 415 | ||
413 | m_log.DebugFormat("[GATEKEEPER SERVICE]: launching agent {0}", loginFlag); | 416 | m_log.DebugFormat("[GATEKEEPER SERVICE]: Launching {0} {1}", aCircuit.Name, loginFlag); |
417 | |||
414 | return m_SimulationService.CreateAgent(destination, aCircuit, (uint)loginFlag, out reason); | 418 | return m_SimulationService.CreateAgent(destination, aCircuit, (uint)loginFlag, out reason); |
415 | } | 419 | } |
416 | 420 | ||
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 3f4c958..cecbe9e 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs | |||
@@ -137,7 +137,10 @@ namespace OpenSim.Services.Interfaces | |||
137 | if ( m_serverURI != string.Empty ) { | 137 | if ( m_serverURI != string.Empty ) { |
138 | return m_serverURI; | 138 | return m_serverURI; |
139 | } else { | 139 | } else { |
140 | return "http://" + m_externalHostName + ":" + m_httpPort + "/"; | 140 | if (m_httpPort == 0) |
141 | return "http://" + m_externalHostName + "/"; | ||
142 | else | ||
143 | return "http://" + m_externalHostName + ":" + m_httpPort + "/"; | ||
141 | } | 144 | } |
142 | } | 145 | } |
143 | set { | 146 | set { |
diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 32bf32b..d418288 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs | |||
@@ -97,6 +97,28 @@ namespace pCampBot | |||
97 | /// </summary> | 97 | /// </summary> |
98 | public ConnectionState ConnectionState { get; private set; } | 98 | public ConnectionState ConnectionState { get; private set; } |
99 | 99 | ||
100 | public List<Simulator> Simulators | ||
101 | { | ||
102 | get | ||
103 | { | ||
104 | lock (Client.Network.Simulators) | ||
105 | return new List<Simulator>(Client.Network.Simulators); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /// <summary> | ||
110 | /// The number of connections that this bot has to different simulators. | ||
111 | /// </summary> | ||
112 | /// <value>Includes both root and child connections.</value> | ||
113 | public int SimulatorsCount | ||
114 | { | ||
115 | get | ||
116 | { | ||
117 | lock (Client.Network.Simulators) | ||
118 | return Client.Network.Simulators.Count; | ||
119 | } | ||
120 | } | ||
121 | |||
100 | public string FirstName { get; private set; } | 122 | public string FirstName { get; private set; } |
101 | public string LastName { get; private set; } | 123 | public string LastName { get; private set; } |
102 | public string Name { get; private set; } | 124 | public string Name { get; private set; } |
@@ -144,8 +166,6 @@ namespace pCampBot | |||
144 | ConnectionState = ConnectionState.Disconnected; | 166 | ConnectionState = ConnectionState.Disconnected; |
145 | 167 | ||
146 | behaviours.ForEach(b => b.Initialize(this)); | 168 | behaviours.ForEach(b => b.Initialize(this)); |
147 | |||
148 | Client = new GridClient(); | ||
149 | 169 | ||
150 | Random = new Random(Environment.TickCount);// We do stuff randomly here | 170 | Random = new Random(Environment.TickCount);// We do stuff randomly here |
151 | FirstName = firstName; | 171 | FirstName = firstName; |
@@ -157,6 +177,59 @@ namespace pCampBot | |||
157 | 177 | ||
158 | Manager = bm; | 178 | Manager = bm; |
159 | Behaviours = behaviours; | 179 | Behaviours = behaviours; |
180 | |||
181 | // Only calling for use as a template. | ||
182 | CreateLibOmvClient(); | ||
183 | } | ||
184 | |||
185 | private void CreateLibOmvClient() | ||
186 | { | ||
187 | GridClient newClient = new GridClient(); | ||
188 | |||
189 | if (Client != null) | ||
190 | { | ||
191 | newClient.Settings.LOGIN_SERVER = Client.Settings.LOGIN_SERVER; | ||
192 | newClient.Settings.ALWAYS_DECODE_OBJECTS = Client.Settings.ALWAYS_DECODE_OBJECTS; | ||
193 | newClient.Settings.AVATAR_TRACKING = Client.Settings.AVATAR_TRACKING; | ||
194 | newClient.Settings.OBJECT_TRACKING = Client.Settings.OBJECT_TRACKING; | ||
195 | newClient.Settings.SEND_AGENT_THROTTLE = Client.Settings.SEND_AGENT_THROTTLE; | ||
196 | newClient.Settings.SEND_AGENT_UPDATES = Client.Settings.SEND_AGENT_UPDATES; | ||
197 | newClient.Settings.SEND_PINGS = Client.Settings.SEND_PINGS; | ||
198 | newClient.Settings.STORE_LAND_PATCHES = Client.Settings.STORE_LAND_PATCHES; | ||
199 | newClient.Settings.USE_ASSET_CACHE = Client.Settings.USE_ASSET_CACHE; | ||
200 | newClient.Settings.MULTIPLE_SIMS = Client.Settings.MULTIPLE_SIMS; | ||
201 | newClient.Throttle.Asset = Client.Throttle.Asset; | ||
202 | newClient.Throttle.Land = Client.Throttle.Land; | ||
203 | newClient.Throttle.Task = Client.Throttle.Task; | ||
204 | newClient.Throttle.Texture = Client.Throttle.Texture; | ||
205 | newClient.Throttle.Wind = Client.Throttle.Wind; | ||
206 | newClient.Throttle.Total = Client.Throttle.Total; | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | newClient.Settings.LOGIN_SERVER = LoginUri; | ||
211 | newClient.Settings.ALWAYS_DECODE_OBJECTS = false; | ||
212 | newClient.Settings.AVATAR_TRACKING = false; | ||
213 | newClient.Settings.OBJECT_TRACKING = false; | ||
214 | newClient.Settings.SEND_AGENT_THROTTLE = true; | ||
215 | newClient.Settings.SEND_PINGS = true; | ||
216 | newClient.Settings.STORE_LAND_PATCHES = false; | ||
217 | newClient.Settings.USE_ASSET_CACHE = false; | ||
218 | newClient.Settings.MULTIPLE_SIMS = true; | ||
219 | newClient.Throttle.Asset = 100000; | ||
220 | newClient.Throttle.Land = 100000; | ||
221 | newClient.Throttle.Task = 100000; | ||
222 | newClient.Throttle.Texture = 100000; | ||
223 | newClient.Throttle.Wind = 100000; | ||
224 | newClient.Throttle.Total = 400000; | ||
225 | } | ||
226 | |||
227 | newClient.Network.LoginProgress += this.Network_LoginProgress; | ||
228 | newClient.Network.SimConnected += this.Network_SimConnected; | ||
229 | newClient.Network.Disconnected += this.Network_OnDisconnected; | ||
230 | newClient.Objects.ObjectUpdate += Objects_NewPrim; | ||
231 | |||
232 | Client = newClient; | ||
160 | } | 233 | } |
161 | 234 | ||
162 | //We do our actions here. This is where one would | 235 | //We do our actions here. This is where one would |
@@ -179,7 +252,7 @@ namespace pCampBot | |||
179 | /// <summary> | 252 | /// <summary> |
180 | /// Tells LibSecondLife to logout and disconnect. Raises the disconnect events once it finishes. | 253 | /// Tells LibSecondLife to logout and disconnect. Raises the disconnect events once it finishes. |
181 | /// </summary> | 254 | /// </summary> |
182 | public void shutdown() | 255 | public void Disconnect() |
183 | { | 256 | { |
184 | ConnectionState = ConnectionState.Disconnecting; | 257 | ConnectionState = ConnectionState.Disconnecting; |
185 | 258 | ||
@@ -189,34 +262,27 @@ namespace pCampBot | |||
189 | Client.Network.Logout(); | 262 | Client.Network.Logout(); |
190 | } | 263 | } |
191 | 264 | ||
265 | public void Connect() | ||
266 | { | ||
267 | Thread connectThread = new Thread(ConnectInternal); | ||
268 | connectThread.Name = Name; | ||
269 | connectThread.IsBackground = true; | ||
270 | |||
271 | connectThread.Start(); | ||
272 | } | ||
273 | |||
192 | /// <summary> | 274 | /// <summary> |
193 | /// This is the bot startup loop. | 275 | /// This is the bot startup loop. |
194 | /// </summary> | 276 | /// </summary> |
195 | public void startup() | 277 | private void ConnectInternal() |
196 | { | 278 | { |
197 | Client.Settings.LOGIN_SERVER = LoginUri; | ||
198 | Client.Settings.ALWAYS_DECODE_OBJECTS = false; | ||
199 | Client.Settings.AVATAR_TRACKING = false; | ||
200 | Client.Settings.OBJECT_TRACKING = false; | ||
201 | Client.Settings.SEND_AGENT_THROTTLE = true; | ||
202 | Client.Settings.SEND_AGENT_UPDATES = false; | ||
203 | Client.Settings.SEND_PINGS = true; | ||
204 | Client.Settings.STORE_LAND_PATCHES = false; | ||
205 | Client.Settings.USE_ASSET_CACHE = false; | ||
206 | Client.Settings.MULTIPLE_SIMS = true; | ||
207 | Client.Throttle.Asset = 100000; | ||
208 | Client.Throttle.Land = 100000; | ||
209 | Client.Throttle.Task = 100000; | ||
210 | Client.Throttle.Texture = 100000; | ||
211 | Client.Throttle.Wind = 100000; | ||
212 | Client.Throttle.Total = 400000; | ||
213 | Client.Network.LoginProgress += this.Network_LoginProgress; | ||
214 | Client.Network.SimConnected += this.Network_SimConnected; | ||
215 | Client.Network.Disconnected += this.Network_OnDisconnected; | ||
216 | Client.Objects.ObjectUpdate += Objects_NewPrim; | ||
217 | |||
218 | ConnectionState = ConnectionState.Connecting; | 279 | ConnectionState = ConnectionState.Connecting; |
219 | 280 | ||
281 | // Current create a new client on each connect. libomv doesn't seem to process new sim | ||
282 | // information (e.g. EstablishAgentCommunication events) if connecting after a disceonnect with the same | ||
283 | // client | ||
284 | CreateLibOmvClient(); | ||
285 | |||
220 | if (Client.Network.Login(FirstName, LastName, Password, "pCampBot", StartLocation, "Your name")) | 286 | if (Client.Network.Login(FirstName, LastName, Password, "pCampBot", StartLocation, "Your name")) |
221 | { | 287 | { |
222 | ConnectionState = ConnectionState.Connected; | 288 | ConnectionState = ConnectionState.Connected; |
@@ -261,6 +327,30 @@ namespace pCampBot | |||
261 | } | 327 | } |
262 | } | 328 | } |
263 | 329 | ||
330 | /// <summary> | ||
331 | /// Sit this bot on the ground. | ||
332 | /// </summary> | ||
333 | public void SitOnGround() | ||
334 | { | ||
335 | if (ConnectionState == ConnectionState.Connected) | ||
336 | Client.Self.SitOnGround(); | ||
337 | } | ||
338 | |||
339 | /// <summary> | ||
340 | /// Stand this bot | ||
341 | /// </summary> | ||
342 | public void Stand() | ||
343 | { | ||
344 | if (ConnectionState == ConnectionState.Connected) | ||
345 | { | ||
346 | // Unlike sit on ground, here libomv checks whether we have SEND_AGENT_UPDATES enabled. | ||
347 | bool prevUpdatesSetting = Client.Settings.SEND_AGENT_UPDATES; | ||
348 | Client.Settings.SEND_AGENT_UPDATES = true; | ||
349 | Client.Self.Stand(); | ||
350 | Client.Settings.SEND_AGENT_UPDATES = prevUpdatesSetting; | ||
351 | } | ||
352 | } | ||
353 | |||
264 | public void SaveDefaultAppearance() | 354 | public void SaveDefaultAppearance() |
265 | { | 355 | { |
266 | saveDir = "MyAppearance/" + FirstName + "_" + LastName; | 356 | saveDir = "MyAppearance/" + FirstName + "_" + LastName; |
@@ -461,6 +551,8 @@ namespace pCampBot | |||
461 | // || args.Reason == NetworkManager.DisconnectType.NetworkTimeout) | 551 | // || args.Reason == NetworkManager.DisconnectType.NetworkTimeout) |
462 | // && OnDisconnected != null) | 552 | // && OnDisconnected != null) |
463 | 553 | ||
554 | |||
555 | |||
464 | if ( | 556 | if ( |
465 | (args.Reason == NetworkManager.DisconnectType.ClientInitiated | 557 | (args.Reason == NetworkManager.DisconnectType.ClientInitiated |
466 | || args.Reason == NetworkManager.DisconnectType.ServerInitiated | 558 | || args.Reason == NetworkManager.DisconnectType.ServerInitiated |
diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index dee02c3..5c3835b 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs | |||
@@ -52,9 +52,14 @@ namespace pCampBot | |||
52 | public const int DefaultLoginDelay = 5000; | 52 | public const int DefaultLoginDelay = 5000; |
53 | 53 | ||
54 | /// <summary> | 54 | /// <summary> |
55 | /// True if pCampbot is in the process of shutting down. | 55 | /// Is pCampbot in the process of connecting bots? |
56 | /// </summary> | 56 | /// </summary> |
57 | public bool ShuttingDown { get; private set; } | 57 | public bool ConnectingBots { get; private set; } |
58 | |||
59 | /// <summary> | ||
60 | /// Is pCampbot in the process of disconnecting bots? | ||
61 | /// </summary> | ||
62 | public bool DisconnectingBots { get; private set; } | ||
58 | 63 | ||
59 | /// <summary> | 64 | /// <summary> |
60 | /// Delay between logins of multiple bots. | 65 | /// Delay between logins of multiple bots. |
@@ -80,7 +85,7 @@ namespace pCampBot | |||
80 | /// <summary> | 85 | /// <summary> |
81 | /// Created bots, whether active or inactive. | 86 | /// Created bots, whether active or inactive. |
82 | /// </summary> | 87 | /// </summary> |
83 | protected List<Bot> m_lBot; | 88 | protected List<Bot> m_bots; |
84 | 89 | ||
85 | /// <summary> | 90 | /// <summary> |
86 | /// Random number generator. | 91 | /// Random number generator. |
@@ -98,6 +103,46 @@ namespace pCampBot | |||
98 | public Dictionary<ulong, GridRegion> RegionsKnown { get; private set; } | 103 | public Dictionary<ulong, GridRegion> RegionsKnown { get; private set; } |
99 | 104 | ||
100 | /// <summary> | 105 | /// <summary> |
106 | /// First name for bots | ||
107 | /// </summary> | ||
108 | private string m_firstName; | ||
109 | |||
110 | /// <summary> | ||
111 | /// Last name stem for bots | ||
112 | /// </summary> | ||
113 | private string m_lastNameStem; | ||
114 | |||
115 | /// <summary> | ||
116 | /// Password for bots | ||
117 | /// </summary> | ||
118 | private string m_password; | ||
119 | |||
120 | /// <summary> | ||
121 | /// Login URI for bots. | ||
122 | /// </summary> | ||
123 | private string m_loginUri; | ||
124 | |||
125 | /// <summary> | ||
126 | /// Start location for bots. | ||
127 | /// </summary> | ||
128 | private string m_startUri; | ||
129 | |||
130 | /// <summary> | ||
131 | /// Postfix bot number at which bot sequence starts. | ||
132 | /// </summary> | ||
133 | private int m_fromBotNumber; | ||
134 | |||
135 | /// <summary> | ||
136 | /// Wear setting for bots. | ||
137 | /// </summary> | ||
138 | private string m_wearSetting; | ||
139 | |||
140 | /// <summary> | ||
141 | /// Behaviour switches for bots. | ||
142 | /// </summary> | ||
143 | private HashSet<string> m_behaviourSwitches = new HashSet<string>(); | ||
144 | |||
145 | /// <summary> | ||
101 | /// 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 |
102 | /// </summary> | 147 | /// </summary> |
103 | public BotManager() | 148 | public BotManager() |
@@ -130,30 +175,47 @@ namespace pCampBot | |||
130 | } | 175 | } |
131 | } | 176 | } |
132 | 177 | ||
133 | m_console.Commands.AddCommand("bot", false, "shutdown", | 178 | m_console.Commands.AddCommand( |
134 | "shutdown", | 179 | "bot", false, "shutdown", "shutdown", "Shutdown bots and exit", HandleShutdown); |
135 | "Shutdown bots and exit", HandleShutdown); | 180 | |
181 | m_console.Commands.AddCommand( | ||
182 | "bot", false, "quit", "quit", "Shutdown bots and exit", HandleShutdown); | ||
136 | 183 | ||
137 | m_console.Commands.AddCommand("bot", false, "quit", | 184 | m_console.Commands.AddCommand( |
138 | "quit", | 185 | "bot", false, "connect", "connect [<n>]", "Connect bots", |
139 | "Shutdown bots and exit", | 186 | "If an <n> is given, then the first <n> disconnected bots by postfix number are connected.\n" |
140 | HandleShutdown); | 187 | + "If no <n> is given, then all currently disconnected bots are connected.", |
188 | HandleConnect); | ||
141 | 189 | ||
142 | m_console.Commands.AddCommand("bot", false, "show regions", | 190 | m_console.Commands.AddCommand( |
143 | "show regions", | 191 | "bot", false, "disconnect", "disconnect [<n>]", "Disconnect bots", |
144 | "Show regions known to bots", | 192 | "Disconnecting bots will interupt any bot connection process, including connection on startup.\n" |
145 | HandleShowRegions); | 193 | + "If an <n> is given, then the last <n> connected bots by postfix number are disconnected.\n" |
194 | + "If no <n> is given, then all currently connected bots are disconnected.", | ||
195 | HandleDisconnect); | ||
146 | 196 | ||
147 | m_console.Commands.AddCommand("bot", false, "show bots", | 197 | m_console.Commands.AddCommand( |
148 | "show bots", | 198 | "bot", false, "sit", "sit", "Sit all bots on the ground.", |
149 | "Shows the status of all bots", | 199 | HandleSit); |
150 | HandleShowStatus); | ||
151 | 200 | ||
152 | // m_console.Commands.AddCommand("bot", false, "add bots", | 201 | m_console.Commands.AddCommand( |
153 | // "add bots <number>", | 202 | "bot", false, "stand", "stand", "Stand all bots.", |
154 | // "Add more bots", HandleAddBots); | 203 | HandleStand); |
155 | 204 | ||
156 | m_lBot = new List<Bot>(); | 205 | m_console.Commands.AddCommand( |
206 | "bot", false, "set bots", "set bots <key> <value>", "Set a setting for all bots.", HandleSetBots); | ||
207 | |||
208 | m_console.Commands.AddCommand( | ||
209 | "bot", false, "show regions", "show regions", "Show regions known to bots", HandleShowRegions); | ||
210 | |||
211 | m_console.Commands.AddCommand( | ||
212 | "bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus); | ||
213 | |||
214 | m_console.Commands.AddCommand( | ||
215 | "bot", false, "show bot", "show bot <n>", | ||
216 | "Shows the detailed status and settings of a particular bot.", HandleShowBotStatus); | ||
217 | |||
218 | m_bots = new List<Bot>(); | ||
157 | } | 219 | } |
158 | 220 | ||
159 | /// <summary> | 221 | /// <summary> |
@@ -161,62 +223,102 @@ namespace pCampBot | |||
161 | /// </summary> | 223 | /// </summary> |
162 | /// <param name="botcount">How many bots to start up</param> | 224 | /// <param name="botcount">How many bots to start up</param> |
163 | /// <param name="cs">The configuration for the bots to use</param> | 225 | /// <param name="cs">The configuration for the bots to use</param> |
164 | public void dobotStartup(int botcount, IConfig startupConfig) | 226 | public void CreateBots(int botcount, IConfig startupConfig) |
165 | { | 227 | { |
166 | string firstName = startupConfig.GetString("firstname"); | 228 | m_firstName = startupConfig.GetString("firstname"); |
167 | string lastNameStem = startupConfig.GetString("lastname"); | 229 | m_lastNameStem = startupConfig.GetString("lastname"); |
168 | string password = startupConfig.GetString("password"); | 230 | m_password = startupConfig.GetString("password"); |
169 | string loginUri = startupConfig.GetString("loginuri"); | 231 | m_loginUri = startupConfig.GetString("loginuri"); |
170 | string startLocation = startupConfig.GetString("start", "last"); | 232 | m_fromBotNumber = startupConfig.GetInt("from", 0); |
171 | int fromBotNumber = startupConfig.GetInt("from", 0); | 233 | m_wearSetting = startupConfig.GetString("wear", "no"); |
172 | string wearSetting = startupConfig.GetString("wear", "no"); | ||
173 | 234 | ||
174 | string startUri = ParseInputStartLocationToUri(startLocation); | 235 | m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last")); |
175 | 236 | ||
176 | HashSet<string> behaviourSwitches = new HashSet<string>(); | ||
177 | Array.ForEach<string>( | 237 | Array.ForEach<string>( |
178 | startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); | 238 | startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b)); |
239 | |||
240 | for (int i = 0; i < botcount; i++) | ||
241 | { | ||
242 | lock (m_bots) | ||
243 | { | ||
244 | string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); | ||
245 | |||
246 | // We must give each bot its own list of instantiated behaviours since they store state. | ||
247 | List<IBehaviour> behaviours = new List<IBehaviour>(); | ||
248 | |||
249 | // Hard-coded for now | ||
250 | if (m_behaviourSwitches.Contains("c")) | ||
251 | behaviours.Add(new CrossBehaviour()); | ||
252 | |||
253 | if (m_behaviourSwitches.Contains("g")) | ||
254 | behaviours.Add(new GrabbingBehaviour()); | ||
255 | |||
256 | if (m_behaviourSwitches.Contains("n")) | ||
257 | behaviours.Add(new NoneBehaviour()); | ||
258 | |||
259 | if (m_behaviourSwitches.Contains("p")) | ||
260 | behaviours.Add(new PhysicsBehaviour()); | ||
261 | |||
262 | if (m_behaviourSwitches.Contains("t")) | ||
263 | behaviours.Add(new TeleportBehaviour()); | ||
264 | |||
265 | CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); | ||
266 | } | ||
267 | } | ||
268 | } | ||
179 | 269 | ||
270 | public void ConnectBots(int botcount) | ||
271 | { | ||
272 | ConnectingBots = true; | ||
273 | |||
274 | Thread connectBotThread = new Thread(o => ConnectBotsInternal(botcount)); | ||
275 | |||
276 | connectBotThread.Name = "Bots connection thread"; | ||
277 | connectBotThread.Start(); | ||
278 | } | ||
279 | |||
280 | private void ConnectBotsInternal(int botCount) | ||
281 | { | ||
180 | MainConsole.Instance.OutputFormat( | 282 | MainConsole.Instance.OutputFormat( |
181 | "[BOT MANAGER]: Starting {0} bots connecting to {1}, location {2}, named {3} {4}_<n>", | 283 | "[BOT MANAGER]: Starting {0} bots connecting to {1}, location {2}, named {3} {4}_<n>", |
182 | botcount, | 284 | botCount, |
183 | loginUri, | 285 | m_loginUri, |
184 | startUri, | 286 | m_startUri, |
185 | firstName, | 287 | m_firstName, |
186 | lastNameStem); | 288 | m_lastNameStem); |
187 | 289 | ||
188 | MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay); | 290 | MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay); |
189 | MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", InitBotSendAgentUpdates); | 291 | MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", InitBotSendAgentUpdates); |
190 | MainConsole.Instance.OutputFormat("[BOT MANAGER]: InitBotRequestObjectTextures is {0}", InitBotRequestObjectTextures); | 292 | MainConsole.Instance.OutputFormat("[BOT MANAGER]: InitBotRequestObjectTextures is {0}", InitBotRequestObjectTextures); |
191 | 293 | ||
192 | for (int i = 0; i < botcount; i++) | 294 | int connectedBots = 0; |
193 | { | ||
194 | if (ShuttingDown) | ||
195 | break; | ||
196 | |||
197 | string lastName = string.Format("{0}_{1}", lastNameStem, i + fromBotNumber); | ||
198 | |||
199 | // We must give each bot its own list of instantiated behaviours since they store state. | ||
200 | List<IBehaviour> behaviours = new List<IBehaviour>(); | ||
201 | |||
202 | // Hard-coded for now | ||
203 | if (behaviourSwitches.Contains("c")) | ||
204 | behaviours.Add(new CrossBehaviour()); | ||
205 | 295 | ||
206 | if (behaviourSwitches.Contains("g")) | 296 | for (int i = 0; i < m_bots.Count; i++) |
207 | behaviours.Add(new GrabbingBehaviour()); | 297 | { |
298 | lock (m_bots) | ||
299 | { | ||
300 | if (DisconnectingBots) | ||
301 | { | ||
302 | MainConsole.Instance.Output( | ||
303 | "[BOT MANAGER]: Aborting bot connection due to user-initiated disconnection"); | ||
304 | break; | ||
305 | } | ||
208 | 306 | ||
209 | if (behaviourSwitches.Contains("n")) | 307 | if (m_bots[i].ConnectionState == ConnectionState.Disconnected) |
210 | behaviours.Add(new NoneBehaviour()); | 308 | { |
309 | m_bots[i].Connect(); | ||
310 | connectedBots++; | ||
211 | 311 | ||
212 | if (behaviourSwitches.Contains("p")) | 312 | if (connectedBots >= botCount) |
213 | behaviours.Add(new PhysicsBehaviour()); | 313 | break; |
214 | |||
215 | if (behaviourSwitches.Contains("t")) | ||
216 | behaviours.Add(new TeleportBehaviour()); | ||
217 | 314 | ||
218 | StartBot(this, behaviours, firstName, lastName, password, loginUri, startUri, wearSetting); | 315 | // Stagger logins |
316 | Thread.Sleep(LoginDelay); | ||
317 | } | ||
318 | } | ||
219 | } | 319 | } |
320 | |||
321 | ConnectingBots = false; | ||
220 | } | 322 | } |
221 | 323 | ||
222 | /// <summary> | 324 | /// <summary> |
@@ -258,28 +360,8 @@ namespace pCampBot | |||
258 | return string.Format("uri:{0}&{1}&{2}&{3}", regionName, startPos.X, startPos.Y, startPos.Z); | 360 | return string.Format("uri:{0}&{1}&{2}&{3}", regionName, startPos.X, startPos.Y, startPos.Z); |
259 | } | 361 | } |
260 | 362 | ||
261 | // /// <summary> | ||
262 | // /// Add additional bots (and threads) to our bot pool | ||
263 | // /// </summary> | ||
264 | // /// <param name="botcount">How Many of them to add</param> | ||
265 | // public void addbots(int botcount) | ||
266 | // { | ||
267 | // int len = m_td.Length; | ||
268 | // Thread[] m_td2 = new Thread[len + botcount]; | ||
269 | // for (int i = 0; i < len; i++) | ||
270 | // { | ||
271 | // m_td2[i] = m_td[i]; | ||
272 | // } | ||
273 | // m_td = m_td2; | ||
274 | // int newlen = len + botcount; | ||
275 | // for (int i = len; i < newlen; i++) | ||
276 | // { | ||
277 | // startupBot(Config); | ||
278 | // } | ||
279 | // } | ||
280 | |||
281 | /// <summary> | 363 | /// <summary> |
282 | /// This starts up the bot and stores the thread for the bot in the thread array | 364 | /// This creates a bot but does not start it. |
283 | /// </summary> | 365 | /// </summary> |
284 | /// <param name="bm"></param> | 366 | /// <param name="bm"></param> |
285 | /// <param name="behaviours">Behaviours for this bot to perform.</param> | 367 | /// <param name="behaviours">Behaviours for this bot to perform.</param> |
@@ -289,12 +371,12 @@ namespace pCampBot | |||
289 | /// <param name="loginUri">Login URI</param> | 371 | /// <param name="loginUri">Login URI</param> |
290 | /// <param name="startLocation">Location to start the bot. Can be "last", "home" or a specific sim name.</param> | 372 | /// <param name="startLocation">Location to start the bot. Can be "last", "home" or a specific sim name.</param> |
291 | /// <param name="wearSetting"></param> | 373 | /// <param name="wearSetting"></param> |
292 | public void StartBot( | 374 | public void CreateBot( |
293 | BotManager bm, List<IBehaviour> behaviours, | 375 | BotManager bm, List<IBehaviour> behaviours, |
294 | string firstName, string lastName, string password, string loginUri, string startLocation, string wearSetting) | 376 | string firstName, string lastName, string password, string loginUri, string startLocation, string wearSetting) |
295 | { | 377 | { |
296 | MainConsole.Instance.OutputFormat( | 378 | MainConsole.Instance.OutputFormat( |
297 | "[BOT MANAGER]: Starting bot {0} {1}, behaviours are {2}", | 379 | "[BOT MANAGER]: Creating bot {0} {1}, behaviours are {2}", |
298 | firstName, lastName, string.Join(",", behaviours.ConvertAll<string>(b => b.Name).ToArray())); | 380 | firstName, lastName, string.Join(",", behaviours.ConvertAll<string>(b => b.Name).ToArray())); |
299 | 381 | ||
300 | Bot pb = new Bot(bm, behaviours, firstName, lastName, password, startLocation, loginUri); | 382 | Bot pb = new Bot(bm, behaviours, firstName, lastName, password, startLocation, loginUri); |
@@ -305,17 +387,7 @@ namespace pCampBot | |||
305 | pb.OnConnected += handlebotEvent; | 387 | pb.OnConnected += handlebotEvent; |
306 | pb.OnDisconnected += handlebotEvent; | 388 | pb.OnDisconnected += handlebotEvent; |
307 | 389 | ||
308 | lock (m_lBot) | 390 | m_bots.Add(pb); |
309 | m_lBot.Add(pb); | ||
310 | |||
311 | Thread pbThread = new Thread(pb.startup); | ||
312 | pbThread.Name = pb.Name; | ||
313 | pbThread.IsBackground = true; | ||
314 | |||
315 | pbThread.Start(); | ||
316 | |||
317 | // Stagger logins | ||
318 | Thread.Sleep(LoginDelay); | ||
319 | } | 391 | } |
320 | 392 | ||
321 | /// <summary> | 393 | /// <summary> |
@@ -328,54 +400,158 @@ namespace pCampBot | |||
328 | switch (eventt) | 400 | switch (eventt) |
329 | { | 401 | { |
330 | case EventType.CONNECTED: | 402 | case EventType.CONNECTED: |
403 | { | ||
331 | m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Connected"); | 404 | m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Connected"); |
332 | break; | 405 | break; |
406 | } | ||
407 | |||
333 | case EventType.DISCONNECTED: | 408 | case EventType.DISCONNECTED: |
409 | { | ||
334 | m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Disconnected"); | 410 | m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Disconnected"); |
335 | 411 | break; | |
336 | lock (m_lBot) | 412 | } |
337 | { | ||
338 | if (m_lBot.TrueForAll(b => b.ConnectionState == ConnectionState.Disconnected)) | ||
339 | Environment.Exit(0); | ||
340 | |||
341 | break; | ||
342 | } | ||
343 | } | 413 | } |
344 | } | 414 | } |
345 | 415 | ||
346 | /// <summary> | 416 | /// <summary> |
347 | /// Shut down all bots | 417 | /// Standard CreateConsole routine |
348 | /// </summary> | 418 | /// </summary> |
349 | /// <remarks> | 419 | /// <returns></returns> |
350 | /// We launch each shutdown on its own thread so that a slow shutting down bot doesn't hold up all the others. | 420 | protected CommandConsole CreateConsole() |
351 | /// </remarks> | 421 | { |
352 | public void doBotShutdown() | 422 | return new LocalConsole("pCampbot"); |
423 | } | ||
424 | |||
425 | private void HandleConnect(string module, string[] cmd) | ||
426 | { | ||
427 | if (ConnectingBots) | ||
428 | { | ||
429 | MainConsole.Instance.Output("Still connecting bots. Please wait for previous process to complete."); | ||
430 | return; | ||
431 | } | ||
432 | |||
433 | lock (m_bots) | ||
434 | { | ||
435 | int botsToConnect; | ||
436 | int disconnectedBots = m_bots.Count(b => b.ConnectionState == ConnectionState.Disconnected); | ||
437 | |||
438 | if (cmd.Length == 1) | ||
439 | { | ||
440 | botsToConnect = disconnectedBots; | ||
441 | } | ||
442 | else | ||
443 | { | ||
444 | if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[1], out botsToConnect)) | ||
445 | return; | ||
446 | |||
447 | botsToConnect = Math.Min(botsToConnect, disconnectedBots); | ||
448 | } | ||
449 | |||
450 | MainConsole.Instance.OutputFormat("Connecting {0} bots", botsToConnect); | ||
451 | |||
452 | ConnectBots(botsToConnect); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | private void HandleDisconnect(string module, string[] cmd) | ||
353 | { | 457 | { |
354 | lock (m_lBot) | 458 | lock (m_bots) |
355 | { | 459 | { |
356 | foreach (Bot bot in m_lBot) | 460 | int botsToDisconnect; |
461 | int connectedBots = m_bots.Count(b => b.ConnectionState == ConnectionState.Connected); | ||
462 | |||
463 | if (cmd.Length == 1) | ||
464 | { | ||
465 | botsToDisconnect = connectedBots; | ||
466 | } | ||
467 | else | ||
468 | { | ||
469 | if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[1], out botsToDisconnect)) | ||
470 | return; | ||
471 | |||
472 | botsToDisconnect = Math.Min(botsToDisconnect, connectedBots); | ||
473 | } | ||
474 | |||
475 | DisconnectingBots = true; | ||
476 | |||
477 | MainConsole.Instance.OutputFormat("Disconnecting {0} bots", botsToDisconnect); | ||
478 | |||
479 | int disconnectedBots = 0; | ||
480 | |||
481 | for (int i = m_bots.Count - 1; i >= 0; i--) | ||
357 | { | 482 | { |
358 | Bot thisBot = bot; | 483 | if (disconnectedBots >= botsToDisconnect) |
359 | Util.FireAndForget(o => thisBot.shutdown()); | 484 | break; |
485 | |||
486 | Bot thisBot = m_bots[i]; | ||
487 | |||
488 | if (thisBot.ConnectionState == ConnectionState.Connected) | ||
489 | { | ||
490 | Util.FireAndForget(o => thisBot.Disconnect()); | ||
491 | disconnectedBots++; | ||
492 | } | ||
360 | } | 493 | } |
494 | |||
495 | DisconnectingBots = false; | ||
361 | } | 496 | } |
362 | } | 497 | } |
363 | 498 | ||
364 | /// <summary> | 499 | private void HandleSit(string module, string[] cmd) |
365 | /// Standard CreateConsole routine | ||
366 | /// </summary> | ||
367 | /// <returns></returns> | ||
368 | protected CommandConsole CreateConsole() | ||
369 | { | 500 | { |
370 | return new LocalConsole("pCampbot"); | 501 | lock (m_bots) |
502 | { | ||
503 | m_bots.ForEach(b => b.SitOnGround()); | ||
504 | } | ||
505 | } | ||
506 | |||
507 | private void HandleStand(string module, string[] cmd) | ||
508 | { | ||
509 | lock (m_bots) | ||
510 | { | ||
511 | m_bots.ForEach(b => b.Stand()); | ||
512 | } | ||
371 | } | 513 | } |
372 | 514 | ||
373 | private void HandleShutdown(string module, string[] cmd) | 515 | private void HandleShutdown(string module, string[] cmd) |
374 | { | 516 | { |
517 | lock (m_bots) | ||
518 | { | ||
519 | int connectedBots = m_bots.Count(b => b.ConnectionState == ConnectionState.Connected); | ||
520 | |||
521 | if (connectedBots > 0) | ||
522 | { | ||
523 | MainConsole.Instance.OutputFormat("Please disconnect {0} connected bots first", connectedBots); | ||
524 | return; | ||
525 | } | ||
526 | } | ||
527 | |||
375 | MainConsole.Instance.Output("Shutting down"); | 528 | MainConsole.Instance.Output("Shutting down"); |
376 | 529 | ||
377 | ShuttingDown = true; | 530 | Environment.Exit(0); |
378 | doBotShutdown(); | 531 | } |
532 | |||
533 | private void HandleSetBots(string module, string[] cmd) | ||
534 | { | ||
535 | string key = cmd[2]; | ||
536 | string rawValue = cmd[3]; | ||
537 | |||
538 | if (key == "SEND_AGENT_UPDATES") | ||
539 | { | ||
540 | bool newSendAgentUpdatesSetting; | ||
541 | |||
542 | if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newSendAgentUpdatesSetting)) | ||
543 | return; | ||
544 | |||
545 | MainConsole.Instance.OutputFormat( | ||
546 | "Setting SEND_AGENT_UPDATES to {0} for all bots", newSendAgentUpdatesSetting); | ||
547 | |||
548 | lock (m_bots) | ||
549 | m_bots.ForEach(b => b.Client.Settings.SEND_AGENT_UPDATES = newSendAgentUpdatesSetting); | ||
550 | } | ||
551 | else | ||
552 | { | ||
553 | MainConsole.Instance.Output("Error: Only setting currently available is SEND_AGENT_UPDATES"); | ||
554 | } | ||
379 | } | 555 | } |
380 | 556 | ||
381 | private void HandleShowRegions(string module, string[] cmd) | 557 | private void HandleShowRegions(string module, string[] cmd) |
@@ -393,56 +569,87 @@ namespace pCampBot | |||
393 | } | 569 | } |
394 | } | 570 | } |
395 | 571 | ||
396 | private void HandleShowStatus(string module, string[] cmd) | 572 | private void HandleShowBotsStatus(string module, string[] cmd) |
397 | { | 573 | { |
398 | string outputFormat = "{0,-30} {1, -30} {2,-14}"; | 574 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); |
399 | MainConsole.Instance.OutputFormat(outputFormat, "Name", "Region", "Status"); | 575 | cdt.AddColumn("Name", 30); |
576 | cdt.AddColumn("Region", 30); | ||
577 | cdt.AddColumn("Status", 14); | ||
578 | cdt.AddColumn("Connections", 11); | ||
400 | 579 | ||
401 | Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>(); | 580 | Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>(); |
402 | foreach (object o in Enum.GetValues(typeof(ConnectionState))) | 581 | foreach (object o in Enum.GetValues(typeof(ConnectionState))) |
403 | totals[(ConnectionState)o] = 0; | 582 | totals[(ConnectionState)o] = 0; |
404 | 583 | ||
405 | lock (m_lBot) | 584 | lock (m_bots) |
406 | { | 585 | { |
407 | foreach (Bot pb in m_lBot) | 586 | foreach (Bot pb in m_bots) |
408 | { | 587 | { |
409 | Simulator currentSim = pb.Client.Network.CurrentSim; | 588 | Simulator currentSim = pb.Client.Network.CurrentSim; |
410 | totals[pb.ConnectionState]++; | 589 | totals[pb.ConnectionState]++; |
411 | 590 | ||
412 | MainConsole.Instance.OutputFormat( | 591 | cdt.AddRow( |
413 | outputFormat, | 592 | pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState, pb.SimulatorsCount); |
414 | pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState); | ||
415 | } | 593 | } |
416 | } | 594 | } |
417 | 595 | ||
596 | MainConsole.Instance.Output(cdt.ToString()); | ||
597 | |||
418 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | 598 | ConsoleDisplayList cdl = new ConsoleDisplayList(); |
419 | 599 | ||
420 | foreach (KeyValuePair<ConnectionState, int> kvp in totals) | 600 | foreach (KeyValuePair<ConnectionState, int> kvp in totals) |
421 | cdl.AddRow(kvp.Key, kvp.Value); | 601 | cdl.AddRow(kvp.Key, kvp.Value); |
422 | 602 | ||
423 | 603 | MainConsole.Instance.Output(cdl.ToString()); | |
424 | MainConsole.Instance.OutputFormat("\n{0}", cdl.ToString()); | ||
425 | } | 604 | } |
426 | 605 | ||
427 | /* | 606 | private void HandleShowBotStatus(string module, string[] cmd) |
428 | private void HandleQuit(string module, string[] cmd) | ||
429 | { | 607 | { |
430 | m_console.Warn("DANGER", "This should only be used to quit the program if you've already used the shutdown command and the program hasn't quit"); | 608 | if (cmd.Length != 3) |
431 | Environment.Exit(0); | 609 | { |
610 | MainConsole.Instance.Output("Usage: show bot <n>"); | ||
611 | return; | ||
612 | } | ||
613 | |||
614 | int botNumber; | ||
615 | |||
616 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber)) | ||
617 | return; | ||
618 | |||
619 | string name = string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); | ||
620 | |||
621 | Bot bot; | ||
622 | |||
623 | lock (m_bots) | ||
624 | bot = m_bots.Find(b => b.Name == name); | ||
625 | |||
626 | if (bot == null) | ||
627 | { | ||
628 | MainConsole.Instance.Output("No bot found with name {0}", name); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
633 | cdl.AddRow("Name", bot.Name); | ||
634 | cdl.AddRow("Status", bot.ConnectionState); | ||
635 | |||
636 | Simulator currentSim = bot.Client.Network.CurrentSim; | ||
637 | cdl.AddRow("Region", currentSim != null ? currentSim.Name : "(none)"); | ||
638 | |||
639 | List<Simulator> connectedSimulators = bot.Simulators; | ||
640 | List<string> simulatorNames = connectedSimulators.ConvertAll<string>(cs => cs.Name); | ||
641 | cdl.AddRow("Connections", string.Join(", ", simulatorNames.ToArray())); | ||
642 | |||
643 | MainConsole.Instance.Output(cdl.ToString()); | ||
644 | |||
645 | MainConsole.Instance.Output("Settings"); | ||
646 | |||
647 | ConsoleDisplayList statusCdl = new ConsoleDisplayList(); | ||
648 | GridClient botClient = bot.Client; | ||
649 | statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); | ||
650 | |||
651 | MainConsole.Instance.Output(statusCdl.ToString()); | ||
432 | } | 652 | } |
433 | */ | ||
434 | // | ||
435 | // private void HandleAddBots(string module, string[] cmd) | ||
436 | // { | ||
437 | // int newbots = 0; | ||
438 | // | ||
439 | // if (cmd.Length > 2) | ||
440 | // { | ||
441 | // Int32.TryParse(cmd[2], out newbots); | ||
442 | // } | ||
443 | // if (newbots > 0) | ||
444 | // addbots(newbots); | ||
445 | // } | ||
446 | 653 | ||
447 | internal void Grid_GridRegion(object o, GridRegionEventArgs args) | 654 | internal void Grid_GridRegion(object o, GridRegionEventArgs args) |
448 | { | 655 | { |
@@ -463,4 +670,4 @@ namespace pCampBot | |||
463 | } | 670 | } |
464 | } | 671 | } |
465 | } | 672 | } |
466 | } | 673 | } \ No newline at end of file |
diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index b02f917..781bb00 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs | |||
@@ -51,7 +51,7 @@ namespace pCampBot | |||
51 | { | 51 | { |
52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | 53 | ||
54 | public const string ConfigFileName = "pCampbot.ini"; | 54 | public const string ConfigFileName = "pCampBot.ini"; |
55 | 55 | ||
56 | [STAThread] | 56 | [STAThread] |
57 | public static void Main(string[] args) | 57 | public static void Main(string[] args) |
@@ -82,6 +82,13 @@ namespace pCampBot | |||
82 | 82 | ||
83 | IConfigSource configSource = new IniConfigSource(iniFilePath); | 83 | IConfigSource configSource = new IniConfigSource(iniFilePath); |
84 | 84 | ||
85 | IConfig botManagerConfig = configSource.Configs["BotManager"]; | ||
86 | |||
87 | if (botManagerConfig != null) | ||
88 | { | ||
89 | bm.LoginDelay = botManagerConfig.GetInt("LoginDelay", bm.LoginDelay); | ||
90 | } | ||
91 | |||
85 | IConfig botConfig = configSource.Configs["Bot"]; | 92 | IConfig botConfig = configSource.Configs["Bot"]; |
86 | 93 | ||
87 | if (botConfig != null) | 94 | if (botConfig != null) |
@@ -94,11 +101,12 @@ namespace pCampBot | |||
94 | } | 101 | } |
95 | 102 | ||
96 | int botcount = commandLineConfig.GetInt("botcount", 1); | 103 | int botcount = commandLineConfig.GetInt("botcount", 1); |
104 | bool startConnected = commandLineConfig.Get("connect") != null; | ||
105 | |||
106 | bm.CreateBots(botcount, commandLineConfig); | ||
97 | 107 | ||
98 | //startup specified number of bots. 1 is the default | 108 | if (startConnected) |
99 | Thread startBotThread = new Thread(o => bm.dobotStartup(botcount, commandLineConfig)); | 109 | bm.ConnectBots(botcount); |
100 | startBotThread.Name = "Initial start bots thread"; | ||
101 | startBotThread.Start(); | ||
102 | 110 | ||
103 | while (true) | 111 | while (true) |
104 | { | 112 | { |
@@ -119,6 +127,7 @@ namespace pCampBot | |||
119 | //Set up our nifty config.. thanks to nini | 127 | //Set up our nifty config.. thanks to nini |
120 | ArgvConfigSource cs = new ArgvConfigSource(args); | 128 | ArgvConfigSource cs = new ArgvConfigSource(args); |
121 | 129 | ||
130 | cs.AddSwitch("Startup", "connect", "c"); | ||
122 | cs.AddSwitch("Startup", "botcount", "n"); | 131 | cs.AddSwitch("Startup", "botcount", "n"); |
123 | cs.AddSwitch("Startup", "from", "f"); | 132 | cs.AddSwitch("Startup", "from", "f"); |
124 | cs.AddSwitch("Startup", "loginuri", "l"); | 133 | cs.AddSwitch("Startup", "loginuri", "l"); |
@@ -145,20 +154,21 @@ namespace pCampBot | |||
145 | "usage: pCampBot <-loginuri loginuri> [OPTIONS]\n" | 154 | "usage: pCampBot <-loginuri loginuri> [OPTIONS]\n" |
146 | + "Spawns a set of bots to test an OpenSim region\n\n" | 155 | + "Spawns a set of bots to test an OpenSim region\n\n" |
147 | + " -l, -loginuri loginuri for grid/standalone (required)\n" | 156 | + " -l, -loginuri loginuri for grid/standalone (required)\n" |
148 | + " -s, -start optional start location for bots. Can be \"last\", \"home\" or a specific location with or without co-ords (e.g. \"region1\" or \"region2/50/30/90\"\n" | 157 | + " -s, -start start location for bots (optional). Can be \"last\", \"home\" or a specific location with or without co-ords (e.g. \"region1\" or \"region2/50/30/90\"\n" |
149 | + " -firstname first name for the bots\n" | 158 | + " -firstname first name for the bots (required)\n" |
150 | + " -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" | 159 | + " -lastname lastname for the bots (required). Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" |
151 | + " -password password for the bots\n" | 160 | + " -password password for the bots (required)\n" |
152 | + " -n, -botcount optional number of bots to start (default: 1)\n" | 161 | + " -n, -botcount number of bots to start (default: 1) (optional)\n" |
153 | + " -f, -from optional starting number for login bot names, e.g. 25 will login Ima Bot_25, Ima Bot_26, etc. (default: 0)" | 162 | + " -f, -from starting number for login bot names, e.g. 25 will login Ima Bot_25, Ima Bot_26, etc. (default: 0) (optional)\n" |
154 | + " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" | 163 | + " -c, -connect connect all bots at startup (optional)\n" |
164 | + " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p (required)\n" | ||
155 | + " current options are:\n" | 165 | + " current options are:\n" |
156 | + " p (physics - bots constantly move and jump around)\n" | 166 | + " p (physics - bots constantly move and jump around)\n" |
157 | + " g (grab - bots randomly click prims whether set clickable or not)\n" | 167 | + " g (grab - bots randomly click prims whether set clickable or not)\n" |
158 | + " n (none - bots do nothing)\n" | 168 | + " n (none - bots do nothing)\n" |
159 | + " t (teleport - bots regularly teleport between regions on the grid)\n" | 169 | + " t (teleport - bots regularly teleport between regions on the grid)\n" |
160 | // " c (cross)" + | 170 | // " c (cross)\n" + |
161 | + " -wear optional folder from which to load appearance data, \"no\" if there is no such folder (default: no)\n" | 171 | + " -wear folder from which to load appearance data, \"no\" if there is no such folder (default: no) (optional)\n" |
162 | + " -h, -help show this message.\n"); | 172 | + " -h, -help show this message.\n"); |
163 | } | 173 | } |
164 | } | 174 | } |