Merge branch 'master' into bigmerge

Conflicts:
	OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
avinationmerge
Melanie 2011-11-28 11:06:38 +00:00
commit dc612d0f08
31 changed files with 706 additions and 455 deletions

View File

@ -98,14 +98,17 @@ namespace OpenSim.Framework.Capabilities
{ {
get { return m_httpListener.UseSSL; } get { return m_httpListener.UseSSL; }
} }
public string SSLCommonName public string SSLCommonName
{ {
get { return m_httpListener.SSLCommonName; } get { return m_httpListener.SSLCommonName; }
} }
public CapsHandlers CapsHandlers public CapsHandlers CapsHandlers
{ {
get { return m_capsHandlers; } get { return m_capsHandlers; }
} }
public Dictionary<string, string> ExternalCapsHandlers public Dictionary<string, string> ExternalCapsHandlers
{ {
get { return m_externalCapsHandlers; } get { return m_externalCapsHandlers; }
@ -157,11 +160,7 @@ namespace OpenSim.Framework.Capabilities
/// <summary> /// <summary>
/// Remove all CAPS service handlers. /// Remove all CAPS service handlers.
///
/// </summary> /// </summary>
/// <param name="httpListener"></param>
/// <param name="path"></param>
/// <param name="restMethod"></param>
public void DeregisterHandlers() public void DeregisterHandlers()
{ {
if (m_capsHandlers != null) if (m_capsHandlers != null)

View File

@ -42,7 +42,6 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers namespace OpenSim.Capabilities.Handlers
{ {
public class WebFetchInvDescHandler public class WebFetchInvDescHandler
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
@ -50,7 +49,7 @@ namespace OpenSim.Capabilities.Handlers
private IInventoryService m_InventoryService; private IInventoryService m_InventoryService;
private ILibraryService m_LibraryService; private ILibraryService m_LibraryService;
private object m_fetchLock = new Object(); // private object m_fetchLock = new Object();
public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService) public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService)
{ {
@ -60,6 +59,10 @@ namespace OpenSim.Capabilities.Handlers
public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{ {
// lock (m_fetchLock)
// {
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request);
// nasty temporary hack here, the linden client falsely // nasty temporary hack here, the linden client falsely
// identifies the uuid 00000000-0000-0000-0000-000000000000 // identifies the uuid 00000000-0000-0000-0000-000000000000
// as a string which breaks us // as a string which breaks us
@ -80,17 +83,16 @@ namespace OpenSim.Capabilities.Handlers
{ {
hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
} }
catch (LLSD.LLSDParseException pe) catch (LLSD.LLSDParseException e)
{ {
m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
m_log.Error("Request: " + request.ToString()); m_log.Error("Request: " + request);
} }
ArrayList foldersrequested = (ArrayList)hash["folders"]; ArrayList foldersrequested = (ArrayList)hash["folders"];
string response = ""; string response = "";
lock (m_fetchLock)
{
for (int i = 0; i < foldersrequested.Count; i++) for (int i = 0; i < foldersrequested.Count; i++)
{ {
string inventoryitemstr = ""; string inventoryitemstr = "";
@ -104,7 +106,7 @@ namespace OpenSim.Capabilities.Handlers
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
} }
LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
@ -115,7 +117,6 @@ namespace OpenSim.Capabilities.Handlers
response += inventoryitemstr; response += inventoryitemstr;
} }
if (response.Length == 0) if (response.Length == 0)
{ {
// Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
@ -129,11 +130,12 @@ namespace OpenSim.Capabilities.Handlers
response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
} }
//m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
//m_log.Debug("[CAPS] "+response); //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
}
return response; return response;
// }
} }
/// <summary> /// <summary>
@ -155,7 +157,10 @@ namespace OpenSim.Capabilities.Handlers
inv.Items = new List<InventoryItemBase>(); inv.Items = new List<InventoryItemBase>();
int version = 0; int version = 0;
inv = Fetch(invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); inv
= Fetch(
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
if (inv.Folders != null) if (inv.Folders != null)
{ {
@ -179,16 +184,31 @@ namespace OpenSim.Capabilities.Handlers
return reply; return reply;
} }
public InventoryCollection Fetch(UUID agentID, UUID folderID, UUID ownerID, /// <summary>
/// Handle the caps inventory descendents fetch.
/// </summary>
/// <param name="agentID"></param>
/// <param name="folderID"></param>
/// <param name="ownerID"></param>
/// <param name="fetchFolders"></param>
/// <param name="fetchItems"></param>
/// <param name="sortOrder"></param>
/// <param name="version"></param>
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
public InventoryCollection Fetch(
UUID agentID, UUID folderID, UUID ownerID,
bool fetchFolders, bool fetchItems, int sortOrder, out int version) bool fetchFolders, bool fetchItems, int sortOrder, out int version)
{ {
m_log.DebugFormat( // m_log.DebugFormat(
"[WEBFETCHINVENTORYDESCENDANTS]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", // "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
fetchFolders, fetchItems, folderID, agentID); // fetchFolders, fetchItems, folderID, agentID);
// FIXME MAYBE: We're not handling sortOrder!
version = 0; version = 0;
InventoryFolderImpl fold; InventoryFolderImpl fold;
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner) if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
{
if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
{ {
InventoryCollection ret = new InventoryCollection(); InventoryCollection ret = new InventoryCollection();
@ -197,6 +217,7 @@ namespace OpenSim.Capabilities.Handlers
return ret; return ret;
} }
}
InventoryCollection contents = new InventoryCollection(); InventoryCollection contents = new InventoryCollection();
@ -212,7 +233,7 @@ namespace OpenSim.Capabilities.Handlers
} }
else else
{ {
// Lost itemsm don't really need a version // Lost items don't really need a version
version = 1; version = 1;
} }
@ -230,10 +251,11 @@ namespace OpenSim.Capabilities.Handlers
llsdFolder.folder_id = invFolder.ID; llsdFolder.folder_id = invFolder.ID;
llsdFolder.parent_id = invFolder.ParentID; llsdFolder.parent_id = invFolder.ParentID;
llsdFolder.name = invFolder.Name; llsdFolder.name = invFolder.Name;
if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length)
if (invFolder.Type == (short)AssetType.Unknown || !Enum.IsDefined(typeof(AssetType), (sbyte)invFolder.Type))
llsdFolder.type = "-1"; llsdFolder.type = "-1";
else else
llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; llsdFolder.type = Utils.AssetTypeToString((AssetType)invFolder.Type);
llsdFolder.preferred_type = "-1"; llsdFolder.preferred_type = "-1";
return llsdFolder; return llsdFolder;
@ -254,16 +276,19 @@ namespace OpenSim.Capabilities.Handlers
llsdItem.item_id = invItem.ID; llsdItem.item_id = invItem.ID;
llsdItem.name = invItem.Name; llsdItem.name = invItem.Name;
llsdItem.parent_id = invItem.Folder; llsdItem.parent_id = invItem.Folder;
try try
{ {
// TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType);
llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType);
llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType];
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[CAPS]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}", invItem.AssetType, invItem.InvType, invItem.Name, e.Message); m_log.ErrorFormat(
"[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}",
invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
} }
llsdItem.permissions = new LLSDPermissions(); llsdItem.permissions = new LLSDPermissions();
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
@ -294,6 +319,5 @@ namespace OpenSim.Capabilities.Handlers
return llsdItem; return llsdItem;
} }
} }
} }

