ObjectsAvatars and ObjectsPrimitives are now ConcurrentDictionary to avoid a rather nasty locking bottleneck.

This commit is contained in:
cinder
2025-05-27 14:16:03 -05:00
parent b25e647e9f
commit 5ee53b32ac
25 changed files with 747 additions and 759 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenMetaverse.TestClient
@@ -48,22 +49,14 @@ namespace OpenMetaverse.TestClient
lock (Client.Network.Simulators)
{
foreach (var sim in Client.Network.Simulators)
foreach (var av in from sim in Client.Network.Simulators
from kvp in sim.ObjectsAvatars
where kvp.Value != null select kvp.Value into av
where !m_AgentList.ContainsKey(av.ID) select av)
{
sim.ObjectsAvatars.ForEach(
delegate(Avatar av)
{
lock (m_AgentList)
{
if (!m_AgentList.ContainsKey(av.ID))
{
result.AppendLine();
result.AppendFormat("{0} (Group: {1}, Location: {2}, UUID: {3} LocalID: {4}) Is Probably a bot",
av.Name, av.GroupName, av.Position, av.ID, av.LocalID);
}
}
}
);
result.AppendLine();
result.AppendFormat("{0} (Group: {1}, Location: {2}, UUID: {3} LocalID: {4}) Is Probably a bot",
av.Name, av.GroupName, av.Position, av.ID, av.LocalID);
}
}

View File

@@ -1,3 +1,5 @@
using System.Linq;
namespace OpenMetaverse.TestClient
{
public class TouchCommand: Command
@@ -11,25 +13,25 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
UUID target;
if (args.Length != 1)
return "Usage: touch UUID";
if (UUID.TryParse(args[0], out target))
{
Primitive targetPrim = Client.Network.CurrentSim.ObjectsPrimitives.Find(
prim => prim.ID == target
);
if (targetPrim != null)
{
Client.Self.Touch(targetPrim.LocalID);
return "Touched prim " + targetPrim.LocalID;
}
return "Usage: touch UUID";
}
return "Couldn't find a prim to touch with UUID " + args[0];
}
if (!UUID.TryParse(args[0], out var target))
{
return $"{args[0]} is not a valid UUID";
}
var targetPrim = Client.Network.CurrentSim.ObjectsPrimitives.FirstOrDefault(prim => prim.Value.ID == target);
if (targetPrim.Value == null)
{
return $"Couldn't find an object to touch with UUID {args[0]}";
}
Client.Self.Touch(targetPrim.Value.LocalID);
return $"Touched object {targetPrim.Value.LocalID}";
}
}
}

View File

@@ -1,3 +1,4 @@
using System.Linq;
using System.Text;
namespace OpenMetaverse.TestClient
@@ -17,18 +18,12 @@ namespace OpenMetaverse.TestClient
lock (Client.Network.Simulators)
{
foreach (var sim
in Client.Network.Simulators)
foreach (var av in from sim in Client.Network.Simulators
from kvp in sim.ObjectsAvatars where kvp.Value != null select kvp.Value)
{
sim
.ObjectsAvatars.ForEach(
delegate(Avatar av)
{
result.AppendLine();
result.AppendFormat("{0} (Group: {1}, Location: {2}, UUID: {3} LocalID: {4})",
av.Name, av.GroupName, av.Position, av.ID, av.LocalID);
}
);
result.AppendLine();
result.AppendFormat("{0} (Group: {1}, Location: {2}, UUID: {3} LocalID: {4})",
av.Name, av.GroupName, av.Position, av.ID, av.LocalID);
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace OpenMetaverse.TestClient
{
@@ -15,20 +14,19 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
List<Primitive> attachments = Client.Network.CurrentSim.ObjectsPrimitives.FindAll(
prim => prim.ParentID == Client.Self.LocalID
);
var attachments = (from kvp in Client.Network.CurrentSim.ObjectsPrimitives
where kvp.Value != null where kvp.Value.ParentID == Client.Self.LocalID select kvp.Value).ToList();
foreach (var prim in attachments)
{
AttachmentPoint point = StateToAttachmentPoint(prim.PrimData.State);
var point = StateToAttachmentPoint(prim.PrimData.State);
// TODO: Fetch properties for the objects with missing property sets so we can show names
// TODO: Fetch properties for the objects with missing property sets, so we can show names
Logger.Log($"[Attachment @ {point}] LocalID: {prim.LocalID} UUID: {prim.ID} Offset: {prim.Position}",
Helpers.LogLevel.Info, Client);
}
return "Found " + attachments.Count + " attachments";
return $"Found {attachments.Count} attachments";
}
public static AttachmentPoint StateToAttachmentPoint(uint state)

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Text;
namespace OpenMetaverse.TestClient.Commands.Appearance
@@ -19,12 +20,12 @@ namespace OpenMetaverse.TestClient.Commands.Appearance
string targetName = $"{args[0]} {args[1]}";
Avatar foundAv = Client.Network.CurrentSim.ObjectsAvatars.Find(
avatar => (avatar.Name == targetName)
);
var kvp = Client.Network.CurrentSim.ObjectsAvatars.SingleOrDefault(
avatar => (avatar.Value.Name == targetName));
if (foundAv != null)
if (kvp.Value != null)
{
var foundAv = kvp.Value;
StringBuilder output = new StringBuilder();
output.AppendFormat("{0} ({1})", targetName, foundAv.ID);
@@ -46,7 +47,7 @@ namespace OpenMetaverse.TestClient.Commands.Appearance
}
else
{
return "No nearby avatar with the name " + targetName;
return $"No nearby avatar named {targetName}";
}
}
}

View File

