diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index f19e3910c8..e50dac611e 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -141,6 +141,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod); // Agent management + availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod); availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod); // User management @@ -1901,6 +1902,71 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Access List List Request complete"); } + private void XmlRpcGetAgentsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + bool includeChildren = false; + + if (requestData.Contains("include_children")) + bool.TryParse((string)requestData["include_children"], out includeChildren); + + Scene scene; + GetSceneFromRegionParams(requestData, responseData, out scene); + + ArrayList xmlRpcRegions = new ArrayList(); + responseData["regions"] = xmlRpcRegions; + + Hashtable xmlRpcRegion = new Hashtable(); + xmlRpcRegions.Add(xmlRpcRegion); + + xmlRpcRegion["name"] = scene.Name; + xmlRpcRegion["id"] = scene.RegionInfo.RegionID.ToString(); + + List agents = scene.GetScenePresences(); + ArrayList xmlrpcAgents = new ArrayList(); + + foreach (ScenePresence agent in agents) + { + if (agent.IsChildAgent && !includeChildren) + continue; + + Hashtable xmlRpcAgent = new Hashtable(); + xmlRpcAgent.Add("name", agent.Name); + xmlRpcAgent.Add("id", agent.UUID.ToString()); + xmlRpcAgent.Add("type", agent.PresenceType.ToString()); + xmlRpcAgent.Add("current_parcel_id", agent.currentParcelUUID.ToString()); + + Vector3 pos = agent.AbsolutePosition; + xmlRpcAgent.Add("pos_x", pos.X.ToString()); + xmlRpcAgent.Add("pos_y", pos.Y.ToString()); + xmlRpcAgent.Add("pos_z", pos.Z.ToString()); + + Vector3 lookAt = agent.Lookat; + xmlRpcAgent.Add("lookat_x", lookAt.X.ToString()); + xmlRpcAgent.Add("lookat_y", lookAt.Y.ToString()); + xmlRpcAgent.Add("lookat_z", lookAt.Z.ToString()); + + Vector3 vel = agent.Velocity; + xmlRpcAgent.Add("vel_x", vel.X.ToString()); + xmlRpcAgent.Add("vel_y", vel.Y.ToString()); + xmlRpcAgent.Add("vel_z", vel.Z.ToString()); + + xmlRpcAgent.Add("is_flying", agent.Flying.ToString()); + xmlRpcAgent.Add("is_sat_on_ground", agent.SitGround.ToString()); + xmlRpcAgent.Add("is_sat_on_object", agent.IsSatOnObject.ToString()); + + xmlrpcAgents.Add(xmlRpcAgent); + } + + m_log.DebugFormat( + "[REMOTE ADMIN]: XmlRpcGetAgents found {0} agents in {1}", xmlrpcAgents.Count, scene.Name); + + xmlRpcRegion["agents"] = xmlrpcAgents; + responseData["success"] = true; + } + private void XmlRpcTeleportAgentMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { Hashtable responseData = (Hashtable)response.Value; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 7609578aad..220fbbcd97 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -931,67 +931,79 @@ public sealed class BSShapeCollection : IDisposable if (newShape.HasPhysicalShape) return newShape; - // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset - if (prim.BaseShape.SculptEntry - && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed - && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting - && prim.BaseShape.SculptTexture != OMV.UUID.Zero - ) + // VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been + // fetched but we end up here again, the meshing of the asset must have failed. + // Prevent trying to keep fetching the mesh by declaring failure. + if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) { - DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); - // Multiple requestors will know we're waiting for this asset - prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; - - BSPhysObject xprim = prim; - Util.FireAndForget(delegate - { - RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; - if (assetProvider != null) - { - BSPhysObject yprim = xprim; // probably not necessary, but, just in case. - assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) - { - bool assetFound = false; - string mismatchIDs = String.Empty; // DEBUG DEBUG - if (asset != null && yprim.BaseShape.SculptEntry) - { - if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) - { - yprim.BaseShape.SculptData = asset.Data; - // This will cause the prim to see that the filler shape is not the right - // one and try again to build the object. - // No race condition with the normal shape setting since the rebuild is at taint time. - yprim.ForceBodyShapeRebuild(false /* inTaintTime */); - assetFound = true; - } - else - { - mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; - } - } - if (assetFound) - yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; - else - yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; - DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", - yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); - - }); - } - else - { - xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; - PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", - LogHeader, PhysicsScene.Name); - } - }); + prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; + PhysicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}", + LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); } else { - if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) + // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset + if (prim.BaseShape.SculptEntry + && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed + && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting + && prim.BaseShape.SculptTexture != OMV.UUID.Zero + ) { - PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", - LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); + DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); + // Multiple requestors will know we're waiting for this asset + prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; + + BSPhysObject xprim = prim; + Util.FireAndForget(delegate + { + RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; + if (assetProvider != null) + { + BSPhysObject yprim = xprim; // probably not necessary, but, just in case. + assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) + { + bool assetFound = false; + string mismatchIDs = String.Empty; // DEBUG DEBUG + if (asset != null && yprim.BaseShape.SculptEntry) + { + if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) + { + yprim.BaseShape.SculptData = asset.Data; + // This will cause the prim to see that the filler shape is not the right + // one and try again to build the object. + // No race condition with the normal shape setting since the rebuild is at taint time. + yprim.ForceBodyShapeRebuild(false /* inTaintTime */); + assetFound = true; + } + else + { + mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; + } + } + if (assetFound) + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; + else + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; + DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", + yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); + + }); + } + else + { + xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; + PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", + LogHeader, PhysicsScene.Name); + } + }); + } + else + { + if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) + { + PhysicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}", + LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); + } } }