View File

@ -565,7 +565,7 @@ namespace OpenSim.Framework.Console
/// </summary> /// </summary>
public class CommandConsole : ConsoleBase, ICommandConsole public class CommandConsole : ConsoleBase, ICommandConsole
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public ICommands Commands { get; private set; } public ICommands Commands { get; private set; }

View File

@ -40,63 +40,6 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
private const uint FULL_MASK_PERMISSIONS_GENERAL = 2147483647; private const uint FULL_MASK_PERMISSIONS_GENERAL = 2147483647;
/// <summary>
/// Inventory types
/// </summary>
public static string[] InvTypes = new string[]
{
"texture",
"sound",
"calling_card",
"landmark",
String.Empty,
String.Empty,
"object",
"notecard",
String.Empty,
String.Empty,
"lsl_text",
String.Empty,
String.Empty,
"bodypart",
String.Empty,
"snapshot",
String.Empty,
String.Empty,
"wearable",
"animation",
"gesture"
};
/// <summary>
/// Asset types
/// </summary>
public static string[] Types = new string[]
{
"texture",
"sound",
"callcard",
"landmark",
"clothing", // Deprecated
"clothing",
"object",
"notecard",
"category",
"root",
"lsltext",
"lslbyte",
"txtr_tga",
"bodypart",
"trash",
"snapshot",
"lstndfnd",
"snd_wav",
"img_tga",
"jpeg",
"animatn",
"gesture"
};
private UUID _assetID = UUID.Zero; private UUID _assetID = UUID.Zero;
private uint _baseMask = FULL_MASK_PERMISSIONS_GENERAL; private uint _baseMask = FULL_MASK_PERMISSIONS_GENERAL;

View File

@ -295,7 +295,7 @@ namespace OpenSim.Framework
return result; return result;
} }
} }
catch (Exception e) catch
{ {
// don't need to treat this as an error... we're just guessing anyway // don't need to treat this as an error... we're just guessing anyway
// m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message); // m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message);

View File

@ -134,7 +134,6 @@ namespace OpenSim.Region.ClientStack.Linden
AddNewInventoryItem = m_Scene.AddUploadedInventoryItem; AddNewInventoryItem = m_Scene.AddUploadedInventoryItem;
ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset; ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
GetClient = m_Scene.SceneGraph.GetControllingClient; GetClient = m_Scene.SceneGraph.GetControllingClient;
} }

View File

