Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/World/Region/RestartModule.cs OpenSim/Region/Framework/Scenes/SceneGraph.cs OpenSim/Region/Framework/Scenes/SceneObjectPart.csavinationmerge
commit
008c98a974
|
@ -179,8 +179,8 @@ namespace OpenSim.Framework.Console
|
|||
/// Convert a console integer to an int, automatically complaining if a console is given.
|
||||
/// </summary>
|
||||
/// <param name='console'>Can be null if no console is available.</param>
|
||||
/// <param name='rawConsoleVector'>/param>
|
||||
/// <param name='vector'></param>
|
||||
/// <param name='rawConsoleInt'>/param>
|
||||
/// <param name='i'></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryParseConsoleInt(ICommandConsole console, string rawConsoleInt, out int i)
|
||||
{
|
||||
|
@ -195,6 +195,31 @@ namespace OpenSim.Framework.Console
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a console integer to a natural int, automatically complaining if a console is given.
|
||||
/// </summary>
|
||||
/// <param name='console'>Can be null if no console is available.</param>
|
||||
/// <param name='rawConsoleInt'>/param>
|
||||
/// <param name='i'></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryParseConsoleNaturalInt(ICommandConsole console, string rawConsoleInt, out int i)
|
||||
{
|
||||
if (TryParseConsoleInt(console, rawConsoleInt, out i))
|
||||
{
|
||||
if (i < 0)
|
||||
{
|
||||
if (console != null)
|
||||
console.OutputFormat("ERROR: {0} is not a positive integer", rawConsoleInt);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
|
||||
/// </summary>
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace OpenSim.Framework.Monitoring
|
|||
if (cmd[3] == "start")
|
||||
{
|
||||
Start();
|
||||
con.OutputFormat("Now recording all stats very {0}ms to file", m_statsLogIntervalMs);
|
||||
con.OutputFormat("Now recording all stats to file every {0}ms", m_statsLogIntervalMs);
|
||||
}
|
||||
else if (cmd[3] == "stop")
|
||||
{
|
||||
|
|
|
@ -201,12 +201,12 @@ namespace OpenSim
|
|||
|
||||
envConfigSource.LoadEnv();
|
||||
m_config.Source.Merge(envConfigSource);
|
||||
m_config.Source.ExpandKeyValues();
|
||||
}
|
||||
|
||||
|
||||
ReadConfigSettings();
|
||||
|
||||
m_config.Source.ExpandKeyValues();
|
||||
|
||||
return m_config;
|
||||
}
|
||||
|
||||
|
|
|
@ -6777,6 +6777,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
#endregion
|
||||
|
||||
if (SceneAgent.IsChildAgent)
|
||||
{
|
||||
SendCantSitBecauseChildAgentResponse();
|
||||
return true;
|
||||
}
|
||||
|
||||
AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit;
|
||||
|
||||
if (handlerAgentRequestSit != null)
|
||||
|
@ -6801,6 +6807,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
#endregion
|
||||
|
||||
if (SceneAgent.IsChildAgent)
|
||||
{
|
||||
SendCantSitBecauseChildAgentResponse();
|
||||
return true;
|
||||
}
|
||||
|
||||
AgentSit handlerAgentSit = OnAgentSit;
|
||||
if (handlerAgentSit != null)
|
||||
{
|
||||
|
@ -6810,6 +6822,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used when a child agent gets a sit response which should not be fulfilled.
|
||||
/// </summary>
|
||||
private void SendCantSitBecauseChildAgentResponse()
|
||||
{
|
||||
SendAlertMessage("Try moving closer. Can't sit on object because it is not in the same region as you.");
|
||||
}
|
||||
|
||||
private bool HandleSoundTrigger(IClientAPI sender, Packet Pack)
|
||||
{
|
||||
SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack;
|
||||
|
@ -12934,7 +12954,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
if (p is ScenePresence)
|
||||
{
|
||||
ScenePresence presence = p as ScenePresence;
|
||||
// It turns out to get the agent to stop flying, you have to feed it stop flying velocities
|
||||
// There's no explicit message to send the client to tell it to stop flying.. it relies on the
|
||||
// velocity, collision plane and avatar height
|
||||
|
@ -12942,15 +12961,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// Add 1/6 the avatar's height to it's position so it doesn't shoot into the air
|
||||
// when the avatar stands up
|
||||
|
||||
Vector3 pos = presence.AbsolutePosition;
|
||||
|
||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock block =
|
||||
CreateImprovedTerseBlock(p, false);
|
||||
|
||||
const float TIME_DILATION = 1.0f;
|
||||
ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
|
||||
|
||||
|
||||
ImprovedTerseObjectUpdatePacket packet
|
||||
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
|
||||
PacketType.ImprovedTerseObjectUpdate);
|
||||
|
|
|
@ -538,7 +538,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message);
|
||||
m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e);
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -309,6 +309,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
string serverURI = string.Empty;
|
||||
GetUserProfileServerURI(targetID, out serverURI);
|
||||
UUID creatorId = UUID.Zero;
|
||||
Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>();
|
||||
|
||||
OSDMap parameters= new OSDMap();
|
||||
UUID.TryParse(args[0], out creatorId);
|
||||
|
@ -316,15 +317,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
OSD Params = (OSD)parameters;
|
||||
if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString()))
|
||||
{
|
||||
// Error Handling here!
|
||||
// if(parameters.ContainsKey("message")
|
||||
remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds);
|
||||
return;
|
||||
}
|
||||
|
||||
parameters = (OSDMap)Params;
|
||||
|
||||
OSDArray list = (OSDArray)parameters["result"];
|
||||
|
||||
Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>();
|
||||
|
||||
foreach(OSD map in list)
|
||||
{
|
||||
|
@ -441,7 +441,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
Vector3 pos = remoteClient.SceneAgent.AbsolutePosition;
|
||||
ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y);
|
||||
ScenePresence p = FindPresence(remoteClient.AgentId);
|
||||
// Vector3 avaPos = p.AbsolutePosition;
|
||||
|
||||
string serverURI = string.Empty;
|
||||
GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
|
||||
|
@ -543,13 +542,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
string serverURI = string.Empty;
|
||||
GetUserProfileServerURI(targetId, out serverURI);
|
||||
|
||||
Dictionary<UUID, string> picks = new Dictionary<UUID, string>();
|
||||
|
||||
OSDMap parameters= new OSDMap();
|
||||
parameters.Add("creatorId", OSD.FromUUID(targetId));
|
||||
OSD Params = (OSD)parameters;
|
||||
if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString()))
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage(
|
||||
"Error requesting picks", false);
|
||||
remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -557,8 +557,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
|
||||
OSDArray list = (OSDArray)parameters["result"];
|
||||
|
||||
Dictionary<UUID, string> picks = new Dictionary<UUID, string>();
|
||||
|
||||
foreach(OSD map in list)
|
||||
{
|
||||
OSDMap m = (OSDMap)map;
|
||||
|
@ -762,8 +760,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
object Note = (object)note;
|
||||
if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString()))
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage(
|
||||
"Error requesting note", false);
|
||||
remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes);
|
||||
return;
|
||||
}
|
||||
note = (UserProfileNotes) Note;
|
||||
|
||||
|
@ -796,8 +794,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
object Note = note;
|
||||
if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString()))
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage(
|
||||
"Error updating note", false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endregion Notes
|
||||
|
@ -1033,8 +1030,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
OSD Params = (OSD)parameters;
|
||||
if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString()))
|
||||
{
|
||||
// Error Handling here!
|
||||
// if(parameters.ContainsKey("message")
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1224,7 +1219,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
byte[] content = Encoding.UTF8.GetBytes(jsonRequestData);
|
||||
|
||||
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
|
||||
// webRequest.Credentials = new NetworkCredential(rpcUser, rpcPass);
|
||||
|
||||
webRequest.ContentType = "application/json-rpc";
|
||||
webRequest.Method = "POST";
|
||||
|
||||
|
@ -1245,7 +1240,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
}
|
||||
|
||||
Stream rstream = webResponse.GetResponseStream();
|
||||
OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream);
|
||||
if (rstream.Length < 1)
|
||||
return false;
|
||||
|
||||
OSDMap mret = new OSDMap();
|
||||
try
|
||||
{
|
||||
mret = (OSDMap)OSDParser.DeserializeJson(rstream);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (mret.ContainsKey("error"))
|
||||
return false;
|
||||
|
@ -1310,6 +1318,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
|||
}
|
||||
|
||||
Stream rstream = webResponse.GetResponseStream();
|
||||
if (rstream.Length < 1)
|
||||
return false;
|
||||
|
||||
OSDMap response = new OSDMap();
|
||||
try
|
||||
|
|
|
@ -837,8 +837,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
|
||||
return;
|
||||
|
@ -1058,8 +1058,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
|
||||
return;
|
||||
|
|
|
@ -48,8 +48,8 @@ namespace OpenSim.Region.CoreModules.World.Region
|
|||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")]
|
||||
public class RestartModule : INonSharedRegionModule, IRestartModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected Scene m_Scene;
|
||||
protected Timer m_CountdownTimer = null;
|
||||
|
@ -222,6 +222,8 @@ namespace OpenSim.Region.CoreModules.World.Region
|
|||
}
|
||||
|
||||
public void SetTimer(int intervalSeconds)
|
||||
{
|
||||
if (intervalSeconds > 0)
|
||||
{
|
||||
m_CountdownTimer = new Timer();
|
||||
m_CountdownTimer.AutoReset = false;
|
||||
|
@ -229,6 +231,18 @@ namespace OpenSim.Region.CoreModules.World.Region
|
|||
m_CountdownTimer.Elapsed += OnTimer;
|
||||
m_CountdownTimer.Start();
|
||||
}
|
||||
else if (m_CountdownTimer != null)
|
||||
{
|
||||
m_CountdownTimer.Stop();
|
||||
m_CountdownTimer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[RESTART MODULE]: Tried to set restart timer to {0} in {1}, which is not a valid interval",
|
||||
intervalSeconds, m_Scene.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTimer(object source, ElapsedEventArgs e)
|
||||
{
|
||||
|
|
|
@ -3986,7 +3986,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
try
|
||||
{
|
||||
if (!AuthorizeUser(acd, SeeIntoRegion, out reason))
|
||||
if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason))
|
||||
{
|
||||
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||
return false;
|
||||
|
@ -4596,10 +4596,27 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
// Check that the auth_token is valid
|
||||
AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID);
|
||||
if (acd != null && acd.SessionID.ToString() == auth_token)
|
||||
|
||||
if (acd == null)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.",
|
||||
agentID, Name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (acd.SessionID.ToString() == auth_token)
|
||||
{
|
||||
return IncomingCloseAgent(agentID, force);
|
||||
}
|
||||
else
|
||||
m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token);
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}",
|
||||
agentID, auth_token, Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -631,40 +631,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
protected internal ScenePresence CreateAndAddChildScenePresence(
|
||||
IClientAPI client, AvatarAppearance appearance, PresenceType type)
|
||||
{
|
||||
ScenePresence newAvatar = null;
|
||||
|
||||
// ScenePresence always defaults to child agent
|
||||
newAvatar = new ScenePresence(client, m_parentScene, appearance, type);
|
||||
|
||||
AddScenePresence(newAvatar);
|
||||
|
||||
return newAvatar;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a presence to the scene
|
||||
/// </summary>
|
||||
/// <param name="presence"></param>
|
||||
protected internal void AddScenePresence(ScenePresence presence)
|
||||
{
|
||||
// Always a child when added to the scene
|
||||
bool child = presence.IsChildAgent;
|
||||
|
||||
if (child)
|
||||
{
|
||||
m_numChildAgents++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_numRootAgents++;
|
||||
presence.AddToPhysicalScene(false);
|
||||
}
|
||||
ScenePresence presence = new ScenePresence(client, m_parentScene, appearance, type);
|
||||
|
||||
Entities[presence.UUID] = presence;
|
||||
|
||||
m_scenePresencesLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
m_numChildAgents++;
|
||||
|
||||
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
|
||||
List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
|
||||
|
||||
|
@ -675,7 +651,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
{
|
||||
// Remember the old presene reference from the dictionary
|
||||
// Remember the old presence reference from the dictionary
|
||||
ScenePresence oldref = newmap[presence.UUID];
|
||||
// Replace the presence reference in the dictionary with the new value
|
||||
newmap[presence.UUID] = presence;
|
||||
|
@ -691,6 +667,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_scenePresencesLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
return presence;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -4522,7 +4522,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// For now, we use the NINJA naming scheme for identifying joints.
|
||||
// In the future, we can support other joint specification schemes such as a
|
||||
// custom checkbox in the viewer GUI.
|
||||
if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
|
||||
if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
|
||||
{
|
||||
return IsHingeJoint() || IsBallJoint();
|
||||
}
|
||||
|
|
|
@ -2707,6 +2707,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
|
||||
{
|
||||
if (IsChildAgent)
|
||||
return;
|
||||
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
|
||||
|
||||
if (part != null)
|
||||
|
@ -2793,6 +2796,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void HandleAgentSitOnGround()
|
||||
{
|
||||
if (IsChildAgent)
|
||||
return;
|
||||
|
||||
// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick..
|
||||
m_AngularVelocity = Vector3.Zero;
|
||||
Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
|
||||
|
@ -3451,11 +3457,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
public void RestoreInCurrentScene()
|
||||
{
|
||||
AddToPhysicalScene(false); // not exactly false
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName);
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using NDesk.Options;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.Avatar.SitStand
|
||||
{
|
||||
/// <summary>
|
||||
/// A module that just holds commands for changing avatar sitting and standing states.
|
||||
/// </summary>
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")]
|
||||
public class SitStandCommandModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
|
||||
public string Name { get { return "SitStand Command Module"; } }
|
||||
|
||||
public Type ReplaceableInterface { get { return null; } }
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE");
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE");
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
|
||||
|
||||
m_scene = scene;
|
||||
|
||||
scene.AddCommand(
|
||||
"Users", this, "sit user name",
|
||||
"sit user name [--regex] <first-name> <last-name>",
|
||||
"Sit the named user on an unoccupied object with a sit target.",
|
||||
"If there are no such objects then nothing happens.\n"
|
||||
+ "If --regex is specified then the names are treated as regular expressions.",
|
||||
HandleSitUserNameCommand);
|
||||
|
||||
scene.AddCommand(
|
||||
"Users", this, "stand user name",
|
||||
"stand user name [--regex] <first-name> <last-name>",
|
||||
"Stand the named user.",
|
||||
"If --regex is specified then the names are treated as regular expressions.",
|
||||
HandleStandUserNameCommand);
|
||||
}
|
||||
|
||||
private void HandleSitUserNameCommand(string module, string[] cmd)
|
||||
{
|
||||
if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
|
||||
return;
|
||||
|
||||
if (cmd.Length < 5)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: sit user name [--regex] <first-name> <last-name>");
|
||||
return;
|
||||
}
|
||||
|
||||
List<ScenePresence> scenePresences = GetScenePresences(cmd);
|
||||
|
||||
foreach (ScenePresence sp in scenePresences)
|
||||
{
|
||||
if (sp.SitGround || sp.IsSatOnObject)
|
||||
continue;
|
||||
|
||||
SceneObjectPart sitPart = null;
|
||||
List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups();
|
||||
|
||||
foreach (SceneObjectGroup sceneObject in sceneObjects)
|
||||
{
|
||||
if (sceneObject.IsAttachment)
|
||||
continue;
|
||||
|
||||
foreach (SceneObjectPart part in sceneObject.Parts)
|
||||
{
|
||||
if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
|
||||
{
|
||||
sitPart = part;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sitPart != null)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Sitting {0} on {1} {2} in {3}",
|
||||
sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name);
|
||||
|
||||
sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero);
|
||||
sp.HandleAgentSit(sp.ControllingClient, sp.UUID);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Could not find any unoccupied set seat on which to sit {0} in {1}. Aborting",
|
||||
sp.Name, m_scene.Name);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStandUserNameCommand(string module, string[] cmd)
|
||||
{
|
||||
if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
|
||||
return;
|
||||
|
||||
if (cmd.Length < 5)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: stand user name [--regex] <first-name> <last-name>");
|
||||
return;
|
||||
}
|
||||
|
||||
List<ScenePresence> scenePresences = GetScenePresences(cmd);
|
||||
|
||||
foreach (ScenePresence sp in scenePresences)
|
||||
{
|
||||
if (sp.SitGround || sp.IsSatOnObject)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name);
|
||||
sp.StandUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ScenePresence> GetScenePresences(string[] cmdParams)
|
||||
{
|
||||
bool useRegex = false;
|
||||
OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
|
||||
|
||||
List<string> mainParams = options.Parse(cmdParams);
|
||||
|
||||
string firstName = mainParams[3];
|
||||
string lastName = mainParams[4];
|
||||
|
||||
List<ScenePresence> scenePresencesMatched = new List<ScenePresence>();
|
||||
|
||||
if (useRegex)
|
||||
{
|
||||
Regex nameRegex = new Regex(string.Format("{0} {1}", firstName, lastName));
|
||||
List<ScenePresence> scenePresences = m_scene.GetScenePresences();
|
||||
|
||||
foreach (ScenePresence sp in scenePresences)
|
||||
{
|
||||
if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name))
|
||||
scenePresencesMatched.Add(sp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
|
||||
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
scenePresencesMatched.Add(sp);
|
||||
}
|
||||
|
||||
return scenePresencesMatched;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1221,6 +1221,50 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
//BSParam.TerrainImplementation = 0;
|
||||
world.SetGravity(new IndexedVector3(0,0,p.gravity));
|
||||
|
||||
// Turn off Pooling since globals and pooling are bad for threading.
|
||||
BulletGlobals.VoronoiSimplexSolverPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SubSimplexConvexCastPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ManifoldPointPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.CastResultPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SphereShapePool.SetPoolingEnabled(false);
|
||||
BulletGlobals.DbvtNodePool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SingleRayCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SubSimplexClosestResultPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.GjkPairDetectorPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.DbvtTreeColliderPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SingleSweepCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.BroadphaseRayTesterPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ClosestNotMeConvexResultCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.GjkEpaPenetrationDepthSolverPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ContinuousConvexCollisionPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.DbvtStackDataBlockPool.SetPoolingEnabled(false);
|
||||
|
||||
BulletGlobals.BoxBoxCollisionAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.CompoundCollisionAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ConvexConcaveCollisionAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ConvexConvexAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ConvexPlaneAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SphereBoxCollisionAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SphereSphereCollisionAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SphereTriangleCollisionAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.GImpactCollisionAlgorithmPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.GjkEpaSolver2MinkowskiDiffPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.PersistentManifoldPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ManifoldResultPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.GJKPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.GIM_ShapeRetrieverPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.TriangleShapePool.SetPoolingEnabled(false);
|
||||
BulletGlobals.SphereTriangleDetectorPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.CompoundLeafCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.GjkConvexCastPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.LocalTriangleSphereCastCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.BridgeTriangleRaycastCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.BridgeTriangleConcaveRaycastCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.BridgeTriangleConvexcastCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.MyNodeOverlapCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.ClosestRayResultCallbackPool.SetPoolingEnabled(false);
|
||||
BulletGlobals.DebugDrawcallbackPool.SetPoolingEnabled(false);
|
||||
|
||||
return world;
|
||||
}
|
||||
//m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL
|
||||
|
@ -1914,7 +1958,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
|||
heightMap, scaleFactor,
|
||||
minHeight, maxHeight, upAxis,
|
||||
false);
|
||||
terrainShape.SetMargin(collisionMargin + 0.5f);
|
||||
terrainShape.SetMargin(collisionMargin);
|
||||
terrainShape.SetUseDiamondSubdivision(true);
|
||||
terrainShape.SetUserPointer(id);
|
||||
return new BulletShapeXNA(terrainShape, BSPhysicsShapeType.SHAPE_TERRAIN);
|
||||
|
|
|
@ -946,7 +946,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
private void ProcessRegularTaints()
|
||||
{
|
||||
if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process
|
||||
if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process
|
||||
{
|
||||
// swizzle a new list into the list location so we can process what's there
|
||||
List<TaintCallbackEntry> oldList;
|
||||
|
@ -989,7 +989,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
// Taints that happen after the normal taint processing but before the simulation step.
|
||||
private void ProcessPostTaintTaints()
|
||||
{
|
||||
if (_postTaintOperations.Count > 0)
|
||||
if (m_initialized && _postTaintOperations.Count > 0)
|
||||
{
|
||||
Dictionary<string, TaintCallbackEntry> oldList;
|
||||
lock (_taintLock)
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace OpenSim.Services.GridService
|
|||
{
|
||||
MainConsole.Instance.Commands.AddCommand("Regions", true,
|
||||
"deregister region id",
|
||||
"deregister region id <Region UUID>",
|
||||
"deregister region id <region-id>+",
|
||||
"Deregister a region manually.",
|
||||
String.Empty,
|
||||
HandleDeregisterRegion);
|
||||
|
@ -526,13 +526,15 @@ namespace OpenSim.Services.GridService
|
|||
|
||||
private void HandleDeregisterRegion(string module, string[] cmd)
|
||||
{
|
||||
if (cmd.Length != 4)
|
||||
if (cmd.Length < 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Syntax: degregister region id <Region UUID>");
|
||||
MainConsole.Instance.Output("Usage: degregister region id <region-id>+");
|
||||
return;
|
||||
}
|
||||
|
||||
string rawRegionUuid = cmd[3];
|
||||
for (int i = 3; i < cmd.Length; i++)
|
||||
{
|
||||
string rawRegionUuid = cmd[i];
|
||||
UUID regionUuid;
|
||||
|
||||
if (!UUID.TryParse(rawRegionUuid, out regionUuid))
|
||||
|
@ -558,8 +560,7 @@ namespace OpenSim.Services.GridService
|
|||
// I don't think this can ever occur if we know that the region exists.
|
||||
MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleShowRegions(string module, string[] cmd)
|
||||
|
|
|
@ -326,7 +326,7 @@ namespace OpenSim.Services.HypergridService
|
|||
return false;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: User is OK");
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: User {0} is ok", aCircuit.Name);
|
||||
|
||||
bool isFirstLogin = false;
|
||||
//
|
||||
|
@ -345,7 +345,8 @@ namespace OpenSim.Services.HypergridService
|
|||
aCircuit.firstname, aCircuit.lastname);
|
||||
return false;
|
||||
}
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence ok");
|
||||
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name);
|
||||
|
||||
// Also login foreigners with GridUser service
|
||||
if (m_GridUserService != null && account == null)
|
||||
|
@ -376,7 +377,9 @@ namespace OpenSim.Services.HypergridService
|
|||
reason = "Destination region not found";
|
||||
return false;
|
||||
}
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: destination ok: {0}", destination.RegionName);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[GATEKEEPER SERVICE]: Destination {0} is ok for {1}", destination.RegionName, aCircuit.Name);
|
||||
|
||||
//
|
||||
// Adjust the visible name
|
||||
|
@ -410,7 +413,8 @@ namespace OpenSim.Services.HypergridService
|
|||
// Preserve our TeleportFlags we have gathered so-far
|
||||
loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags;
|
||||
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: launching agent {0}", loginFlag);
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: Launching {0} {1}", aCircuit.Name, loginFlag);
|
||||
|
||||
return m_SimulationService.CreateAgent(destination, aCircuit, (uint)loginFlag, out reason);
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,9 @@ namespace OpenSim.Services.Interfaces
|
|||
if ( m_serverURI != string.Empty ) {
|
||||
return m_serverURI;
|
||||
} else {
|
||||
if (m_httpPort == 0)
|
||||
return "http://" + m_externalHostName + "/";
|
||||
else
|
||||
return "http://" + m_externalHostName + ":" + m_httpPort + "/";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,28 @@ namespace pCampBot
|
|||
/// </summary>
|
||||
public ConnectionState ConnectionState { get; private set; }
|
||||
|
||||
public List<Simulator> Simulators
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (Client.Network.Simulators)
|
||||
return new List<Simulator>(Client.Network.Simulators);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of connections that this bot has to different simulators.
|
||||
/// </summary>
|
||||
/// <value>Includes both root and child connections.</value>
|
||||
public int SimulatorsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (Client.Network.Simulators)
|
||||
return Client.Network.Simulators.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public string FirstName { get; private set; }
|
||||
public string LastName { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
|
@ -145,8 +167,6 @@ namespace pCampBot
|
|||
|
||||
behaviours.ForEach(b => b.Initialize(this));
|
||||
|
||||
Client = new GridClient();
|
||||
|
||||
Random = new Random(Environment.TickCount);// We do stuff randomly here
|
||||
FirstName = firstName;
|
||||
LastName = lastName;
|
||||
|
@ -157,6 +177,59 @@ namespace pCampBot
|
|||
|
||||
Manager = bm;
|
||||
Behaviours = behaviours;
|
||||
|
||||
// Only calling for use as a template.
|
||||
CreateLibOmvClient();
|
||||
}
|
||||
|
||||
private void CreateLibOmvClient()
|
||||
{
|
||||
GridClient newClient = new GridClient();
|
||||
|
||||
if (Client != null)
|
||||
{
|
||||
newClient.Settings.LOGIN_SERVER = Client.Settings.LOGIN_SERVER;
|
||||
newClient.Settings.ALWAYS_DECODE_OBJECTS = Client.Settings.ALWAYS_DECODE_OBJECTS;
|
||||
newClient.Settings.AVATAR_TRACKING = Client.Settings.AVATAR_TRACKING;
|
||||
newClient.Settings.OBJECT_TRACKING = Client.Settings.OBJECT_TRACKING;
|
||||
newClient.Settings.SEND_AGENT_THROTTLE = Client.Settings.SEND_AGENT_THROTTLE;
|
||||
newClient.Settings.SEND_AGENT_UPDATES = Client.Settings.SEND_AGENT_UPDATES;
|
||||
newClient.Settings.SEND_PINGS = Client.Settings.SEND_PINGS;
|
||||
newClient.Settings.STORE_LAND_PATCHES = Client.Settings.STORE_LAND_PATCHES;
|
||||
newClient.Settings.USE_ASSET_CACHE = Client.Settings.USE_ASSET_CACHE;
|
||||
newClient.Settings.MULTIPLE_SIMS = Client.Settings.MULTIPLE_SIMS;
|
||||
newClient.Throttle.Asset = Client.Throttle.Asset;
|
||||
newClient.Throttle.Land = Client.Throttle.Land;
|
||||
newClient.Throttle.Task = Client.Throttle.Task;
|
||||
newClient.Throttle.Texture = Client.Throttle.Texture;
|
||||
newClient.Throttle.Wind = Client.Throttle.Wind;
|
||||
newClient.Throttle.Total = Client.Throttle.Total;
|
||||
}
|
||||
else
|
||||
{
|
||||
newClient.Settings.LOGIN_SERVER = LoginUri;
|
||||
newClient.Settings.ALWAYS_DECODE_OBJECTS = false;
|
||||
newClient.Settings.AVATAR_TRACKING = false;
|
||||
newClient.Settings.OBJECT_TRACKING = false;
|
||||
newClient.Settings.SEND_AGENT_THROTTLE = true;
|
||||
newClient.Settings.SEND_PINGS = true;
|
||||
newClient.Settings.STORE_LAND_PATCHES = false;
|
||||
newClient.Settings.USE_ASSET_CACHE = false;
|
||||
newClient.Settings.MULTIPLE_SIMS = true;
|
||||
newClient.Throttle.Asset = 100000;
|
||||
newClient.Throttle.Land = 100000;
|
||||
newClient.Throttle.Task = 100000;
|
||||
newClient.Throttle.Texture = 100000;
|
||||
newClient.Throttle.Wind = 100000;
|
||||
newClient.Throttle.Total = 400000;
|
||||
}
|
||||
|
||||
newClient.Network.LoginProgress += this.Network_LoginProgress;
|
||||
newClient.Network.SimConnected += this.Network_SimConnected;
|
||||
newClient.Network.Disconnected += this.Network_OnDisconnected;
|
||||
newClient.Objects.ObjectUpdate += Objects_NewPrim;
|
||||
|
||||
Client = newClient;
|
||||
}
|
||||
|
||||
//We do our actions here. This is where one would
|
||||
|
@ -179,7 +252,7 @@ namespace pCampBot
|
|||
/// <summary>
|
||||
/// Tells LibSecondLife to logout and disconnect. Raises the disconnect events once it finishes.
|
||||
/// </summary>
|
||||
public void shutdown()
|
||||
public void Disconnect()
|
||||
{
|
||||
ConnectionState = ConnectionState.Disconnecting;
|
||||
|
||||
|
@ -189,34 +262,27 @@ namespace pCampBot
|
|||
Client.Network.Logout();
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
Thread connectThread = new Thread(ConnectInternal);
|
||||
connectThread.Name = Name;
|
||||
connectThread.IsBackground = true;
|
||||
|
||||
connectThread.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the bot startup loop.
|
||||
/// </summary>
|
||||
public void startup()
|
||||
private void ConnectInternal()
|
||||
{
|
||||
Client.Settings.LOGIN_SERVER = LoginUri;
|
||||
Client.Settings.ALWAYS_DECODE_OBJECTS = false;
|
||||
Client.Settings.AVATAR_TRACKING = false;
|
||||
Client.Settings.OBJECT_TRACKING = false;
|
||||
Client.Settings.SEND_AGENT_THROTTLE = true;
|
||||
Client.Settings.SEND_AGENT_UPDATES = false;
|
||||
Client.Settings.SEND_PINGS = true;
|
||||
Client.Settings.STORE_LAND_PATCHES = false;
|
||||
Client.Settings.USE_ASSET_CACHE = false;
|
||||
Client.Settings.MULTIPLE_SIMS = true;
|
||||
Client.Throttle.Asset = 100000;
|
||||
Client.Throttle.Land = 100000;
|
||||
Client.Throttle.Task = 100000;
|
||||
Client.Throttle.Texture = 100000;
|
||||
Client.Throttle.Wind = 100000;
|
||||
Client.Throttle.Total = 400000;
|
||||
Client.Network.LoginProgress += this.Network_LoginProgress;
|
||||
Client.Network.SimConnected += this.Network_SimConnected;
|
||||
Client.Network.Disconnected += this.Network_OnDisconnected;
|
||||
Client.Objects.ObjectUpdate += Objects_NewPrim;
|
||||
|
||||
ConnectionState = ConnectionState.Connecting;
|
||||
|
||||
// Current create a new client on each connect. libomv doesn't seem to process new sim
|
||||
// information (e.g. EstablishAgentCommunication events) if connecting after a disceonnect with the same
|
||||
// client
|
||||
CreateLibOmvClient();
|
||||
|
||||
if (Client.Network.Login(FirstName, LastName, Password, "pCampBot", StartLocation, "Your name"))
|
||||
{
|
||||
ConnectionState = ConnectionState.Connected;
|
||||
|
@ -261,6 +327,30 @@ namespace pCampBot
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sit this bot on the ground.
|
||||
/// </summary>
|
||||
public void SitOnGround()
|
||||
{
|
||||
if (ConnectionState == ConnectionState.Connected)
|
||||
Client.Self.SitOnGround();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stand this bot
|
||||
/// </summary>
|
||||
public void Stand()
|
||||
{
|
||||
if (ConnectionState == ConnectionState.Connected)
|
||||
{
|
||||
// Unlike sit on ground, here libomv checks whether we have SEND_AGENT_UPDATES enabled.
|
||||
bool prevUpdatesSetting = Client.Settings.SEND_AGENT_UPDATES;
|
||||
Client.Settings.SEND_AGENT_UPDATES = true;
|
||||
Client.Self.Stand();
|
||||
Client.Settings.SEND_AGENT_UPDATES = prevUpdatesSetting;
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveDefaultAppearance()
|
||||
{
|
||||
saveDir = "MyAppearance/" + FirstName + "_" + LastName;
|
||||
|
@ -461,6 +551,8 @@ namespace pCampBot
|
|||
// || args.Reason == NetworkManager.DisconnectType.NetworkTimeout)
|
||||
// && OnDisconnected != null)
|
||||
|
||||
|
||||
|
||||
if (
|
||||
(args.Reason == NetworkManager.DisconnectType.ClientInitiated
|
||||
|| args.Reason == NetworkManager.DisconnectType.ServerInitiated
|
||||
|
|
|
@ -52,9 +52,14 @@ namespace pCampBot
|
|||
public const int DefaultLoginDelay = 5000;
|
||||
|
||||
/// <summary>
|
||||
/// True if pCampbot is in the process of shutting down.
|
||||
/// Is pCampbot in the process of connecting bots?
|
||||
/// </summary>
|
||||
public bool ShuttingDown { get; private set; }
|
||||
public bool ConnectingBots { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is pCampbot in the process of disconnecting bots?
|
||||
/// </summary>
|
||||
public bool DisconnectingBots { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Delay between logins of multiple bots.
|
||||
|
@ -80,7 +85,7 @@ namespace pCampBot
|
|||
/// <summary>
|
||||
/// Created bots, whether active or inactive.
|
||||
/// </summary>
|
||||
protected List<Bot> m_lBot;
|
||||
protected List<Bot> m_bots;
|
||||
|
||||
/// <summary>
|
||||
/// Random number generator.
|
||||
|
@ -97,6 +102,46 @@ namespace pCampBot
|
|||
/// </summary>
|
||||
public Dictionary<ulong, GridRegion> RegionsKnown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// First name for bots
|
||||
/// </summary>
|
||||
private string m_firstName;
|
||||
|
||||
/// <summary>
|
||||
/// Last name stem for bots
|
||||
/// </summary>
|
||||
private string m_lastNameStem;
|
||||
|
||||
/// <summary>
|
||||
/// Password for bots
|
||||
/// </summary>
|
||||
private string m_password;
|
||||
|
||||
/// <summary>
|
||||
/// Login URI for bots.
|
||||
/// </summary>
|
||||
private string m_loginUri;
|
||||
|
||||
/// <summary>
|
||||
/// Start location for bots.
|
||||
/// </summary>
|
||||
private string m_startUri;
|
||||
|
||||
/// <summary>
|
||||
/// Postfix bot number at which bot sequence starts.
|
||||
/// </summary>
|
||||
private int m_fromBotNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Wear setting for bots.
|
||||
/// </summary>
|
||||
private string m_wearSetting;
|
||||
|
||||
/// <summary>
|
||||
/// Behaviour switches for bots.
|
||||
/// </summary>
|
||||
private HashSet<string> m_behaviourSwitches = new HashSet<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Constructor Creates MainConsole.Instance to take commands and provide the place to write data
|
||||
/// </summary>
|
||||
|
@ -130,30 +175,47 @@ namespace pCampBot
|
|||
}
|
||||
}
|
||||
|
||||
m_console.Commands.AddCommand("bot", false, "shutdown",
|
||||
"shutdown",
|
||||
"Shutdown bots and exit", HandleShutdown);
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "shutdown", "shutdown", "Shutdown bots and exit", HandleShutdown);
|
||||
|
||||
m_console.Commands.AddCommand("bot", false, "quit",
|
||||
"quit",
|
||||
"Shutdown bots and exit",
|
||||
HandleShutdown);
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "quit", "quit", "Shutdown bots and exit", HandleShutdown);
|
||||
|
||||
m_console.Commands.AddCommand("bot", false, "show regions",
|
||||
"show regions",
|
||||
"Show regions known to bots",
|
||||
HandleShowRegions);
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "connect", "connect [<n>]", "Connect bots",
|
||||
"If an <n> is given, then the first <n> disconnected bots by postfix number are connected.\n"
|
||||
+ "If no <n> is given, then all currently disconnected bots are connected.",
|
||||
HandleConnect);
|
||||
|
||||
m_console.Commands.AddCommand("bot", false, "show bots",
|
||||
"show bots",
|
||||
"Shows the status of all bots",
|
||||
HandleShowStatus);
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "disconnect", "disconnect [<n>]", "Disconnect bots",
|
||||
"Disconnecting bots will interupt any bot connection process, including connection on startup.\n"
|
||||
+ "If an <n> is given, then the last <n> connected bots by postfix number are disconnected.\n"
|
||||
+ "If no <n> is given, then all currently connected bots are disconnected.",
|
||||
HandleDisconnect);
|
||||
|
||||
// m_console.Commands.AddCommand("bot", false, "add bots",
|
||||
// "add bots <number>",
|
||||
// "Add more bots", HandleAddBots);
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "sit", "sit", "Sit all bots on the ground.",
|
||||
HandleSit);
|
||||
|
||||
m_lBot = new List<Bot>();
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "stand", "stand", "Stand all bots.",
|
||||
HandleStand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "set bots", "set bots <key> <value>", "Set a setting for all bots.", HandleSetBots);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "show regions", "show regions", "Show regions known to bots", HandleShowRegions);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"bot", false, "show bot", "show bot <n>",
|
||||
"Shows the detailed status and settings of a particular bot.", HandleShowBotStatus);
|
||||
|
||||
m_bots = new List<Bot>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -161,63 +223,103 @@ namespace pCampBot
|
|||
/// </summary>
|
||||
/// <param name="botcount">How many bots to start up</param>
|
||||
/// <param name="cs">The configuration for the bots to use</param>
|
||||
public void dobotStartup(int botcount, IConfig startupConfig)
|
||||
public void CreateBots(int botcount, IConfig startupConfig)
|
||||
{
|
||||
string firstName = startupConfig.GetString("firstname");
|
||||
string lastNameStem = startupConfig.GetString("lastname");
|
||||
string password = startupConfig.GetString("password");
|
||||
string loginUri = startupConfig.GetString("loginuri");
|
||||
string startLocation = startupConfig.GetString("start", "last");
|
||||
int fromBotNumber = startupConfig.GetInt("from", 0);
|
||||
string wearSetting = startupConfig.GetString("wear", "no");
|
||||
m_firstName = startupConfig.GetString("firstname");
|
||||
m_lastNameStem = startupConfig.GetString("lastname");
|
||||
m_password = startupConfig.GetString("password");
|
||||
m_loginUri = startupConfig.GetString("loginuri");
|
||||
m_fromBotNumber = startupConfig.GetInt("from", 0);
|
||||
m_wearSetting = startupConfig.GetString("wear", "no");
|
||||
|
||||
string startUri = ParseInputStartLocationToUri(startLocation);
|
||||
m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last"));
|
||||
|
||||
HashSet<string> behaviourSwitches = new HashSet<string>();
|
||||
Array.ForEach<string>(
|
||||
startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b));
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"[BOT MANAGER]: Starting {0} bots connecting to {1}, location {2}, named {3} {4}_<n>",
|
||||
botcount,
|
||||
loginUri,
|
||||
startUri,
|
||||
firstName,
|
||||
lastNameStem);
|
||||
|
||||
MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay);
|
||||
MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", InitBotSendAgentUpdates);
|
||||
MainConsole.Instance.OutputFormat("[BOT MANAGER]: InitBotRequestObjectTextures is {0}", InitBotRequestObjectTextures);
|
||||
startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b));
|
||||
|
||||
for (int i = 0; i < botcount; i++)
|
||||
{
|
||||
if (ShuttingDown)
|
||||
break;
|
||||
|
||||
string lastName = string.Format("{0}_{1}", lastNameStem, i + fromBotNumber);
|
||||
lock (m_bots)
|
||||
{
|
||||
string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber);
|
||||
|
||||
// We must give each bot its own list of instantiated behaviours since they store state.
|
||||
List<IBehaviour> behaviours = new List<IBehaviour>();
|
||||
|
||||
// Hard-coded for now
|
||||
if (behaviourSwitches.Contains("c"))
|
||||
if (m_behaviourSwitches.Contains("c"))
|
||||
behaviours.Add(new CrossBehaviour());
|
||||
|
||||
if (behaviourSwitches.Contains("g"))
|
||||
if (m_behaviourSwitches.Contains("g"))
|
||||
behaviours.Add(new GrabbingBehaviour());
|
||||
|
||||
if (behaviourSwitches.Contains("n"))
|
||||
if (m_behaviourSwitches.Contains("n"))
|
||||
behaviours.Add(new NoneBehaviour());
|
||||
|
||||
if (behaviourSwitches.Contains("p"))
|
||||
if (m_behaviourSwitches.Contains("p"))
|
||||
behaviours.Add(new PhysicsBehaviour());
|
||||
|
||||
if (behaviourSwitches.Contains("t"))
|
||||
if (m_behaviourSwitches.Contains("t"))
|
||||
behaviours.Add(new TeleportBehaviour());
|
||||
|
||||
StartBot(this, behaviours, firstName, lastName, password, loginUri, startUri, wearSetting);
|
||||
CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ConnectBots(int botcount)
|
||||
{
|
||||
ConnectingBots = true;
|
||||
|
||||
Thread connectBotThread = new Thread(o => ConnectBotsInternal(botcount));
|
||||
|
||||
connectBotThread.Name = "Bots connection thread";
|
||||
connectBotThread.Start();
|
||||
}
|
||||
|
||||
private void ConnectBotsInternal(int botCount)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"[BOT MANAGER]: Starting {0} bots connecting to {1}, location {2}, named {3} {4}_<n>",
|
||||
botCount,
|
||||
m_loginUri,
|
||||
m_startUri,
|
||||
m_firstName,
|
||||
m_lastNameStem);
|
||||
|
||||
MainConsole.Instance.OutputFormat("[BOT MANAGER]: Delay between logins is {0}ms", LoginDelay);
|
||||
MainConsole.Instance.OutputFormat("[BOT MANAGER]: BotsSendAgentUpdates is {0}", InitBotSendAgentUpdates);
|
||||
MainConsole.Instance.OutputFormat("[BOT MANAGER]: InitBotRequestObjectTextures is {0}", InitBotRequestObjectTextures);
|
||||
|
||||
int connectedBots = 0;
|
||||
|
||||
for (int i = 0; i < m_bots.Count; i++)
|
||||
{
|
||||
lock (m_bots)
|
||||
{
|
||||
if (DisconnectingBots)
|
||||
{
|
||||
MainConsole.Instance.Output(
|
||||
"[BOT MANAGER]: Aborting bot connection due to user-initiated disconnection");
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_bots[i].ConnectionState == ConnectionState.Disconnected)
|
||||
{
|
||||
m_bots[i].Connect();
|
||||
connectedBots++;
|
||||
|
||||
if (connectedBots >= botCount)
|
||||
break;
|
||||
|
||||
// Stagger logins
|
||||
Thread.Sleep(LoginDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConnectingBots = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the command line start location to a start string/uri that the login mechanism will recognize.
|
||||
|
@ -258,28 +360,8 @@ namespace pCampBot
|
|||
return string.Format("uri:{0}&{1}&{2}&{3}", regionName, startPos.X, startPos.Y, startPos.Z);
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Add additional bots (and threads) to our bot pool
|
||||
// /// </summary>
|
||||
// /// <param name="botcount">How Many of them to add</param>
|
||||
// public void addbots(int botcount)
|
||||
// {
|
||||
// int len = m_td.Length;
|
||||
// Thread[] m_td2 = new Thread[len + botcount];
|
||||
// for (int i = 0; i < len; i++)
|
||||
// {
|
||||
// m_td2[i] = m_td[i];
|
||||
// }
|
||||
// m_td = m_td2;
|
||||
// int newlen = len + botcount;
|
||||
// for (int i = len; i < newlen; i++)
|
||||
// {
|
||||
// startupBot(Config);
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// This starts up the bot and stores the thread for the bot in the thread array
|
||||
/// This creates a bot but does not start it.
|
||||
/// </summary>
|
||||
/// <param name="bm"></param>
|
||||
/// <param name="behaviours">Behaviours for this bot to perform.</param>
|
||||
|
@ -289,12 +371,12 @@ namespace pCampBot
|
|||
/// <param name="loginUri">Login URI</param>
|
||||
/// <param name="startLocation">Location to start the bot. Can be "last", "home" or a specific sim name.</param>
|
||||
/// <param name="wearSetting"></param>
|
||||
public void StartBot(
|
||||
public void CreateBot(
|
||||
BotManager bm, List<IBehaviour> behaviours,
|
||||
string firstName, string lastName, string password, string loginUri, string startLocation, string wearSetting)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"[BOT MANAGER]: Starting bot {0} {1}, behaviours are {2}",
|
||||
"[BOT MANAGER]: Creating bot {0} {1}, behaviours are {2}",
|
||||
firstName, lastName, string.Join(",", behaviours.ConvertAll<string>(b => b.Name).ToArray()));
|
||||
|
||||
Bot pb = new Bot(bm, behaviours, firstName, lastName, password, startLocation, loginUri);
|
||||
|
@ -305,17 +387,7 @@ namespace pCampBot
|
|||
pb.OnConnected += handlebotEvent;
|
||||
pb.OnDisconnected += handlebotEvent;
|
||||
|
||||
lock (m_lBot)
|
||||
m_lBot.Add(pb);
|
||||
|
||||
Thread pbThread = new Thread(pb.startup);
|
||||
pbThread.Name = pb.Name;
|
||||
pbThread.IsBackground = true;
|
||||
|
||||
pbThread.Start();
|
||||
|
||||
// Stagger logins
|
||||
Thread.Sleep(LoginDelay);
|
||||
m_bots.Add(pb);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -328,39 +400,19 @@ namespace pCampBot
|
|||
switch (eventt)
|
||||
{
|
||||
case EventType.CONNECTED:
|
||||
{
|
||||
m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Connected");
|
||||
break;
|
||||
}
|
||||
|
||||
case EventType.DISCONNECTED:
|
||||
{
|
||||
m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Disconnected");
|
||||
|
||||
lock (m_lBot)
|
||||
{
|
||||
if (m_lBot.TrueForAll(b => b.ConnectionState == ConnectionState.Disconnected))
|
||||
Environment.Exit(0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shut down all bots
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We launch each shutdown on its own thread so that a slow shutting down bot doesn't hold up all the others.
|
||||
/// </remarks>
|
||||
public void doBotShutdown()
|
||||
{
|
||||
lock (m_lBot)
|
||||
{
|
||||
foreach (Bot bot in m_lBot)
|
||||
{
|
||||
Bot thisBot = bot;
|
||||
Util.FireAndForget(o => thisBot.shutdown());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standard CreateConsole routine
|
||||
/// </summary>
|
||||
|
@ -370,12 +422,136 @@ namespace pCampBot
|
|||
return new LocalConsole("pCampbot");
|
||||
}
|
||||
|
||||
private void HandleConnect(string module, string[] cmd)
|
||||
{
|
||||
if (ConnectingBots)
|
||||
{
|
||||
MainConsole.Instance.Output("Still connecting bots. Please wait for previous process to complete.");
|
||||
return;
|
||||
}
|
||||
|
||||
lock (m_bots)
|
||||
{
|
||||
int botsToConnect;
|
||||
int disconnectedBots = m_bots.Count(b => b.ConnectionState == ConnectionState.Disconnected);
|
||||
|
||||
if (cmd.Length == 1)
|
||||
{
|
||||
botsToConnect = disconnectedBots;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[1], out botsToConnect))
|
||||
return;
|
||||
|
||||
botsToConnect = Math.Min(botsToConnect, disconnectedBots);
|
||||
}
|
||||
|
||||
MainConsole.Instance.OutputFormat("Connecting {0} bots", botsToConnect);
|
||||
|
||||
ConnectBots(botsToConnect);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDisconnect(string module, string[] cmd)
|
||||
{
|
||||
lock (m_bots)
|
||||
{
|
||||
int botsToDisconnect;
|
||||
int connectedBots = m_bots.Count(b => b.ConnectionState == ConnectionState.Connected);
|
||||
|
||||
if (cmd.Length == 1)
|
||||
{
|
||||
botsToDisconnect = connectedBots;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[1], out botsToDisconnect))
|
||||
return;
|
||||
|
||||
botsToDisconnect = Math.Min(botsToDisconnect, connectedBots);
|
||||
}
|
||||
|
||||
DisconnectingBots = true;
|
||||
|
||||
MainConsole.Instance.OutputFormat("Disconnecting {0} bots", botsToDisconnect);
|
||||
|
||||
int disconnectedBots = 0;
|
||||
|
||||
for (int i = m_bots.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (disconnectedBots >= botsToDisconnect)
|
||||
break;
|
||||
|
||||
Bot thisBot = m_bots[i];
|
||||
|
||||
if (thisBot.ConnectionState == ConnectionState.Connected)
|
||||
{
|
||||
Util.FireAndForget(o => thisBot.Disconnect());
|
||||
disconnectedBots++;
|
||||
}
|
||||
}
|
||||
|
||||
DisconnectingBots = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSit(string module, string[] cmd)
|
||||
{
|
||||
lock (m_bots)
|
||||
{
|
||||
m_bots.ForEach(b => b.SitOnGround());
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStand(string module, string[] cmd)
|
||||
{
|
||||
lock (m_bots)
|
||||
{
|
||||
m_bots.ForEach(b => b.Stand());
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleShutdown(string module, string[] cmd)
|
||||
{
|
||||
lock (m_bots)
|
||||
{
|
||||
int connectedBots = m_bots.Count(b => b.ConnectionState == ConnectionState.Connected);
|
||||
|
||||
if (connectedBots > 0)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Please disconnect {0} connected bots first", connectedBots);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output("Shutting down");
|
||||
|
||||
ShuttingDown = true;
|
||||
doBotShutdown();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private void HandleSetBots(string module, string[] cmd)
|
||||
{
|
||||
string key = cmd[2];
|
||||
string rawValue = cmd[3];
|
||||
|
||||
if (key == "SEND_AGENT_UPDATES")
|
||||
{
|
||||
bool newSendAgentUpdatesSetting;
|
||||
|
||||
if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newSendAgentUpdatesSetting))
|
||||
return;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Setting SEND_AGENT_UPDATES to {0} for all bots", newSendAgentUpdatesSetting);
|
||||
|
||||
lock (m_bots)
|
||||
m_bots.ForEach(b => b.Client.Settings.SEND_AGENT_UPDATES = newSendAgentUpdatesSetting);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Error: Only setting currently available is SEND_AGENT_UPDATES");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleShowRegions(string module, string[] cmd)
|
||||
|
@ -393,56 +569,87 @@ namespace pCampBot
|
|||
}
|
||||
}
|
||||
|
||||
private void HandleShowStatus(string module, string[] cmd)
|
||||
private void HandleShowBotsStatus(string module, string[] cmd)
|
||||
{
|
||||
string outputFormat = "{0,-30} {1, -30} {2,-14}";
|
||||
MainConsole.Instance.OutputFormat(outputFormat, "Name", "Region", "Status");
|
||||
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||
cdt.AddColumn("Name", 30);
|
||||
cdt.AddColumn("Region", 30);
|
||||
cdt.AddColumn("Status", 14);
|
||||
cdt.AddColumn("Connections", 11);
|
||||
|
||||
Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>();
|
||||
foreach (object o in Enum.GetValues(typeof(ConnectionState)))
|
||||
totals[(ConnectionState)o] = 0;
|
||||
|
||||
lock (m_lBot)
|
||||
lock (m_bots)
|
||||
{
|
||||
foreach (Bot pb in m_lBot)
|
||||
foreach (Bot pb in m_bots)
|
||||
{
|
||||
Simulator currentSim = pb.Client.Network.CurrentSim;
|
||||
totals[pb.ConnectionState]++;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
outputFormat,
|
||||
pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState);
|
||||
cdt.AddRow(
|
||||
pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState, pb.SimulatorsCount);
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output(cdt.ToString());
|
||||
|
||||
ConsoleDisplayList cdl = new ConsoleDisplayList();
|
||||
|
||||
foreach (KeyValuePair<ConnectionState, int> kvp in totals)
|
||||
cdl.AddRow(kvp.Key, kvp.Value);
|
||||
|
||||
|
||||
MainConsole.Instance.OutputFormat("\n{0}", cdl.ToString());
|
||||
MainConsole.Instance.Output(cdl.ToString());
|
||||
}
|
||||
|
||||
/*
|
||||
private void HandleQuit(string module, string[] cmd)
|
||||
private void HandleShowBotStatus(string module, string[] cmd)
|
||||
{
|
||||
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");
|
||||
Environment.Exit(0);
|
||||
if (cmd.Length != 3)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: show bot <n>");
|
||||
return;
|
||||
}
|
||||
|
||||
int botNumber;
|
||||
|
||||
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber))
|
||||
return;
|
||||
|
||||
string name = string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber);
|
||||
|
||||
Bot bot;
|
||||
|
||||
lock (m_bots)
|
||||
bot = m_bots.Find(b => b.Name == name);
|
||||
|
||||
if (bot == null)
|
||||
{
|
||||
MainConsole.Instance.Output("No bot found with name {0}", name);
|
||||
return;
|
||||
}
|
||||
|
||||
ConsoleDisplayList cdl = new ConsoleDisplayList();
|
||||
cdl.AddRow("Name", bot.Name);
|
||||
cdl.AddRow("Status", bot.ConnectionState);
|
||||
|
||||
Simulator currentSim = bot.Client.Network.CurrentSim;
|
||||
cdl.AddRow("Region", currentSim != null ? currentSim.Name : "(none)");
|
||||
|
||||
List<Simulator> connectedSimulators = bot.Simulators;
|
||||
List<string> simulatorNames = connectedSimulators.ConvertAll<string>(cs => cs.Name);
|
||||
cdl.AddRow("Connections", string.Join(", ", simulatorNames.ToArray()));
|
||||
|
||||
MainConsole.Instance.Output(cdl.ToString());
|
||||
|
||||
MainConsole.Instance.Output("Settings");
|
||||
|
||||
ConsoleDisplayList statusCdl = new ConsoleDisplayList();
|
||||
GridClient botClient = bot.Client;
|
||||
statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES);
|
||||
|
||||
MainConsole.Instance.Output(statusCdl.ToString());
|
||||
}
|
||||
*/
|
||||
//
|
||||
// private void HandleAddBots(string module, string[] cmd)
|
||||
// {
|
||||
// int newbots = 0;
|
||||
//
|
||||
// if (cmd.Length > 2)
|
||||
// {
|
||||
// Int32.TryParse(cmd[2], out newbots);
|
||||
// }
|
||||
// if (newbots > 0)
|
||||
// addbots(newbots);
|
||||
// }
|
||||
|
||||
internal void Grid_GridRegion(object o, GridRegionEventArgs args)
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace pCampBot
|
|||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public const string ConfigFileName = "pCampbot.ini";
|
||||
public const string ConfigFileName = "pCampBot.ini";
|
||||
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
|
@ -82,6 +82,13 @@ namespace pCampBot
|
|||
|
||||
IConfigSource configSource = new IniConfigSource(iniFilePath);
|
||||
|
||||
IConfig botManagerConfig = configSource.Configs["BotManager"];
|
||||
|
||||
if (botManagerConfig != null)
|
||||
{
|
||||
bm.LoginDelay = botManagerConfig.GetInt("LoginDelay", bm.LoginDelay);
|
||||
}
|
||||
|
||||
IConfig botConfig = configSource.Configs["Bot"];
|
||||
|
||||
if (botConfig != null)
|
||||
|
@ -94,11 +101,12 @@ namespace pCampBot
|
|||
}
|
||||
|
||||
int botcount = commandLineConfig.GetInt("botcount", 1);
|
||||
bool startConnected = commandLineConfig.Get("connect") != null;
|
||||
|
||||
//startup specified number of bots. 1 is the default
|
||||
Thread startBotThread = new Thread(o => bm.dobotStartup(botcount, commandLineConfig));
|
||||
startBotThread.Name = "Initial start bots thread";
|
||||
startBotThread.Start();
|
||||
bm.CreateBots(botcount, commandLineConfig);
|
||||
|
||||
if (startConnected)
|
||||
bm.ConnectBots(botcount);
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -119,6 +127,7 @@ namespace pCampBot
|
|||
//Set up our nifty config.. thanks to nini
|
||||
ArgvConfigSource cs = new ArgvConfigSource(args);
|
||||
|
||||
cs.AddSwitch("Startup", "connect", "c");
|
||||
cs.AddSwitch("Startup", "botcount", "n");
|
||||
cs.AddSwitch("Startup", "from", "f");
|
||||
cs.AddSwitch("Startup", "loginuri", "l");
|
||||
|
@ -145,20 +154,21 @@ namespace pCampBot
|
|||
"usage: pCampBot <-loginuri loginuri> [OPTIONS]\n"
|
||||
+ "Spawns a set of bots to test an OpenSim region\n\n"
|
||||
+ " -l, -loginuri loginuri for grid/standalone (required)\n"
|
||||
+ " -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"
|
||||
+ " -firstname first name for the bots\n"
|
||||
+ " -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n"
|
||||
+ " -password password for the bots\n"
|
||||
+ " -n, -botcount optional number of bots to start (default: 1)\n"
|
||||
+ " -f, -from optional starting number for login bot names, e.g. 25 will login Ima Bot_25, Ima Bot_26, etc. (default: 0)"
|
||||
+ " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n"
|
||||
+ " -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"
|
||||
+ " -firstname first name for the bots (required)\n"
|
||||
+ " -lastname lastname for the bots (required). Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n"
|
||||
+ " -password password for the bots (required)\n"
|
||||
+ " -n, -botcount number of bots to start (default: 1) (optional)\n"
|
||||
+ " -f, -from starting number for login bot names, e.g. 25 will login Ima Bot_25, Ima Bot_26, etc. (default: 0) (optional)\n"
|
||||
+ " -c, -connect connect all bots at startup (optional)\n"
|
||||
+ " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p (required)\n"
|
||||
+ " current options are:\n"
|
||||
+ " p (physics - bots constantly move and jump around)\n"
|
||||
+ " g (grab - bots randomly click prims whether set clickable or not)\n"
|
||||
+ " n (none - bots do nothing)\n"
|
||||
+ " t (teleport - bots regularly teleport between regions on the grid)\n"
|
||||
// " c (cross)" +
|
||||
+ " -wear optional folder from which to load appearance data, \"no\" if there is no such folder (default: no)\n"
|
||||
// " c (cross)\n" +
|
||||
+ " -wear folder from which to load appearance data, \"no\" if there is no such folder (default: no) (optional)\n"
|
||||
+ " -h, -help show this message.\n");
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,6 +1,10 @@
|
|||
; This is the example config file for pCampbot
|
||||
; To use it, copy this file to pCampbot.ini and change settings if required
|
||||
|
||||
[BotManager]
|
||||
; Number of milliseconds to wait between bot logins
|
||||
LoginDelay = 5000
|
||||
|
||||
[Bot]
|
||||
; Control whether bots should regularly send agent updates
|
||||
; Not doing this will reduce CPU requirements for pCampbot but greatly
|
Loading…
Reference in New Issue