@@ -29,6 +29,7 @@ using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using CoreJ2K;
using OpenMetaverse.Assets;
using OpenMetaverse.Imaging;
@@ -64,12 +65,12 @@ namespace OpenMetaverse.TestClient
{
foreach (var sim in Client.Network.Simulators)
{
Avatar targetAv = sim.ObjectsAvatars.Find(
avatar => avatar.ID == target
);
var kvp = sim.ObjectsAvatars.FirstOrDefault(
avatar => avatar.Value.ID == target);
if (targetAv != null)
if (kvp.Value != null)
{
var targetAv = kvp.Value;
StringBuilder output = new StringBuilder("Downloading ");
lock (OutfitAssets) OutfitAssets.Clear();

View File

@@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace OpenMetaverse.TestClient
{
@@ -15,44 +15,47 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
if (args.Length != 1)
return "Usage: objectinventory [objectID]";
uint objectLocalID;
UUID objectID;
if (!UUID.TryParse(args[0], out objectID))
return "Usage: objectinventory [objectID]";
Primitive found = Client.Network.CurrentSim.ObjectsPrimitives.Find(prim => prim.ID == objectID);
if (found != null)
objectLocalID = found.LocalID;
else
return "Couldn't find prim " + objectID;
List<InventoryBase> items = Client.Inventory.GetTaskInventory(objectID, objectLocalID, TimeSpan.FromSeconds(30));
if (items != null)
{
string result = string.Empty;
return "Usage: objectinventory [objectID]";
}
foreach (var i in items)
if (!UUID.TryParse(args[0], out var objectID))
{
return "Usage: objectinventory [objectID]";
}
var found = Client.Network.CurrentSim.ObjectsPrimitives.FirstOrDefault(prim => prim.Value.ID == objectID);
if (found.Value == null)
{
return $"Could not find ${objectID} object";
}
var objectLocalID = found.Value.LocalID;
var items = Client.Inventory.GetTaskInventory(objectID, objectLocalID, TimeSpan.FromSeconds(30));
if (items == null)
{
return $"Failed to download task inventory for {objectLocalID}";
}
var result = string.Empty;
foreach (var i in items)
{
if (i is InventoryFolder)
{
if (i is InventoryFolder)
{
result += $"[Folder] Name: {i.Name}" + Environment.NewLine;
}
else
{
InventoryItem item = (InventoryItem)i;
result += $"[Item] Name: {item.Name} Desc: {item.Description} Type: {item.AssetType}" + Environment.NewLine;
}
result += $"[Folder] Name: {i.Name}" + Environment.NewLine;
}
else
{
InventoryItem item = (InventoryItem)i;
result += $"[Item] Name: {item.Name} Desc: {item.Description} Type: {item.AssetType}" + Environment.NewLine;
}
}
return result;
return result;
}
else
{
return "Failed to download task inventory for " + objectLocalID;
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace OpenMetaverse.TestClient
@@ -16,19 +17,22 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
if (args.Length != 1)
{
return "Usage: taskrunning objectID [[scriptName] true|false]";
}
uint objectLocalID;
UUID objectID;
if (!UUID.TryParse(args[0], out objectID))
if (!UUID.TryParse(args[0], out var objectID))
{
return "Usage: taskrunning objectID [[scriptName] true|false]";
}
Primitive found = Client.Network.CurrentSim.ObjectsPrimitives.Find(prim => prim.ID == objectID);
if (found != null)
objectLocalID = found.LocalID;
else
return $"Couldn't find prim {objectID}";
var found = Client.Network.CurrentSim.ObjectsPrimitives.FirstOrDefault(prim => prim.Value.ID == objectID);
if (found.Value == null)
{
return $"Couldn't find object {objectID}";
}
var objectLocalID = found.Value.LocalID;
List<InventoryBase> items = Client.Inventory.GetTaskInventory(objectID, objectLocalID, TimeSpan.FromSeconds(30));

View File

@@ -43,18 +43,14 @@ namespace OpenMetaverse.TestClient
{
lock (Client.Network.Simulators)
{
foreach (var sim in Client.Network.Simulators)
foreach (var target in Client.Network.Simulators
.Select(sim => sim.ObjectsAvatars
.FirstOrDefault(avatar => avatar.Value.Name == name))
.Where(target => target.Value != null))
{
Avatar target = sim.ObjectsAvatars.Find(
avatar => avatar.Name == name
);
if (target != null)
{
targetLocalID = target.LocalID;
Active = true;
return true;
}
targetLocalID = target.Value.LocalID;
Active = true;
return true;
}
}

View File

@@ -16,30 +16,28 @@ namespace OpenMetaverse.TestClient
Primitive closest = null;
double closestDistance = double.MaxValue;
Client.Network.CurrentSim.ObjectsPrimitives.ForEach(
delegate(Primitive prim)
{
float distance = Vector3.Distance(Client.Self.SimPosition, prim.Position);
if (closest == null || distance < closestDistance)
{
closest = prim;
closestDistance = distance;
}
}
);
if (closest != null)
foreach (var kvp in Client.Network.CurrentSim.ObjectsPrimitives)
{
Client.Self.RequestSit(closest.ID, Vector3.Zero);
Client.Self.Sit();
if (kvp.Value == null) { continue; }
return "Sat on " + closest.ID + " (" + closest.LocalID + "). Distance: " + closestDistance;
var prim = kvp.Value;
var distance = Vector3.Distance(Client.Self.SimPosition, prim.Position);
if (closest == null || distance < closestDistance)
{
closest = prim;
closestDistance = distance;
}
}
else
if (closest == null)
{
return "Couldn't find a nearby prim to sit on";
}
}
Client.Self.RequestSit(closest.ID, Vector3.Zero);
Client.Self.Sit();
return $"Sat on {closest.ID} ({closest.LocalID}). Distance: {closestDistance}";
}
}
}

View File

@@ -1,3 +1,5 @@
using System.Linq;
namespace OpenMetaverse.TestClient
{
public class SitOnCommand : Command
@@ -14,16 +16,13 @@ namespace OpenMetaverse.TestClient
if (args.Length != 1)
return "Usage: siton UUID";
UUID target;
if (UUID.TryParse(args[0], out target))
if (UUID.TryParse(args[0], out var target))
{
Primitive targetPrim = Client.Network.CurrentSim.ObjectsPrimitives.Find(
prim => prim.ID == target
);
var kvp = Client.Network.CurrentSim.ObjectsPrimitives.FirstOrDefault(prim => prim.Value.ID == target);
if (targetPrim != null)
if (kvp.Value != null)
{
var targetPrim = kvp.Value;
Client.Self.RequestSit(targetPrim.ID, Vector3.Zero);
Client.Self.Sit();
return "Requested to sit on prim " + targetPrim.ID +

View File

@@ -7,9 +7,9 @@ namespace OpenMetaverse.TestClient
{
public class ChangePermsCommand : Command
{
AutoResetEvent GotPermissionsEvent = new AutoResetEvent(false);
Dictionary<UUID, Primitive> Objects = new Dictionary<UUID, Primitive>();
PermissionMask Perms = PermissionMask.None;
private readonly AutoResetEvent GotPermissionsEvent = new AutoResetEvent(false);
private readonly Dictionary<UUID, Primitive> Objects = new Dictionary<UUID, Primitive>();
private PermissionMask Perms = PermissionMask.None;
private bool PermsSent;
private int PermCount;
@@ -24,7 +24,6 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
UUID rootID;
var localIDs = new List<uint>();
// Reset class-wide variables
@@ -36,7 +35,7 @@ namespace OpenMetaverse.TestClient
if (args.Length < 1 || args.Length > 4)
return "Usage prim-uuid [copy] [mod] [xfer]";
if (!UUID.TryParse(args[0], out rootID))
if (!UUID.TryParse(args[0], out var rootID))
return "Usage prim-uuid [copy] [mod] [xfer]";
for (int i = 1; i < args.Length; i++)
@@ -60,13 +59,15 @@ namespace OpenMetaverse.TestClient
Logger.DebugLog($"Using PermissionMask: {Perms}", Client);
// Find the requested prim
var rootPrim = Client.Network.CurrentSim.ObjectsPrimitives.Find(prim => prim.ID == rootID);
if (rootPrim == null)
var reqkvp = Client.Network.CurrentSim.ObjectsPrimitives
.FirstOrDefault(prim => prim.Value.ID == rootID);
if (reqkvp.Value == null)
{
return $"Cannot find requested prim {rootID}";
return $"Cannot find requested object {rootID}";
}
Logger.DebugLog($"Found requested prim {rootPrim.ID}", Client);
var rootPrim = reqkvp.Value;
Logger.DebugLog($"Found requested object {rootPrim.ID}", Client);
if (rootPrim.ParentID != 0)
{
@@ -79,8 +80,10 @@ namespace OpenMetaverse.TestClient
Logger.DebugLog($"Set root prim to {rootPrim.ID}", Client);
}
// Find, find all the child objects linked to this root
var childPrims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll(prim => prim.ParentID == rootPrim.LocalID);
// Find all the child primitives linked to the root
var childPrims = (from kvp
in Client.Network.CurrentSim.ObjectsPrimitives where kvp.Value != null
select kvp.Value into child where child.ParentID == rootPrim.LocalID select child).ToList();
// Build a dictionary of primitives for referencing later
Objects[rootPrim.ID] = rootPrim;
@@ -140,7 +143,7 @@ namespace OpenMetaverse.TestClient
return $"Set permissions to {Perms} on {localIDs.Count} objects and {taskItems} inventory items";
}
void Objects_OnObjectProperties(object sender, ObjectPropertiesEventArgs e)
private void Objects_OnObjectProperties(object sender, ObjectPropertiesEventArgs e)
{
if (!PermsSent) { return; }

View File

@@ -1,4 +1,6 @@
namespace OpenMetaverse.TestClient
using System.Linq;
namespace OpenMetaverse.TestClient
{
public class DeRezCommand : Command
{
@@ -11,34 +13,28 @@
public override string Execute(string[] args, UUID fromAgentID)
{
UUID primID;
if (args.Length != 1)
return "Usage: derez [prim-uuid]";
if (UUID.TryParse(args[0], out primID))
{
Primitive target = Client.Network.CurrentSim.ObjectsPrimitives.Find(
prim => prim.ID == primID
);
if (target != null)
{
uint objectLocalID = target.LocalID;
Client.Inventory.RequestDeRezToInventory(objectLocalID, DeRezDestination.AgentInventoryTake,
Client.Inventory.FindFolderForType(FolderType.Trash),
UUID.Random());
return "removing " + target;
}
else
{
return "Could not find prim " + primID;
}
}
else
{
return "Usage: derez [prim-uuid]";
}
if (!UUID.TryParse(args[0], out var primID))
{
return $"{args[0]} is not a valid UUID";
}
var kvp = Client.Network.CurrentSim.ObjectsPrimitives.FirstOrDefault(prim => prim.Value.ID == primID);
if (kvp.Value == null)
{
return $"Could not find object {primID}";
}
var target = kvp.Value;
var objectLocalID = target.LocalID;
Client.Inventory.RequestDeRezToInventory(objectLocalID, DeRezDestination.AgentInventoryTake,
Client.Inventory.FindFolderForType(FolderType.Trash),
UUID.Random());
return $"Removing {target}";
}
}
}

View File

@@ -10,14 +10,14 @@ namespace OpenMetaverse.TestClient
{
public class ExportCommand : Command
{
List<UUID> Textures = new List<UUID>();
AutoResetEvent GotPermissionsEvent = new AutoResetEvent(false);
Primitive.ObjectProperties Properties;
bool GotPermissions = false;
UUID SelectedObject = UUID.Zero;
private readonly List<UUID> Textures = new List<UUID>();
private readonly AutoResetEvent GotPermissionsEvent = new AutoResetEvent(false);
private Primitive.ObjectProperties Properties;
private bool GotPermissions = false;
private UUID SelectedObject = UUID.Zero;
Dictionary<UUID, Primitive> PrimsWaiting = new Dictionary<UUID, Primitive>();
AutoResetEvent AllPropertiesReceived = new AutoResetEvent(false);
private readonly Dictionary<UUID, Primitive> PrimsWaiting = new Dictionary<UUID, Primitive>();
private readonly AutoResetEvent AllPropertiesReceived = new AutoResetEvent(false);
public ExportCommand(TestClient testClient)
{
@@ -29,9 +29,9 @@ namespace OpenMetaverse.TestClient
Name = "export";
Description = "Exports an object to an xml file. Usage: export uuid outputfile.xml";
Category = CommandCategory.Objects;
}
}
void Avatars_ViewerEffectPointAt(object sender, ViewerEffectPointAtEventArgs e)
private void Avatars_ViewerEffectPointAt(object sender, ViewerEffectPointAtEventArgs e)
{
if (e.SourceID == Client.MasterKey)
{
@@ -46,7 +46,6 @@ namespace OpenMetaverse.TestClient
return "Usage: export uuid outputfile.xml";
UUID id;
uint localid;
string file;
if (args.Length == 2)
@@ -61,105 +60,100 @@ namespace OpenMetaverse.TestClient
id = SelectedObject;
}
var exportPrim = Client.Network.CurrentSim.ObjectsPrimitives.Find(
prim => prim.ID == id
);
var kvp = Client.Network.CurrentSim.ObjectsPrimitives.FirstOrDefault(
prim => prim.Value.ID == id);
if (exportPrim != null)
if (kvp.Value == null)
{
localid = exportPrim.ParentID != 0 ? exportPrim.ParentID : exportPrim.LocalID;
return $"Couldn't find UUID {id} in the objects currently indexed in the current simulator";
}
// Check for export permission first
Client.Objects.RequestObjectPropertiesFamily(Client.Network.CurrentSim, id);
GotPermissionsEvent.WaitOne(TimeSpan.FromSeconds(20), false);
var exportPrim = kvp.Value;
var localId = exportPrim.ParentID != 0 ? exportPrim.ParentID : exportPrim.LocalID;
if (!GotPermissions)
// Check for export permission first
Client.Objects.RequestObjectPropertiesFamily(Client.Network.CurrentSim, id);
GotPermissionsEvent.WaitOne(TimeSpan.FromSeconds(20), false);
if (!GotPermissions)
{
return "Couldn't fetch permissions for the requested object, try again";
}
GotPermissions = false;
if (Properties.OwnerID != Client.Self.AgentID &&
Properties.OwnerID != Client.MasterKey)
{
return "That object is owned by " + Properties.OwnerID + ", we don't have permission " +
"to export it";
}
var prims = (from kvprim in Client.Network.CurrentSim.ObjectsPrimitives
where kvprim.Value != null select kvprim.Value into prim
where prim.LocalID == localId || prim.ParentID == localId select prim).ToList();
bool complete = RequestObjectProperties(prims, 250);
if (!complete)
{
Logger.Log("Warning: Unable to retrieve full properties for:", Helpers.LogLevel.Warning, Client);
foreach (UUID uuid in PrimsWaiting.Keys)
Logger.Log(uuid.ToString(), Helpers.LogLevel.Warning, Client);
}
string output = OSDParser.SerializeLLSDXmlString(Helpers.PrimListToOSD(prims));
try { File.WriteAllText(file, output); }
catch (Exception e) { return e.Message; }
Logger.Log("Exported " + prims.Count + " prims to " + file, Helpers.LogLevel.Info, Client);
// Create a list of all the textures to download
List<ImageRequest> textureRequests = new List<ImageRequest>();
lock (Textures)
{
foreach (var prim in prims)
{
return "Couldn't fetch permissions for the requested object, try again";
}
else
{
GotPermissions = false;
if (Properties.OwnerID != Client.Self.AgentID &&
Properties.OwnerID != Client.MasterKey)
if (prim.Textures.DefaultTexture.TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
!Textures.Contains(prim.Textures.DefaultTexture.TextureID))
{
return "That object is owned by " + Properties.OwnerID + ", we don't have permission " +
"to export it";
Textures.Add(prim.Textures.DefaultTexture.TextureID);
}
}
List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll(
prim => (prim.LocalID == localid || prim.ParentID == localid)
);
bool complete = RequestObjectProperties(prims, 250);
if (!complete)
{
Logger.Log("Warning: Unable to retrieve full properties for:", Helpers.LogLevel.Warning, Client);
foreach (UUID uuid in PrimsWaiting.Keys)
Logger.Log(uuid.ToString(), Helpers.LogLevel.Warning, Client);
}
string output = OSDParser.SerializeLLSDXmlString(Helpers.PrimListToOSD(prims));
try { File.WriteAllText(file, output); }
catch (Exception e) { return e.Message; }
Logger.Log("Exported " + prims.Count + " prims to " + file, Helpers.LogLevel.Info, Client);
// Create a list of all of the textures to download
List<ImageRequest> textureRequests = new List<ImageRequest>();
lock (Textures)
{
foreach (var prim in prims)
foreach (var face in prim.Textures.FaceTextures)
{
if (prim.Textures.DefaultTexture.TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
!Textures.Contains(prim.Textures.DefaultTexture.TextureID))
if (face != null &&
face.TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
!Textures.Contains(face.TextureID))
{
Textures.Add(prim.Textures.DefaultTexture.TextureID);
}
foreach (var face in prim.Textures.FaceTextures)
{
if (face != null &&
face.TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
!Textures.Contains(face.TextureID))
{
Textures.Add(face.TextureID);
}
}
if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero && !Textures.Contains(prim.Sculpt.SculptTexture))
{
Textures.Add(prim.Sculpt.SculptTexture);
Textures.Add(face.TextureID);
}
}
// Create a request list from all of the images
textureRequests.AddRange(Textures.Select(t => new ImageRequest(t, ImageType.Normal, 1013000.0f, 0)));
if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero && !Textures.Contains(prim.Sculpt.SculptTexture))
{
Textures.Add(prim.Sculpt.SculptTexture);
}
}
// Download all of the textures in the export list
foreach (ImageRequest request in textureRequests)
{
Client.Assets.RequestImage(request.ImageID, request.Type, Assets_OnImageReceived);
}
return "XML exported, began downloading " + Textures.Count + " textures";
// Create a request list from all the images
textureRequests.AddRange(Textures.Select(t => new ImageRequest(t, ImageType.Normal, 1013000.0f, 0)));
}
else
// Download all the textures in the export list
foreach (var request in textureRequests)
{
return "Couldn't find UUID " + id + " in the " +
Client.Network.CurrentSim.ObjectsPrimitives.Count +
"objects currently indexed in the current simulator";
Client.Assets.RequestImage(request.ImageID, request.Type, Assets_OnImageReceived);
}
return $"XML exported, downloading {Textures.Count} textures";
}
private bool RequestObjectProperties(List<Primitive> objects, int msPerRequest)
{
// Create an array of the local IDs of all the prims we are requesting properties for
uint[] localids = new uint[objects.Count];
uint[] localIds = new uint[objects.Count];
lock (PrimsWaiting)
{
@@ -167,12 +161,12 @@ namespace OpenMetaverse.TestClient
for (int i = 0; i < objects.Count; ++i)
{
localids[i] = objects[i].LocalID;
localIds[i] = objects[i].LocalID;
PrimsWaiting.Add(objects[i].ID, objects[i]);
}
}
Client.Objects.SelectObjects(Client.Network.CurrentSim, localids);
Client.Objects.SelectObjects(Client.Network.CurrentSim, localIds);
return AllPropertiesReceived.WaitOne(2000 + msPerRequest * objects.Count, false);
}
@@ -202,7 +196,7 @@ namespace OpenMetaverse.TestClient
}
}
void Objects_OnObjectPropertiesFamily(object sender, ObjectPropertiesFamilyEventArgs e)
private void Objects_OnObjectPropertiesFamily(object sender, ObjectPropertiesFamilyEventArgs e)
{
Properties = new Primitive.ObjectProperties();
Properties.SetFamilyProperties(e.Properties);
@@ -210,7 +204,7 @@ namespace OpenMetaverse.TestClient
GotPermissionsEvent.Set();
}
void Objects_OnObjectProperties(object sender, ObjectPropertiesEventArgs e)
private void Objects_OnObjectProperties(object sender, ObjectPropertiesEventArgs e)
{
lock (PrimsWaiting)
{

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Text;
namespace OpenMetaverse.TestClient
@@ -15,121 +16,119 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
if (args.Length != 1)
{
return "Usage: exportparticles [prim-uuid]";
}
UUID id;
if (!UUID.TryParse(args[0], out id))
if (!UUID.TryParse(args[0], out var id))
{
return "Usage: exportparticles [prim-uuid]";
}
lock (Client.Network.Simulators)
{
foreach (var sim in Client.Network.Simulators)
foreach (var exportPrim in from sim in Client.Network.Simulators
select sim.ObjectsPrimitives.FirstOrDefault(
prim => prim.Value.ID == id)
into kvp where kvp.Value != null select kvp.Value)
{
Primitive exportPrim = sim.ObjectsPrimitives.Find(
prim => prim.ID == id
);
if (exportPrim != null)
if (exportPrim.ParticleSys.CRC == 0)
{
if (exportPrim.ParticleSys.CRC != 0)
{
StringBuilder lsl = new StringBuilder();
#region Particle System to LSL
lsl.Append("default" + Environment.NewLine);
lsl.Append("{" + Environment.NewLine);
lsl.Append(" state_entry()" + Environment.NewLine);
lsl.Append(" {" + Environment.NewLine);
lsl.Append(" llParticleSystem([" + Environment.NewLine);
lsl.Append(" PSYS_PART_FLAGS, 0");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.InterpColor) != 0)
lsl.Append(" | PSYS_PART_INTERP_COLOR_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.InterpScale) != 0)
lsl.Append(" | PSYS_PART_INTERP_SCALE_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Bounce) != 0)
lsl.Append(" | PSYS_PART_BOUNCE_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Wind) != 0)
lsl.Append(" | PSYS_PART_WIND_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.FollowSrc) != 0)
lsl.Append(" | PSYS_PART_FOLLOW_SRC_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.FollowVelocity) != 0)
lsl.Append(" | PSYS_PART_FOLLOW_VELOCITY_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.TargetPos) != 0)
lsl.Append(" | PSYS_PART_TARGET_POS_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.TargetLinear) != 0)
lsl.Append(" | PSYS_PART_TARGET_LINEAR_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Emissive) != 0)
lsl.Append(" | PSYS_PART_EMISSIVE_MASK");
lsl.Append(","); lsl.Append(Environment.NewLine);
lsl.Append(" PSYS_SRC_PATTERN, 0");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Drop) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_DROP");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Explode) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_EXPLODE");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Angle) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_ANGLE");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.AngleCone) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_ANGLE_CONE");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.AngleConeEmpty) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY");
lsl.Append("," + Environment.NewLine);
lsl.Append(" PSYS_PART_START_ALPHA, " +
$"{exportPrim.ParticleSys.PartStartColor.A:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_END_ALPHA, " +
$"{exportPrim.ParticleSys.PartEndColor.A:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_START_COLOR, " + exportPrim.ParticleSys.PartStartColor.ToRGBString() + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_END_COLOR, " + exportPrim.ParticleSys.PartEndColor.ToRGBString() + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_START_SCALE, <" +
$"{exportPrim.ParticleSys.PartStartScaleX:0.00000}" + ", " +
$"{exportPrim.ParticleSys.PartStartScaleY:0.00000}" + ", 0>, " + Environment.NewLine);
lsl.Append(" PSYS_PART_END_SCALE, <" +
$"{exportPrim.ParticleSys.PartEndScaleX:0.00000}" + ", " +
$"{exportPrim.ParticleSys.PartEndScaleY:0.00000}" + ", 0>, " + Environment.NewLine);
lsl.Append(" PSYS_PART_MAX_AGE, " + $"{exportPrim.ParticleSys.PartMaxAge:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_MAX_AGE, " + $"{exportPrim.ParticleSys.MaxAge:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_ACCEL, " + exportPrim.ParticleSys.PartAcceleration + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_PART_COUNT, " +
$"{exportPrim.ParticleSys.BurstPartCount:0}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_RADIUS, " +
$"{exportPrim.ParticleSys.BurstRadius:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_RATE, " +
$"{exportPrim.ParticleSys.BurstRate:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_SPEED_MIN, " +
$"{exportPrim.ParticleSys.BurstSpeedMin:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_SPEED_MAX, " +
$"{exportPrim.ParticleSys.BurstSpeedMax:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_INNERANGLE, " +
$"{exportPrim.ParticleSys.InnerAngle:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_OUTERANGLE, " +
$"{exportPrim.ParticleSys.OuterAngle:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_OMEGA, " + exportPrim.ParticleSys.AngularVelocity + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_TEXTURE, (key)\"" + exportPrim.ParticleSys.Texture + "\"," + Environment.NewLine);
lsl.Append(" PSYS_SRC_TARGET_KEY, (key)\"" + exportPrim.ParticleSys.Target + "\"" + Environment.NewLine);
lsl.Append(" ]);" + Environment.NewLine);
lsl.Append(" }" + Environment.NewLine);
lsl.Append("}" + Environment.NewLine);
#endregion Particle System to LSL
return lsl.ToString();
}
else
{
return "Prim " + exportPrim.LocalID + " does not have a particle system";
}
return $"Prim {exportPrim.LocalID} does not have a particle system";
}
StringBuilder lsl = new StringBuilder();
#region Particle System to LSL
lsl.Append("default" + Environment.NewLine);
lsl.Append("{" + Environment.NewLine);
lsl.Append(" state_entry()" + Environment.NewLine);
lsl.Append(" {" + Environment.NewLine);
lsl.Append(" llParticleSystem([" + Environment.NewLine);
lsl.Append(" PSYS_PART_FLAGS, 0");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.InterpColor) != 0)
lsl.Append(" | PSYS_PART_INTERP_COLOR_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.InterpScale) != 0)
lsl.Append(" | PSYS_PART_INTERP_SCALE_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Bounce) != 0)
lsl.Append(" | PSYS_PART_BOUNCE_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Wind) != 0)
lsl.Append(" | PSYS_PART_WIND_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.FollowSrc) != 0)
lsl.Append(" | PSYS_PART_FOLLOW_SRC_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.FollowVelocity) != 0)
lsl.Append(" | PSYS_PART_FOLLOW_VELOCITY_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.TargetPos) != 0)
lsl.Append(" | PSYS_PART_TARGET_POS_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.TargetLinear) != 0)
lsl.Append(" | PSYS_PART_TARGET_LINEAR_MASK");
if ((exportPrim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Emissive) != 0)
lsl.Append(" | PSYS_PART_EMISSIVE_MASK");
lsl.Append(","); lsl.Append(Environment.NewLine);
lsl.Append(" PSYS_SRC_PATTERN, 0");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Drop) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_DROP");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Explode) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_EXPLODE");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Angle) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_ANGLE");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.AngleCone) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_ANGLE_CONE");
if ((exportPrim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.AngleConeEmpty) != 0)
lsl.Append(" | PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY");
lsl.Append("," + Environment.NewLine);
lsl.Append(" PSYS_PART_START_ALPHA, " +
$"{exportPrim.ParticleSys.PartStartColor.A:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_END_ALPHA, " +
$"{exportPrim.ParticleSys.PartEndColor.A:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_START_COLOR, " + exportPrim.ParticleSys.PartStartColor.ToRGBString() + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_END_COLOR, " + exportPrim.ParticleSys.PartEndColor.ToRGBString() + "," + Environment.NewLine);
lsl.Append(" PSYS_PART_START_SCALE, <" +
$"{exportPrim.ParticleSys.PartStartScaleX:0.00000}" + ", " +
$"{exportPrim.ParticleSys.PartStartScaleY:0.00000}" + ", 0>, " + Environment.NewLine);
lsl.Append(" PSYS_PART_END_SCALE, <" +
$"{exportPrim.ParticleSys.PartEndScaleX:0.00000}" + ", " +
$"{exportPrim.ParticleSys.PartEndScaleY:0.00000}" + ", 0>, " + Environment.NewLine);
lsl.Append(" PSYS_PART_MAX_AGE, " + $"{exportPrim.ParticleSys.PartMaxAge:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_MAX_AGE, " + $"{exportPrim.ParticleSys.MaxAge:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_ACCEL, " + exportPrim.ParticleSys.PartAcceleration + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_PART_COUNT, " +
$"{exportPrim.ParticleSys.BurstPartCount:0}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_RADIUS, " +
$"{exportPrim.ParticleSys.BurstRadius:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_RATE, " +
$"{exportPrim.ParticleSys.BurstRate:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_SPEED_MIN, " +
$"{exportPrim.ParticleSys.BurstSpeedMin:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_BURST_SPEED_MAX, " +
$"{exportPrim.ParticleSys.BurstSpeedMax:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_INNERANGLE, " +
$"{exportPrim.ParticleSys.InnerAngle:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_OUTERANGLE, " +
$"{exportPrim.ParticleSys.OuterAngle:0.00000}" + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_OMEGA, " + exportPrim.ParticleSys.AngularVelocity + "," + Environment.NewLine);
lsl.Append(" PSYS_SRC_TEXTURE, (key)\"" + exportPrim.ParticleSys.Texture + "\"," + Environment.NewLine);
lsl.Append(" PSYS_SRC_TARGET_KEY, (key)\"" + exportPrim.ParticleSys.Target + "\"" + Environment.NewLine);
lsl.Append(" ]);" + Environment.NewLine);
lsl.Append(" }" + Environment.NewLine);
lsl.Append("}" + Environment.NewLine);
#endregion Particle System to LSL
return lsl.ToString();
}
}
return "Couldn't find prim " + id;
return $"Could not find {id} object";
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading;
@@ -23,36 +25,36 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
// *** parse arguments ***
if ((args.Length < 1) || (args.Length > 2))
if (args.Length < 1 || args.Length > 2)
{
return "Usage: findobjects [radius] <search-string>";
float radius = float.Parse(args[0]);
string searchString = (args.Length > 1) ? args[1] : string.Empty;
}
var radius = float.Parse(args[0]);
var searchString = (args.Length > 1) ? args[1] : string.Empty;
// *** get current location ***
Vector3 location = Client.Self.SimPosition;
var location = Client.Self.SimPosition;
// *** find all objects in radius ***
List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll(
delegate(Primitive prim)
{
Vector3 pos = prim.Position;
return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius));
}
);
var prims = (from kvp
in Client.Network.CurrentSim.ObjectsPrimitives
where kvp.Value != null select kvp.Value into prim let pos = prim.Position
where prim.ParentID == 0 && pos != Vector3.Zero && Vector3.Distance(pos, location) < radius select prim).ToList();
// *** request properties of these objects ***
bool complete = RequestObjectProperties(prims, 250);
var complete = RequestObjectProperties(prims, 250);
foreach (Primitive p in prims)
foreach (var p in prims)
{
string name = p.Properties?.Name;
var name = p.Properties?.Name;
if (string.IsNullOrEmpty(searchString) || ((name != null) && (name.Contains(searchString))))
Console.WriteLine("Object '{0}': {1}", name, p.ID.ToString());
}
if (complete) return "Done searching";
Console.WriteLine("Warning: Unable to retrieve full properties for:");
foreach (UUID uuid in PrimsWaiting.Keys)
foreach (var uuid in PrimsWaiting.Keys)
Console.WriteLine(uuid);
return "Done searching";
@@ -83,8 +85,7 @@ namespace OpenMetaverse.TestClient
{
lock (PrimsWaiting)
{
Primitive prim;
if (PrimsWaiting.TryGetValue(e.Properties.ObjectID, out prim))
if (PrimsWaiting.TryGetValue(e.Properties.ObjectID, out var prim))
{
prim.Properties = e.Properties;
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Security.Permissions;
namespace OpenMetaverse.TestClient
{
@@ -14,36 +15,32 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
int faceIndex;
UUID textureID;
if (args.Length != 2)
return "Usage: findtexture [face-index] [texture-uuid]";
if (int.TryParse(args[0], out faceIndex) &&
UUID.TryParse(args[1], out textureID))
{
Client.Network.CurrentSim.ObjectsPrimitives.ForEach(
delegate(Primitive prim)
return "Usage: findtexture [face-index] [texture-uuid]";
}
if (int.TryParse(args[0], out var faceIndex) &&
UUID.TryParse(args[1], out var textureID))
{
foreach (var kvp in Client.Network.CurrentSim.ObjectsPrimitives)
{
if (kvp.Value == null) { continue; }
var prim = kvp.Value;
if (prim.Textures?.FaceTextures[faceIndex] == null) { continue; }
if (prim.Textures.FaceTextures[faceIndex].TextureID == textureID)
{
if (prim.Textures?.FaceTextures[faceIndex] != null)
{
if (prim.Textures.FaceTextures[faceIndex].TextureID == textureID)
{
Logger.Log(
$"Primitive {prim.ID.ToString()} ({prim.LocalID}) has face index {faceIndex} set to {textureID.ToString()}",
Helpers.LogLevel.Info, Client);
}
}
Logger.Log(
$"Primitive {prim.ID.ToString()} ({prim.LocalID}) has face index {faceIndex} set to {textureID.ToString()}",
Helpers.LogLevel.Info, Client);
}
);
}
return "Done searching";
}
else
{
return "Usage: findtexture [face-index] [texture-uuid]";
}
return "Usage: findtexture [face-index] [texture-uuid]";
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading;
namespace OpenMetaverse.TestClient
@@ -17,73 +18,73 @@ namespace OpenMetaverse.TestClient
UUID primID;
if (args.Length != 1)
return "Usage: priminfo [prim-uuid]";
if (UUID.TryParse(args[0], out primID))
{
Primitive target = Client.Network.CurrentSim.ObjectsPrimitives.Find(
prim => prim.ID == primID
);
return "Usage: priminfo [prim-uuid]";
}
if (target != null)
if (!UUID.TryParse(args[0], out primID))
{
return $"{args[0]} is not a valid UUID";
}
var kvp = Client.Network.CurrentSim.ObjectsPrimitives.FirstOrDefault(
prim => prim.Value.ID == primID);
if (kvp.Value == null)
{
return $"Could not find object {primID}";
}
var target = kvp.Value;
if (target.Text != string.Empty)
{
Logger.Log("Text: " + target.Text, Helpers.LogLevel.Info, Client);
}
if (target.Light != null)
{
Logger.Log("Light: " + target.Light, Helpers.LogLevel.Info, Client);
}
if (target.ParticleSys.CRC != 0)
{
Logger.Log("Particles: " + target.ParticleSys, Helpers.LogLevel.Info, Client);
}
if (target.Textures != null)
{
Logger.Log($"Default texture: {target.Textures.DefaultTexture.TextureID.ToString()}",
Helpers.LogLevel.Info);
for (int i = 0; i < target.Textures.FaceTextures.Length; i++)
{
if (target.Text != string.Empty)
if (target.Textures.FaceTextures[i] != null)
{
Logger.Log("Text: " + target.Text, Helpers.LogLevel.Info, Client);
Logger.Log($"Face {i}: {target.Textures.FaceTextures[i].TextureID.ToString()}",
Helpers.LogLevel.Info, Client);
}
if(target.Light != null)
Logger.Log("Light: " + target.Light, Helpers.LogLevel.Info, Client);
if (target.ParticleSys.CRC != 0)
Logger.Log("Particles: " + target.ParticleSys, Helpers.LogLevel.Info, Client);
Logger.Log("TextureEntry:", Helpers.LogLevel.Info, Client);
if (target.Textures != null)
{
Logger.Log($"Default texure: {target.Textures.DefaultTexture.TextureID.ToString()}",
Helpers.LogLevel.Info);
for (int i = 0; i < target.Textures.FaceTextures.Length; i++)
{
if (target.Textures.FaceTextures[i] != null)
{
Logger.Log($"Face {i}: {target.Textures.FaceTextures[i].TextureID.ToString()}",
Helpers.LogLevel.Info, Client);
}
}
}
else
{
Logger.Log("null", Helpers.LogLevel.Info, Client);
}
AutoResetEvent propsEvent = new AutoResetEvent(false);
EventHandler<ObjectPropertiesEventArgs> propsCallback =
delegate(object sender, ObjectPropertiesEventArgs e)
{
Logger.Log(
$"Category: {e.Properties.Category}\nFolderID: {e.Properties.FolderID}\nFromTaskID: {e.Properties.FromTaskID}\nInventorySerial: {e.Properties.InventorySerial}\nItemID: {e.Properties.ItemID}\nCreationDate: {e.Properties.CreationDate}", Helpers.LogLevel.Info);
propsEvent.Set();
};
Client.Objects.ObjectProperties += propsCallback;
Client.Objects.SelectObject(Client.Network.CurrentSim, target.LocalID, true);
propsEvent.WaitOne(TimeSpan.FromSeconds(10), false);
Client.Objects.ObjectProperties -= propsCallback;
return "Done.";
}
else
{
return "Could not find prim " + primID;
}
}
else
{
return "Usage: priminfo [prim-uuid]";
Logger.Log("null", Helpers.LogLevel.Info, Client);
}
AutoResetEvent propsEvent = new AutoResetEvent(false);
EventHandler<ObjectPropertiesEventArgs> propsCallback =
delegate(object sender, ObjectPropertiesEventArgs e)
{
Logger.Log(
$"Category: {e.Properties.Category}\nFolderID: {e.Properties.FolderID}\nFromTaskID: {e.Properties.FromTaskID}\nInventorySerial: {e.Properties.InventorySerial}\nItemID: {e.Properties.ItemID}\nCreationDate: {e.Properties.CreationDate}", Helpers.LogLevel.Info);
propsEvent.Set();
};
Client.Objects.ObjectProperties += propsCallback;
Client.Objects.SelectObject(Client.Network.CurrentSim, target.LocalID, true);
propsEvent.WaitOne(TimeSpan.FromSeconds(10), false);
Client.Objects.ObjectProperties -= propsCallback;
return "Done.";
}
}
}

View File

@@ -20,46 +20,46 @@ namespace OpenMetaverse.TestClient
try
{
// Build the predicat from the args list
string predicatPrim = args.Aggregate(string.Empty, (current, t) => current + (t + " "));
predicatPrim = predicatPrim.TrimEnd();
// Build the predicate from the args list
var predicatePrim = args.Aggregate(string.Empty, (current, t) => current + (t + " "));
predicatePrim = predicatePrim.TrimEnd();
// Build Regex
Regex regexPrimName = new Regex(predicatPrim.ToLower());
var regexPrimName = new Regex(predicatePrim.ToLower());
// Print result
Logger.Log(
$"Searching prim for [{predicatPrim}] ({Client.Network.CurrentSim.ObjectsPrimitives.Count} prims loaded in simulator)\n", Helpers.LogLevel.Info, Client);
$"Searching prim for [{predicatePrim}] ({Client.Network.CurrentSim.ObjectsPrimitives.Count} prims loaded in simulator)\n",
Helpers.LogLevel.Info, Client);
Client.Network.CurrentSim.ObjectsPrimitives.ForEach(
delegate(Primitive prim)
foreach (var kvp in Client.Network.CurrentSim.ObjectsPrimitives)
{
if (kvp.Value == null) { continue; }
var prim = kvp.Value;
var name = "(unknown)";
var description = "(unknown)";
var match = (prim.Text != null && regexPrimName.IsMatch(prim.Text.ToLower()));
if (prim.Properties != null && !match)
{
bool match = false;
string name = "(unknown)";
string description = "(unknown)";
match = (prim.Text != null && regexPrimName.IsMatch(prim.Text.ToLower()));
if (prim.Properties != null && !match)
{
match = regexPrimName.IsMatch(prim.Properties.Name.ToLower());
if (!match)
match = regexPrimName.IsMatch(prim.Properties.Description.ToLower());
}
if (match)
{
if (prim.Properties != null)
{
name = prim.Properties.Name;
description = prim.Properties.Description;
}
Logger.Log(
$"\nNAME={name}\nID = {prim.ID}\nFLAGS = {prim.Flags.ToString()}\nTEXT = '{prim.Text}'\nDESC='{description}'", Helpers.LogLevel.Info, Client);
}
match = regexPrimName.IsMatch(prim.Properties.Name.ToLower());
if (!match)
match = regexPrimName.IsMatch(prim.Properties.Description.ToLower());
}
);
if (!match) { continue; }
if (prim.Properties != null)
{
name = prim.Properties.Name;
description = prim.Properties.Description;
}
Logger.Log(
$"\nNAME={name}\nID = {prim.ID}\nFLAGS = {prim.Flags.ToString()}\nTEXT = '{prim.Text}'\nDESC='{description}'",
Helpers.LogLevel.Info, Client);
}
}
catch (System.Exception e)
{

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
namespace OpenMetaverse.TestClient
{
@@ -19,18 +20,14 @@ namespace OpenMetaverse.TestClient
lock (Client.Network.Simulators)
{
foreach (var sim in Client.Network.Simulators)
foreach (var master in Client.Network.Simulators
.Select(sim => sim.ObjectsAvatars.FirstOrDefault(
kvp => kvp.Value.ID == Client.MasterKey))
.Where(master => master.Value != null))
{
Avatar master = sim.ObjectsAvatars.Find(
avatar => avatar.ID == Client.MasterKey
);
if (master != null)
{
Client.Self.InstantMessage(master.ID,
"You are now my master. IM me with \"help\" for a command list.");
break;
}
Client.Self.InstantMessage(master.Value.ID,
"You are now my master. IM me with \"help\" for a command list.");
break;
}
}