@ -39,6 +39,7 @@ using OpenMetaverse.Messages.Linden;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
@ -58,9 +59,15 @@ namespace OpenSim.Region.ClientStack.Linden
public class EventQueueGetModule : IEventQueue, IRegionModule public class EventQueueGetModule : IEventQueue, IRegionModule
{ {
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 = null;
/// <value>
/// Debug level.
/// </value>
public int DebugLevel { get; set; }
protected Scene m_scene;
private IConfigSource m_gConfig; private IConfigSource m_gConfig;
bool enabledYN = false; bool enabledYN;
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
@ -97,6 +104,15 @@ namespace OpenSim.Region.ClientStack.Linden
scene.EventManager.OnClientClosed += ClientClosed; scene.EventManager.OnClientClosed += ClientClosed;
scene.EventManager.OnMakeChildAgent += MakeChildAgent; scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnRegisterCaps += OnRegisterCaps; scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand(
"event queue",
false,
"debug eq",
"debug eq [0|1]",
"debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n"
+ "debug eq 1 will turn off event queue debugging.",
HandleDebugEq);
} }
else else
{ {
@ -128,6 +144,22 @@ namespace OpenSim.Region.ClientStack.Linden
} }
#endregion #endregion
protected void HandleDebugEq(string module, string[] args)
{
int debugLevel;
if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
{
MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]");
}
else
{
DebugLevel = debugLevel;
MainConsole.Instance.OutputFormat(
"Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName);
}
}
/// <summary> /// <summary>
/// Always returns a valid queue /// Always returns a valid queue
/// </summary> /// </summary>
@ -314,16 +346,22 @@ namespace OpenSim.Region.ClientStack.Linden
} }
// Register this as a caps handler // Register this as a caps handler
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
// really it should be possible to directly register the poll handler as a capability.
caps.RegisterHandler("EventQueueGet", caps.RegisterHandler("EventQueueGet",
new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
delegate(Hashtable m_dhttpMethod) // delegate(Hashtable m_dhttpMethod)
{ // {
return ProcessQueue(m_dhttpMethod, agentID, caps); // return ProcessQueue(m_dhttpMethod, agentID, caps);
})); // }));
// This will persist this beyond the expiry of the caps handlers // This will persist this beyond the expiry of the caps handlers
MainServer.Instance.AddPollServiceHTTPHandler( MainServer.Instance.AddPollServiceHTTPHandler(
capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); capsBase + EventQueueGetUUID.ToString() + "/",
EventQueuePoll,
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
Random rnd = new Random(Environment.TickCount); Random rnd = new Random(Environment.TickCount);
lock (m_ids) lock (m_ids)
@ -348,6 +386,8 @@ namespace OpenSim.Region.ClientStack.Linden
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
{ {
// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId);
Queue<OSD> queue = TryGetQueue(pAgentId); Queue<OSD> queue = TryGetQueue(pAgentId);
OSD element; OSD element;
lock (queue) lock (queue)
@ -370,12 +410,31 @@ namespace OpenSim.Region.ClientStack.Linden
} }
else else
{ {
if (DebugLevel > 0 && element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
array.Add(element); array.Add(element);
lock (queue) lock (queue)
{ {
while (queue.Count > 0) while (queue.Count > 0)
{ {
array.Add(queue.Dequeue()); element = queue.Dequeue();
if (DebugLevel > 0 && element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
array.Add(element);
thisID++; thisID++;
} }
} }
@ -412,148 +471,166 @@ namespace OpenSim.Region.ClientStack.Linden
return responsedata; return responsedata;
} }
public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps) // public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
{
// TODO: this has to be redone to not busy-wait (and block the thread),
// TODO: as soon as we have a non-blocking way to handle HTTP-requests.
// if (m_log.IsDebugEnabled)
// { // {
// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ "; // // TODO: this has to be redone to not busy-wait (and block the thread),
// foreach (object key in request.Keys) // // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
//
//// if (m_log.IsDebugEnabled)
//// {
//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
//// foreach (object key in request.Keys)
//// {
//// debug += key.ToString() + "=" + request[key].ToString() + " ";
//// }
//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
//// }
//
// Queue<OSD> queue = TryGetQueue(agentID);
// OSD element;
//
// lock (queue)
// element = queue.Dequeue(); // 15s timeout
//
// Hashtable responsedata = new Hashtable();
//
// int thisID = 0;
// lock (m_ids)
// thisID = m_ids[agentID];
//
// if (element == null)
// { // {
// debug += key.ToString() + "=" + request[key].ToString() + " "; // //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
// if (thisID == -1) // close-request
// {
// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
// responsedata["int_response_code"] = 404; //501; //410; //404;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Closed EQG";
// return responsedata;
// } // }
// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name); // responsedata["int_response_code"] = 502;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Upstream error: ";
// responsedata["error_status_text"] = "Upstream error:";
// responsedata["http_protocol_version"] = "HTTP/1.0";
// return responsedata;
// }
//
// OSDArray array = new OSDArray();
// if (element == null) // didn't have an event in 15s
// {
// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
// array.Add(EventQueueHelper.KeepAliveEvent());
// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
// }
// else
// {
// array.Add(element);
//
// if (element is OSDMap)
// {
// OSDMap ev = (OSDMap)element;
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
// ev["message"], m_scene.GetScenePresence(agentID).Name);
// }
//
// lock (queue)
// {
// while (queue.Count > 0)
// {
// element = queue.Dequeue();
//
// if (element is OSDMap)
// {
// OSDMap ev = (OSDMap)element;
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
// ev["message"], m_scene.GetScenePresence(agentID).Name);
// }
//
// array.Add(element);
// thisID++;
// }
// }
// }
//
// OSDMap events = new OSDMap();
// events.Add("events", array);
//
// events.Add("id", new OSDInteger(thisID));
// lock (m_ids)
// {
// m_ids[agentID] = thisID + 1;
// }
//
// responsedata["int_response_code"] = 200;
// responsedata["content_type"] = "application/xml";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
//
// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
//
// return responsedata;
// } // }
Queue<OSD> queue = TryGetQueue(agentID);
OSD element;
lock (queue)
element = queue.Dequeue(); // 15s timeout
Hashtable responsedata = new Hashtable();
int thisID = 0;
lock (m_ids)
thisID = m_ids[agentID];
if (element == null)
{
//m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
if (thisID == -1) // close-request
{
m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Closed EQG";
return responsedata;
}
responsedata["int_response_code"] = 502;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Upstream error: ";
responsedata["error_status_text"] = "Upstream error:";
responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata;
}
OSDArray array = new OSDArray();
if (element == null) // didn't have an event in 15s
{
// Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
array.Add(EventQueueHelper.KeepAliveEvent());
//m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
}
else
{
array.Add(element);
lock (queue)
{
while (queue.Count > 0)
{
array.Add(queue.Dequeue());
thisID++;
}
}
}
OSDMap events = new OSDMap();
events.Add("events", array);
events.Add("id", new OSDInteger(thisID));
lock (m_ids)
{
m_ids[agentID] = thisID + 1;
}
responsedata["int_response_code"] = 200;
responsedata["content_type"] = "application/xml";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
return responsedata;
}
public Hashtable EventQueuePoll(Hashtable request) public Hashtable EventQueuePoll(Hashtable request)
{ {
return new Hashtable(); return new Hashtable();
} }
public Hashtable EventQueuePath2(Hashtable request) // public Hashtable EventQueuePath2(Hashtable request)
{ // {
string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/",""); // string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
// pull off the last "/" in the path. // // pull off the last "/" in the path.
Hashtable responsedata = new Hashtable(); // Hashtable responsedata = new Hashtable();
capuuid = capuuid.Substring(0, capuuid.Length - 1); // capuuid = capuuid.Substring(0, capuuid.Length - 1);
capuuid = capuuid.Replace("/CAPS/EQG/", ""); // capuuid = capuuid.Replace("/CAPS/EQG/", "");
UUID AvatarID = UUID.Zero; // UUID AvatarID = UUID.Zero;
UUID capUUID = UUID.Zero; // UUID capUUID = UUID.Zero;
//
// parse the path and search for the avatar with it registered // // parse the path and search for the avatar with it registered
if (UUID.TryParse(capuuid, out capUUID)) // if (UUID.TryParse(capuuid, out capUUID))
{ // {
lock (m_QueueUUIDAvatarMapping) // lock (m_QueueUUIDAvatarMapping)
{ // {
if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID)) // if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
{ // {
AvatarID = m_QueueUUIDAvatarMapping[capUUID]; // AvatarID = m_QueueUUIDAvatarMapping[capUUID];
} // }
} // }
//
if (AvatarID != UUID.Zero) // if (AvatarID != UUID.Zero)
{ // {
return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID)); // return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
} // }
else // else
{ // {
responsedata["int_response_code"] = 404; // responsedata["int_response_code"] = 404;
responsedata["content_type"] = "text/plain"; // responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false; // responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Not Found"; // responsedata["str_response_string"] = "Not Found";
responsedata["error_status_text"] = "Not Found"; // responsedata["error_status_text"] = "Not Found";
responsedata["http_protocol_version"] = "HTTP/1.0"; // responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata; // return responsedata;
// return 404 // // return 404
} // }
} // }
else // else
{ // {
responsedata["int_response_code"] = 404; // responsedata["int_response_code"] = 404;
responsedata["content_type"] = "text/plain"; // responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false; // responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Not Found"; // responsedata["str_response_string"] = "Not Found";
responsedata["error_status_text"] = "Not Found"; // responsedata["error_status_text"] = "Not Found";
responsedata["http_protocol_version"] = "HTTP/1.0"; // responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata; // return responsedata;
// return 404 // // return 404
} // }
// }
}
public OSD EventQueueFallBack(string path, OSD request, string endpoint) public OSD EventQueueFallBack(string path, OSD request, string endpoint)
{ {
@ -717,6 +794,7 @@ namespace OpenSim.Region.ClientStack.Linden
OSD item = EventQueueHelper.GroupMembership(groupUpdate); OSD item = EventQueueHelper.GroupMembership(groupUpdate);
Enqueue(item, avatarID); Enqueue(item, avatarID);
} }
public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID) public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
{ {
OSD item = EventQueueHelper.PlacesQuery(groupUpdate); OSD item = EventQueueHelper.PlacesQuery(groupUpdate);

View File

@ -42,18 +42,25 @@ using OpenSim.Capabilities.Handlers;
namespace OpenSim.Region.ClientStack.Linden namespace OpenSim.Region.ClientStack.Linden
{ {
/// <summary>
/// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class WebFetchInvDescModule : INonSharedRegionModule public class WebFetchInvDescModule : INonSharedRegionModule
{ {
private static readonly ILog m_log = // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene; private Scene m_scene;
private IInventoryService m_InventoryService; private IInventoryService m_InventoryService;
private ILibraryService m_LibraryService; private ILibraryService m_LibraryService;
private bool m_Enabled = false;
private string m_URL; private bool m_Enabled;
private string m_fetchInventoryDescendents2Url;
private string m_webFetchInventoryDescendentsUrl;
private WebFetchInvDescHandler m_webFetchHandler;
#region ISharedRegionModule Members #region ISharedRegionModule Members
@ -63,11 +70,14 @@ namespace OpenSim.Region.ClientStack.Linden
if (config == null) if (config == null)
return; return;
m_URL = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty); m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
// Cap doesn't exist m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
if (m_URL != string.Empty)
if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
{
m_Enabled = true; m_Enabled = true;
} }
}
public void AddRegion(Scene s) public void AddRegion(Scene s)
{ {
@ -91,8 +101,13 @@ namespace OpenSim.Region.ClientStack.Linden
if (!m_Enabled) if (!m_Enabled)
return; return;
m_InventoryService = m_scene.InventoryService; ; m_InventoryService = m_scene.InventoryService;
m_LibraryService = m_scene.LibraryService; m_LibraryService = m_scene.LibraryService;
// We'll reuse the same handler for all requests.
if (m_fetchInventoryDescendents2Url == "localhost" || m_webFetchInventoryDescendentsUrl == "localhost")
m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
m_scene.EventManager.OnRegisterCaps += RegisterCaps; m_scene.EventManager.OnRegisterCaps += RegisterCaps;
} }
@ -111,24 +126,38 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion #endregion
public void RegisterCaps(UUID agentID, Caps caps) private void RegisterCaps(UUID agentID, Caps caps)
{ {
UUID capID = UUID.Random(); if (m_webFetchInventoryDescendentsUrl != "")
RegisterFetchCap(agentID, caps, "WebFetchInventoryDescendents", m_webFetchInventoryDescendentsUrl);
//caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); if (m_fetchInventoryDescendents2Url != "")
if (m_URL == "localhost") RegisterFetchCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
}
private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url)
{ {
m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); string capUrl;
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), webFetchHandler.FetchInventoryDescendentsRequest); if (url == "localhost")
caps.RegisterHandler("WebFetchInventoryDescendents", reqHandler); {
capUrl = "/CAPS/" + UUID.Random();
IRequestHandler reqHandler
= new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest);
caps.RegisterHandler(capName, reqHandler);
} }
else else
{ {
m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); capUrl = url;
caps.RegisterHandler("WebFetchInventoryDescendents", m_URL);
} caps.RegisterHandler(capName, capUrl);
} }
// m_log.DebugFormat(
// "[WEB FETCH INV DESC MODULE]: Registered capability {0} at {1} in region {2} for {3}",
// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
}
} }
} }

