ObjectsAvatars and ObjectsPrimitives are now ConcurrentDictionary to avoid a rather nasty locking bottleneck.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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}";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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}";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 +
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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}";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user