View File

@ -11730,7 +11730,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
logPacket = false; logPacket = false;
if (logPacket) if (logPacket)
m_log.DebugFormat("[CLIENT]: Packet OUT {0} to {1}", packet.Type, Name); m_log.DebugFormat(
"[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}",
Name, ChildAgentStatus() ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
} }
m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
@ -11773,19 +11775,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (DebugPacketLevel > 0) if (DebugPacketLevel > 0)
{ {
bool outputPacket = true; bool logPacket = true;
if (DebugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate) if (DebugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
outputPacket = false; logPacket = false;
if (DebugPacketLevel <= 200 && packet.Type == PacketType.RequestImage) if (DebugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
outputPacket = false; logPacket = false;
if (DebugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation)) if (DebugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
outputPacket = false; logPacket = false;
if (outputPacket) if (logPacket)
m_log.DebugFormat("[CLIENT]: Packet IN {0} from {1}", packet.Type, Name); m_log.DebugFormat(
"[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}",
Name, ChildAgentStatus() ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
} }
if (!ProcessPacketMethod(packet)) if (!ProcessPacketMethod(packet))

View File

@ -92,7 +92,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
return; return;
} }
m_log.DebugFormat("MAP NAME=({0})", mapName); //m_log.DebugFormat("MAP NAME=({0})", mapName);
// try to fetch from GridServer // try to fetch from GridServer
List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);

View File

@ -487,6 +487,7 @@ namespace OpenSim.Region.Framework.Scenes
// can be handled transparently). // can be handled transparently).
InventoryFolderImpl fold = null; InventoryFolderImpl fold = null;
if (LibraryService != null && LibraryService.LibraryRootFolder != null) if (LibraryService != null && LibraryService.LibraryRootFolder != null)
{
if ((fold = LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) if ((fold = LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
{ {
remoteClient.SendInventoryFolderDetails( remoteClient.SendInventoryFolderDetails(
@ -494,6 +495,7 @@ namespace OpenSim.Region.Framework.Scenes
fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems); fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems);
return; return;
} }
}
// We're going to send the reply async, because there may be // We're going to send the reply async, because there may be
// an enormous quantity of packets -- basically the entire inventory! // an enormous quantity of packets -- basically the entire inventory!
@ -515,64 +517,6 @@ namespace OpenSim.Region.Framework.Scenes
d.EndInvoke(iar); d.EndInvoke(iar);
} }
/// <summary>
/// Handle the caps inventory descendents fetch.
///
/// Since the folder structure is sent to the client on login, I believe we only need to handle items.
/// Diva comment 8/13/2009: what if someone gave us a folder in the meantime??
/// </summary>
/// <param name="agentID"></param>
/// <param name="folderID"></param>
/// <param name="ownerID"></param>
/// <param name="fetchFolders"></param>
/// <param name="fetchItems"></param>
/// <param name="sortOrder"></param>
/// <returns>null if the inventory look up failed</returns>
public InventoryCollection HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
bool fetchFolders, bool fetchItems, int sortOrder, out int version)
{
m_log.DebugFormat(
"[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
fetchFolders, fetchItems, folderID, agentID);
// FIXME MAYBE: We're not handling sortOrder!
// TODO: This code for looking in the folder for the library should be folded back into the
// CachedUserInfo so that this class doesn't have to know the details (and so that multiple libraries, etc.
// can be handled transparently).
InventoryFolderImpl fold;
if (LibraryService != null && LibraryService.LibraryRootFolder != null)
if ((fold = LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
{
version = 0;
InventoryCollection ret = new InventoryCollection();
ret.Folders = new List<InventoryFolderBase>();
ret.Items = fold.RequestListOfItems();
return ret;
}
InventoryCollection contents = new InventoryCollection();
if (folderID != UUID.Zero)
{
contents = InventoryService.GetFolderContent(agentID, folderID);
InventoryFolderBase containingFolder = new InventoryFolderBase();
containingFolder.ID = folderID;
containingFolder.Owner = agentID;
containingFolder = InventoryService.GetFolder(containingFolder);
version = containingFolder.Version;
}
else
{
// Lost itemsm don't really need a version
version = 1;
}
return contents;
}
/// <summary> /// <summary>
/// Handle an inventory folder creation request from the client. /// Handle an inventory folder creation request from the client.
/// </summary> /// </summary>
@ -646,14 +590,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
delegate void PurgeFolderDelegate(UUID userID, UUID folder);
/// <summary> /// <summary>
/// This should delete all the items and folders in the given directory. /// This should delete all the items and folders in the given directory.
/// </summary> /// </summary>
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
/// <param name="folderID"></param> /// <param name="folderID"></param>
delegate void PurgeFolderDelegate(UUID userID, UUID folder);
public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID) public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID)
{ {
PurgeFolderDelegate d = PurgeFolderAsync; PurgeFolderDelegate d = PurgeFolderAsync;
@ -667,7 +610,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
private void PurgeFolderAsync(UUID userID, UUID folderID) private void PurgeFolderAsync(UUID userID, UUID folderID)
{ {
InventoryFolderBase folder = new InventoryFolderBase(folderID, userID); InventoryFolderBase folder = new InventoryFolderBase(folderID, userID);

View File

@ -4834,9 +4834,6 @@ namespace OpenSim.Region.Framework.Scenes
public Vector3? GetNearestAllowedPosition(ScenePresence avatar) public Vector3? GetNearestAllowedPosition(ScenePresence avatar)
{ {
//simulate to make sure we have pretty up to date positions
PhysicsScene.Simulate(0);
ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
if (nearestParcel != null) if (nearestParcel != null)
@ -4863,12 +4860,13 @@ namespace OpenSim.Region.Framework.Scenes
//Ultimate backup if we have no idea where they are //Ultimate backup if we have no idea where they are
Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString()); Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString());
return avatar.lastKnownAllowedPosition; return avatar.lastKnownAllowedPosition;
} }
//Go to the edge, this happens in teleporting to a region with no available parcels //Go to the edge, this happens in teleporting to a region with no available parcels
Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar);
//Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString());
return nearestRegionEdgePoint; return nearestRegionEdgePoint;
} }

View File

@ -448,29 +448,25 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// Set the debug packet level on the current scene. This level governs which packets are printed out to the /// Set the debug packet level on each current scene. This level governs which packets are printed out to the
/// console. /// console.
/// </summary> /// </summary>
/// <param name="newDebug"></param> /// <param name="newDebug"></param>
/// <param name="name">Name of avatar to debug</param> /// <param name="name">Name of avatar to debug</param>
public void SetDebugPacketLevelOnCurrentScene(int newDebug, string name) public void SetDebugPacketLevelOnCurrentScene(int newDebug, string name)
{ {
ForEachCurrentScene( ForEachCurrentScene(scene =>
delegate(Scene scene) scene.ForEachScenePresence(sp =>
{ {
scene.ForEachRootClient(delegate(IClientAPI client) if (name == null || sp.Name == name)
{ {
if (name == null || client.Name == name) m_log.DebugFormat(
{ "Packet debug for {0} ({1}) set to {2}",
m_log.DebugFormat("Packet debug for {0} {1} set to {2}", sp.Name, sp.IsChildAgent ? "child" : "root", newDebug);
client.FirstName,
client.LastName,
newDebug);
client.DebugPacketLevel = newDebug; sp.ControllingClient.DebugPacketLevel = newDebug;
}
});
} }
})
); );
} }

View File

@ -1085,8 +1085,8 @@ namespace OpenSim.Region.Framework.Scenes
invString.AddNameValueLine("asset_id", item.AssetID.ToString()); invString.AddNameValueLine("asset_id", item.AssetID.ToString());
else else
invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
invString.AddSaleStart(); invString.AddSaleStart();

View File

@ -56,7 +56,7 @@ namespace OpenSim.Region.Physics.Manager
public abstract class PhysicsScene public abstract class PhysicsScene
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
/// Name of this scene. Useful in debug messages to distinguish one OdeScene instance from another. /// Name of this scene. Useful in debug messages to distinguish one OdeScene instance from another.

View File

@ -86,7 +86,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private float CAPSULE_RADIUS = 0.37f; private float CAPSULE_RADIUS = 0.37f;
private float CAPSULE_LENGTH = 2.140599f; private float CAPSULE_LENGTH = 2.140599f;
private float m_tensor = 3800000f; private float m_tensor = 3800000f;
private float heightFudgeFactor = 0.52f; // private float heightFudgeFactor = 0.52f;
private float walkDivisor = 1.3f; private float walkDivisor = 1.3f;
private float runDivisor = 0.8f; private float runDivisor = 0.8f;
private bool flying = false; private bool flying = false;
@ -149,7 +149,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public OdeCharacter( public OdeCharacter(
String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p,
float capsule_radius, float tensor, float density, float height_fudge_factor, float capsule_radius, float tensor, float density,
float walk_divisor, float rundivisor) float walk_divisor, float rundivisor)
{ {
m_uuid = UUID.Random(); m_uuid = UUID.Random();
@ -187,7 +187,7 @@ namespace OpenSim.Region.Physics.OdePlugin
CAPSULE_RADIUS = capsule_radius; CAPSULE_RADIUS = capsule_radius;
m_tensor = tensor; m_tensor = tensor;
m_density = density; m_density = density;
heightFudgeFactor = height_fudge_factor; // heightFudgeFactor = height_fudge_factor;
walkDivisor = walk_divisor; walkDivisor = walk_divisor;
runDivisor = rundivisor; runDivisor = rundivisor;

View File

@ -156,7 +156,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool avCapsuleTilted = true; // true = old compatibility mode with leaning capsule; false = new corrected mode private bool avCapsuleTilted = true; // true = old compatibility mode with leaning capsule; false = new corrected mode
public bool IsAvCapsuleTilted { get { return avCapsuleTilted; } set { avCapsuleTilted = value; } } public bool IsAvCapsuleTilted { get { return avCapsuleTilted; } set { avCapsuleTilted = value; } }
private float avDensity = 80f; private float avDensity = 80f;
private float avHeightFudgeFactor = 0.52f; // private float avHeightFudgeFactor = 0.52f;
private float avMovementDivisorWalk = 1.3f; private float avMovementDivisorWalk = 1.3f;
private float avMovementDivisorRun = 0.8f; private float avMovementDivisorRun = 0.8f;
private float minimumGroundFlightOffset = 3f; private float minimumGroundFlightOffset = 3f;
@ -316,7 +316,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private int m_physicsiterations = 10; private int m_physicsiterations = 10;
private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag
private readonly PhysicsActor PANull = new NullPhysicsActor(); private readonly PhysicsActor PANull = new NullPhysicsActor();
private float step_time = 0.0f; // private float step_time = 0.0f;
//Ckrinke: Comment out until used. We declare it, initialize it, but do not use it //Ckrinke: Comment out until used. We declare it, initialize it, but do not use it
//Ckrinke private int ms = 0; //Ckrinke private int ms = 0;
public IntPtr world; public IntPtr world;
@ -479,7 +479,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10); m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10);
avDensity = physicsconfig.GetFloat("av_density", 80f); avDensity = physicsconfig.GetFloat("av_density", 80f);
avHeightFudgeFactor = physicsconfig.GetFloat("av_height_fudge_factor", 0.52f); // avHeightFudgeFactor = physicsconfig.GetFloat("av_height_fudge_factor", 0.52f);
avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f);
avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f);
avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
@ -1706,7 +1706,7 @@ namespace OpenSim.Region.Physics.OdePlugin
OdeCharacter newAv OdeCharacter newAv
= new OdeCharacter( = new OdeCharacter(
avName, this, pos, size, avPIDD, avPIDP, avName, this, pos, size, avPIDD, avPIDP,
avCapRadius, avStandupTensor, avDensity, avHeightFudgeFactor, avCapRadius, avStandupTensor, avDensity,
avMovementDivisorWalk, avMovementDivisorRun); avMovementDivisorWalk, avMovementDivisorRun);
newAv.Flying = isFlying; newAv.Flying = isFlying;

View File

@ -8695,6 +8695,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_ROT_LOCAL: case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
break; break;
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
res.Add(new LSL_Vector(GetPartLocalPos(part)));
break;
} }
} }
return res; return res;

View File

@ -140,7 +140,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>(); List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
foreach (SenseRepeatClass ts in SenseRepeaters) foreach (SenseRepeatClass ts in SenseRepeaters)
{ {
if (ts.localID != m_localID && ts.itemID != m_itemID) if (ts.localID != m_localID || ts.itemID != m_itemID)
{ {
NewSensors.Add(ts); NewSensors.Add(ts);
} }

View File

@ -323,6 +323,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int PRIM_DESC = 28; public const int PRIM_DESC = 28;
public const int PRIM_ROT_LOCAL = 29; public const int PRIM_ROT_LOCAL = 29;
public const int PRIM_OMEGA = 32; public const int PRIM_OMEGA = 32;
public const int PRIM_POS_LOCAL = 33;
public const int PRIM_LINK_TARGET = 34; public const int PRIM_LINK_TARGET = 34;
public const int PRIM_TEXGEN_DEFAULT = 0; public const int PRIM_TEXGEN_DEFAULT = 0;
public const int PRIM_TEXGEN_PLANAR = 1; public const int PRIM_TEXGEN_PLANAR = 1;

View File

@ -81,7 +81,7 @@ namespace OpenSim.Services.LLLoginService
protected string m_DeniedClients; protected string m_DeniedClients;
IConfig m_LoginServerConfig; IConfig m_LoginServerConfig;
IConfig m_ClientsConfig; // IConfig m_ClientsConfig;
public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService) public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService)
{ {

View File

@ -0,0 +1,49 @@
/*
* 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 OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Linq;
using pCampBot.Interfaces;
namespace pCampBot
{
public class AbstractBehaviour : IBehaviour
{
public string Name { get; protected set; }
public Bot Bot { get; protected set; }
public virtual void Action() {}
public virtual void Initialize(Bot bot)
{
Bot = bot;
}
}
}

View File

@ -0,0 +1,169 @@
/*
* 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.Reflection;
using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using pCampBot.Interfaces;
namespace pCampBot
{
/// <summary>
/// Get the bot to make a region crossing.
/// </summary>
public class CrossBehaviour : AbstractBehaviour
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public AutoResetEvent m_regionCrossedMutex = new AutoResetEvent(false);
public const int m_regionCrossingTimeout = 1000 * 60;
public CrossBehaviour() { Name = "Cross"; }
public override void Action()
{
GridClient client = Bot.Client;
// // Fly to make the border cross easier.
// client.Self.Movement.Fly = true;
// client.Self.Movement.Fly = false;
// Seek out neighbouring region
Simulator currentSim = client.Network.CurrentSim;
ulong currentHandle = currentSim.Handle;
uint currentX, currentY;
Utils.LongToUInts(currentHandle, out currentX, out currentY);
List<GridRegion> candidateRegions = new List<GridRegion>();
TryAddRegion(Utils.UIntsToLong(Math.Max(0, currentX - Constants.RegionSize), currentY), candidateRegions); // West
TryAddRegion(Utils.UIntsToLong(currentX + Constants.RegionSize, currentY), candidateRegions); // East
TryAddRegion(Utils.UIntsToLong(currentX, Math.Max(0, currentY - Constants.RegionSize)), candidateRegions); // South
TryAddRegion(Utils.UIntsToLong(currentX, currentY + Constants.RegionSize), candidateRegions); // North
if (candidateRegions.Count != 0)
{
GridRegion destRegion = candidateRegions[Bot.Manager.Rng.Next(candidateRegions.Count)];
uint targetX, targetY;
Utils.LongToUInts(destRegion.RegionHandle, out targetX, out targetY);
Vector3 pos = client.Self.SimPosition;
if (targetX < currentX)
pos.X = -1;
else if (targetX > currentX)
pos.X = Constants.RegionSize + 1;
if (targetY < currentY)
pos.Y = -1;
else if (targetY > currentY)
pos.Y = Constants.RegionSize + 1;
m_log.DebugFormat(
"[CROSS BEHAVIOUR]: {0} moving to cross from {1} into {2}, target {3}",
Bot.Name, currentSim.Name, destRegion.Name, pos);
// Face in the direction of the candidate region
client.Self.Movement.TurnToward(pos);
// Listen for event so that we know when we've crossed the region boundary
Bot.Client.Self.RegionCrossed += Self_RegionCrossed;
// Start moving
Bot.Client.Self.Movement.AtPos = true;
// Stop when reach region target or border cross detected
if (!m_regionCrossedMutex.WaitOne(m_regionCrossingTimeout))
{
m_log.ErrorFormat(
"[CROSS BEHAVIOUR]: {0} failed to cross from {1} into {2} with {3}ms",
Bot.Name, currentSim.Name, destRegion.Name, m_regionCrossingTimeout);
}
else
{
m_log.DebugFormat(
"[CROSS BEHAVIOUR]: {0} crossed from {1} into {2}",
Bot.Name, currentSim.Name, destRegion.Name);
}
Bot.Client.Self.RegionCrossed -= Self_RegionCrossed;
// We will hackishly carry on travelling into the region for a little bit.
Thread.Sleep(6000);
m_log.DebugFormat(
"[CROSS BEHAVIOUR]: {0} stopped moving after cross from {1} into {2}",
Bot.Name, currentSim.Name, destRegion.Name);
Bot.Client.Self.Movement.AtPos = false;
}
else
{
m_log.DebugFormat(
"[CROSS BEHAVIOUR]: No candidate region for {0} to cross into from {1}. Ignoring.",
Bot.Name, currentSim.Name);
}
}
private bool TryAddRegion(ulong handle, List<GridRegion> regions)
{
Dictionary<ulong, GridRegion> knownRegions = Bot.Manager.RegionsKnown;
lock (knownRegions)
{
if (knownRegions.Count == 0)
return false;
m_log.DebugFormat("[CROSS BEHAVIOUR]: Looking for region with handle {0} in known regions", handle);
if (knownRegions.ContainsKey(handle))
{
GridRegion region = knownRegions[handle];
m_log.DebugFormat(
"[CROSS BEHAVIOUR]: Adding region {0} to crossing candidates for {1}", region.Name, Bot.Name);
regions.Add(region);
return true;
}
else
{
return false;
}
}
}
internal void Self_RegionCrossed(object o, RegionCrossedEventArgs args)
{
m_regionCrossedMutex.Set();
}
}
}

View File

@ -39,20 +39,20 @@ namespace pCampBot
/// <remarks> /// <remarks>
/// The viewer itself does not give the option of grabbing objects that haven't been signalled as grabbable. /// The viewer itself does not give the option of grabbing objects that haven't been signalled as grabbable.
/// </remarks> /// </remarks>
public class GrabbingBehaviour : IBehaviour public class GrabbingBehaviour : AbstractBehaviour
{ {
public string Name { get { return "Grabbing"; } } public GrabbingBehaviour() { Name = "Grabbing"; }
public void Action(Bot bot) public override void Action()
{ {
Dictionary<UUID, Primitive> objects = bot.Objects; Dictionary<UUID, Primitive> objects = Bot.Objects;
Primitive prim = objects.ElementAt(bot.Random.Next(0, objects.Count)).Value; Primitive prim = objects.ElementAt(Bot.Random.Next(0, objects.Count)).Value;
// This appears to be a typical message sent when a viewer user clicks a clickable object // This appears to be a typical message sent when a viewer user clicks a clickable object
bot.Client.Self.Grab(prim.LocalID); Bot.Client.Self.Grab(prim.LocalID);
bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero); Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero);
bot.Client.Self.DeGrab(prim.LocalID); Bot.Client.Self.DeGrab(prim.LocalID);
} }
} }
} }

View File

@ -40,43 +40,41 @@ namespace pCampBot
/// <remarks> /// <remarks>
/// TODO: talkarray should be in a separate behaviour. /// TODO: talkarray should be in a separate behaviour.
/// </remarks> /// </remarks>
public class PhysicsBehaviour : IBehaviour public class PhysicsBehaviour : AbstractBehaviour
{ {
public string Name { get { return "Physics"; } }
private string[] talkarray; private string[] talkarray;
public PhysicsBehaviour() public PhysicsBehaviour()
{ {
Name = "Physics";
talkarray = readexcuses(); talkarray = readexcuses();
} }
public void Action(Bot bot) public override void Action()
{ {
int walkorrun = bot.Random.Next(4); // Randomize between walking and running. The greater this number, int walkorrun = Bot.Random.Next(4); // Randomize between walking and running. The greater this number,
// the greater the bot's chances to walk instead of run. // the greater the bot's chances to walk instead of run.
bot.Client.Self.Jump(false); Bot.Client.Self.Jump(false);
if (walkorrun == 0) if (walkorrun == 0)
{ {
bot.Client.Self.Movement.AlwaysRun = true; Bot.Client.Self.Movement.AlwaysRun = true;
} }
else else
{ {
bot.Client.Self.Movement.AlwaysRun = false; Bot.Client.Self.Movement.AlwaysRun = false;
} }
// TODO: unused: Vector3 pos = client.Self.SimPosition; // TODO: unused: Vector3 pos = client.Self.SimPosition;
Vector3 newpos = new Vector3(bot.Random.Next(1, 254), bot.Random.Next(1, 254), bot.Random.Next(1, 254)); Vector3 newpos = new Vector3(Bot.Random.Next(1, 254), Bot.Random.Next(1, 254), Bot.Random.Next(1, 254));
bot.Client.Self.Movement.TurnToward(newpos); Bot.Client.Self.Movement.TurnToward(newpos);
bot.Client.Self.Movement.AtPos = true; Bot.Client.Self.Movement.AtPos = true;
Thread.Sleep(bot.Random.Next(3000, 13000)); Thread.Sleep(Bot.Random.Next(3000, 13000));
bot.Client.Self.Movement.AtPos = false; Bot.Client.Self.Movement.AtPos = false;
bot.Client.Self.Jump(true); Bot.Client.Self.Jump(true);
string randomf = talkarray[Bot.Random.Next(talkarray.Length)];
string randomf = talkarray[bot.Random.Next(talkarray.Length)];
if (talkarray.Length > 1 && randomf.Length > 1) if (talkarray.Length > 1 && randomf.Length > 1)
bot.Client.Self.Chat(randomf, 0, ChatType.Normal); Bot.Client.Self.Chat(randomf, 0, ChatType.Normal);
} }
private string[] readexcuses() private string[] readexcuses()

View File

@ -38,38 +38,38 @@ namespace pCampBot
/// <summary> /// <summary>
/// Teleport to a random region on the grid. /// Teleport to a random region on the grid.
/// </summary> /// </summary>
public class TeleportBehaviour : IBehaviour public class TeleportBehaviour : AbstractBehaviour
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public string Name { get { return "Teleport"; } } public TeleportBehaviour() { Name = "Teleport"; }
public void Action(Bot bot) public override void Action()
{ {
Random rng = bot.Manager.Rng; Random rng = Bot.Manager.Rng;
GridRegion[] knownRegions; GridRegion[] knownRegions;
lock (bot.Manager.RegionsKnown) lock (Bot.Manager.RegionsKnown)
{ {
if (bot.Manager.RegionsKnown.Count == 0) if (Bot.Manager.RegionsKnown.Count == 0)
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[TELEPORT BEHAVIOUR]: Ignoring teleport action for {0} since no regions are known yet", bot.Name); "[TELEPORT BEHAVIOUR]: Ignoring teleport action for {0} since no regions are known yet", Bot.Name);
return; return;
} }
knownRegions = bot.Manager.RegionsKnown.Values.ToArray(); knownRegions = Bot.Manager.RegionsKnown.Values.ToArray();
} }
Simulator sourceRegion = bot.Client.Network.CurrentSim; Simulator sourceRegion = Bot.Client.Network.CurrentSim;
GridRegion destRegion = knownRegions[rng.Next(knownRegions.Length)]; GridRegion destRegion = knownRegions[rng.Next(knownRegions.Length)];
Vector3 destPosition = new Vector3(rng.Next(255), rng.Next(255), 50); Vector3 destPosition = new Vector3(rng.Next(255), rng.Next(255), 50);
m_log.DebugFormat( m_log.DebugFormat(
"[TELEPORT BEHAVIOUR]: Teleporting {0} from {1} {2} to {3} {4}", "[TELEPORT BEHAVIOUR]: Teleporting {0} from {1} {2} to {3} {4}",
bot.Name, sourceRegion.Name, bot.Client.Self.SimPosition, destRegion.Name, destPosition); Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition);
bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition); Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition);
} }
} }
} }

View File

@ -130,6 +130,8 @@ namespace pCampBot
BotManager bm, List<IBehaviour> behaviours, BotManager bm, List<IBehaviour> behaviours,
string firstName, string lastName, string password, string loginUri) string firstName, string lastName, string password, string loginUri)
{ {
behaviours.ForEach(b => b.Initialize(this));
Client = new GridClient(); Client = new GridClient();
Random = new Random(Environment.TickCount);// We do stuff randomly here Random = new Random(Environment.TickCount);// We do stuff randomly here
@ -156,7 +158,7 @@ namespace pCampBot
b => b =>
{ {
// m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType());
b.Action(this); b.Action();
Thread.Sleep(Random.Next(1000, 10000)); Thread.Sleep(Random.Next(1000, 10000));
} }
@ -226,8 +228,6 @@ namespace pCampBot
MakeDefaultAppearance(wear); MakeDefaultAppearance(wear);
} }
Client.Self.Jump(true);
// Extract nearby region information. // Extract nearby region information.
Client.Grid.GridRegion += Manager.Grid_GridRegion; Client.Grid.GridRegion += Manager.Grid_GridRegion;
uint xUint, yUint; uint xUint, yUint;

View File

@ -151,6 +151,10 @@ namespace pCampBot
Array.ForEach<string>( Array.ForEach<string>(
cs.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); cs.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b));
for (int i = 0; i < botcount; i++)
{
string lastName = string.Format("{0}_{1}", lastNameStem, i);
List<IBehaviour> behaviours = new List<IBehaviour>(); List<IBehaviour> behaviours = new List<IBehaviour>();
// Hard-coded for now // Hard-coded for now
@ -163,13 +167,12 @@ namespace pCampBot
if (behaviourSwitches.Contains("t")) if (behaviourSwitches.Contains("t"))
behaviours.Add(new TeleportBehaviour()); behaviours.Add(new TeleportBehaviour());
MainConsole.Instance.OutputFormat( if (behaviourSwitches.Contains("c"))
"[BOT MANAGER]: Bots configured for behaviours {0}", behaviours.Add(new CrossBehaviour());
string.Join(",", behaviours.ConvertAll<string>(b => b.Name).ToArray()));
for (int i = 0; i < botcount; i++) MainConsole.Instance.OutputFormat(
{ "[BOT MANAGER]: Bot {0} {1} configured for behaviours {2}",
string lastName = string.Format("{0}_{1}", lastNameStem, i); firstName, lastName, string.Join(",", behaviours.ConvertAll<string>(b => b.Name).ToArray()));
StartBot(this, behaviours, firstName, lastName, password, loginUri); StartBot(this, behaviours, firstName, lastName, password, loginUri);
} }

View File

@ -36,10 +36,19 @@ namespace pCampBot.Interfaces
/// </summary> /// </summary>
string Name { get; } string Name { get; }
/// <summary>
/// Initialize the behaviour for this bot.
/// </summary>
/// <remarks>
/// This must be invoked before Action() is called.
/// </remarks>
/// <param name="bot"></param>
void Initialize(Bot bot);
/// <summary> /// <summary>
/// Action to take when this behaviour is invoked. /// Action to take when this behaviour is invoked.
/// </summary> /// </summary>
/// <param name="bot"></param> /// <param name="bot"></param>
void Action(Bot bot); void Action();
} }
} }

View File

@ -111,10 +111,14 @@ namespace pCampBot
" -firstname first name for the bots\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" + " -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" +
" -password password for the bots\n" + " -password password for the bots\n" +
" -b, behaviours behaviours for bots. Current options p (physics), g (grab), t (teleport). Comma separated, e.g. p,g. Default is p", " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n",
" current options are:" +
" p (physics)" +
" g (grab)" +
" t (teleport)" +
// " c (cross)" +
" -wear set appearance folder to load from (default: no)\n" + " -wear set appearance folder to load from (default: no)\n" +
" -h, -help show this message" " -h, -help show this message");
);
} }
} }
} }

View File

@ -507,8 +507,7 @@
; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps ; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps
; will also be affected. ; will also be affected.
; ;
;DisableFacelights = "false" ;DisableFacelights = "false(1815)
[ClientStack.LindenCaps] [ClientStack.LindenCaps]
;; Long list of capabilities taken from ;; Long list of capabilities taken from
@ -574,10 +573,13 @@
Cap_UploadObjectAsset = "localhost" Cap_UploadObjectAsset = "localhost"
Cap_ViewerStartAuction = "" Cap_ViewerStartAuction = ""
Cap_ViewerStats = "" Cap_ViewerStats = ""
; This last one is supported by OpenSim, but may
; The fetch inventory descendents caps are supported by OpenSim, but may
; lead to poor sim performance if served by the simulators, ; lead to poor sim performance if served by the simulators,
; so it is disabled by default. ; so they are disabled by default.
; FetchInventoryDescendents2 is the one used in the latest Linden Lab viewers (from some point in the v2 series and above)
Cap_WebFetchInventoryDescendents = "" Cap_WebFetchInventoryDescendents = ""
Cap_FetchInventoryDescendents2 = ""
[Chat] [Chat]
@ -722,7 +724,8 @@
av_density = 80 av_density = 80
; use this value to cut 52% of the height the sim gives us ; use this value to cut 52% of the height the sim gives us
av_height_fudge_factor = 0.52 ; Currently unused
; av_height_fudge_factor = 0.52
; Movement. Smaller is faster. ; Movement. Smaller is faster.