* Implemented asset and appearance persistence in Simian
git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2283 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
@@ -10,9 +10,12 @@ namespace Simian.Extensions
|
||||
{
|
||||
public class AssetManager : IExtension, IAssetProvider
|
||||
{
|
||||
public const string UPLOAD_DIR = "uploadedAssets";
|
||||
|
||||
Simian Server;
|
||||
Dictionary<UUID, Asset> AssetStore = new Dictionary<UUID, Asset>();
|
||||
Dictionary<ulong, Asset> CurrentUploads = new Dictionary<ulong, Asset>();
|
||||
string UploadDir;
|
||||
|
||||
public AssetManager(Simian server)
|
||||
{
|
||||
@@ -21,7 +24,22 @@ namespace Simian.Extensions
|
||||
|
||||
public void Start()
|
||||
{
|
||||
LoadDefaultAssets(Server.DataDir);
|
||||
UploadDir = Path.Combine(Server.DataDir, UPLOAD_DIR);
|
||||
|
||||
// Try to create the data directories if they don't already exist
|
||||
if (!Directory.Exists(Server.DataDir))
|
||||
{
|
||||
try { Directory.CreateDirectory(Server.DataDir); }
|
||||
catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Warning, ex); }
|
||||
}
|
||||
if (!Directory.Exists(UploadDir))
|
||||
{
|
||||
try { Directory.CreateDirectory(UploadDir); }
|
||||
catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Warning, ex); }
|
||||
}
|
||||
|
||||
LoadAssets(Server.DataDir);
|
||||
LoadAssets(UploadDir);
|
||||
|
||||
Server.UDP.RegisterPacketCallback(PacketType.AssetUploadRequest, new PacketCallback(AssetUploadRequestHandler));
|
||||
Server.UDP.RegisterPacketCallback(PacketType.SendXferPacket, new PacketCallback(SendXferPacketHandler));
|
||||
@@ -43,6 +61,8 @@ namespace Simian.Extensions
|
||||
{
|
||||
lock (AssetStore)
|
||||
AssetStore[asset.AssetID] = texture;
|
||||
if (!asset.Temporary)
|
||||
SaveAsset(texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -56,6 +76,8 @@ namespace Simian.Extensions
|
||||
{
|
||||
lock (AssetStore)
|
||||
AssetStore[asset.AssetID] = asset;
|
||||
if (!asset.Temporary)
|
||||
SaveAsset(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -77,9 +99,10 @@ namespace Simian.Extensions
|
||||
AssetUploadRequestPacket request = (AssetUploadRequestPacket)packet;
|
||||
UUID assetID = UUID.Combine(request.AssetBlock.TransactionID, agent.SecureSessionID);
|
||||
|
||||
// Check if the asset is small enough to fit in a single packet
|
||||
if (request.AssetBlock.AssetData.Length != 0)
|
||||
{
|
||||
// Create a new asset from the upload
|
||||
// Create a new asset from the completed upload
|
||||
Asset asset = CreateAsset((AssetType)request.AssetBlock.Type, assetID, request.AssetBlock.AssetData);
|
||||
if (asset == null)
|
||||
{
|
||||
@@ -89,6 +112,8 @@ namespace Simian.Extensions
|
||||
|
||||
Logger.DebugLog(String.Format("Storing uploaded asset {0} ({1})", assetID, asset.AssetType));
|
||||
|
||||
asset.Temporary = (request.AssetBlock.Tempfile | request.AssetBlock.StoreLocal);
|
||||
|
||||
// Store the asset
|
||||
StoreAsset(asset);
|
||||
|
||||
@@ -101,15 +126,18 @@ namespace Simian.Extensions
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset for the upload
|
||||
// Create a new (empty) asset for the upload
|
||||
Asset asset = CreateAsset((AssetType)request.AssetBlock.Type, assetID, null);
|
||||
if (asset == null)
|
||||
{
|
||||
Logger.Log("Failed to create asset from uploaded data", Helpers.LogLevel.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.DebugLog(String.Format("Starting upload for {0} ({1})", assetID, asset.AssetType));
|
||||
|
||||
asset.Temporary = (request.AssetBlock.Tempfile | request.AssetBlock.StoreLocal);
|
||||
|
||||
RequestXferPacket xfer = new RequestXferPacket();
|
||||
xfer.XferID.DeleteOnCompletion = request.AssetBlock.Tempfile;
|
||||
xfer.XferID.FilePath = 0;
|
||||
@@ -168,7 +196,7 @@ namespace Simian.Extensions
|
||||
if ((xfer.XferID.Packet & (uint)0x80000000) != 0)
|
||||
{
|
||||
// Asset upload finished
|
||||
Logger.DebugLog("Completed asset upload");
|
||||
Logger.DebugLog(String.Format("Completed Xfer upload of asset {0} ({1}", asset.AssetID, asset.AssetType));
|
||||
|
||||
lock (CurrentUploads)
|
||||
CurrentUploads.Remove(xfer.XferID.ID);
|
||||
@@ -348,6 +376,19 @@ namespace Simian.Extensions
|
||||
|
||||
#endregion Transfer System
|
||||
|
||||
void SaveAsset(Asset asset)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllBytes(Path.Combine(UploadDir, String.Format("{0}.{1}", asset.AssetID,
|
||||
asset.AssetType.ToString().ToLower())), asset.AssetData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log(ex.Message, Helpers.LogLevel.Warning, ex);
|
||||
}
|
||||
}
|
||||
|
||||
Asset CreateAsset(AssetType type, UUID assetID, byte[] data)
|
||||
{
|
||||
switch (type)
|
||||
@@ -389,38 +430,51 @@ namespace Simian.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
void LoadDefaultAssets(string path)
|
||||
void LoadAssets(string path)
|
||||
{
|
||||
string[] textures = Directory.GetFiles(path, "*.jp2", SearchOption.TopDirectoryOnly);
|
||||
string[] clothing = Directory.GetFiles(path, "*.clothing", SearchOption.TopDirectoryOnly);
|
||||
string[] bodyparts = Directory.GetFiles(path, "*.bodypart", SearchOption.TopDirectoryOnly);
|
||||
string[] sounds = Directory.GetFiles(path, "*.ogg", SearchOption.TopDirectoryOnly);
|
||||
|
||||
for (int i = 0; i < textures.Length; i++)
|
||||
try
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(textures[i]);
|
||||
StoreAsset(new AssetTexture(assetID, File.ReadAllBytes(textures[i])));
|
||||
}
|
||||
string[] textures = Directory.GetFiles(path, "*.jp2", SearchOption.TopDirectoryOnly);
|
||||
string[] clothing = Directory.GetFiles(path, "*.clothing", SearchOption.TopDirectoryOnly);
|
||||
string[] bodyparts = Directory.GetFiles(path, "*.bodypart", SearchOption.TopDirectoryOnly);
|
||||
string[] sounds = Directory.GetFiles(path, "*.ogg", SearchOption.TopDirectoryOnly);
|
||||
|
||||
for (int i = 0; i < clothing.Length; i++)
|
||||
for (int i = 0; i < textures.Length; i++)
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(textures[i]);
|
||||
Asset asset = new AssetTexture(assetID, File.ReadAllBytes(textures[i]));
|
||||
asset.Temporary = true;
|
||||
StoreAsset(asset);
|
||||
}
|
||||
|
||||
for (int i = 0; i < clothing.Length; i++)
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(clothing[i]);
|
||||
Asset asset = new AssetClothing(assetID, File.ReadAllBytes(clothing[i]));
|
||||
asset.Temporary = true;
|
||||
StoreAsset(asset);
|
||||
}
|
||||
|
||||
for (int i = 0; i < bodyparts.Length; i++)
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(bodyparts[i]);
|
||||
Asset asset = new AssetBodypart(assetID, File.ReadAllBytes(bodyparts[i]));
|
||||
asset.Temporary = true;
|
||||
StoreAsset(asset);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sounds.Length; i++)
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(sounds[i]);
|
||||
Asset asset = new AssetSound(assetID, File.ReadAllBytes(sounds[i]));
|
||||
asset.Temporary = true;
|
||||
StoreAsset(asset);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(clothing[i]);
|
||||
StoreAsset(new AssetClothing(assetID, File.ReadAllBytes(clothing[i])));
|
||||
Logger.Log(ex.Message, Helpers.LogLevel.Warning, ex);
|
||||
}
|
||||
|
||||
for (int i = 0; i < bodyparts.Length; i++)
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(bodyparts[i]);
|
||||
StoreAsset(new AssetBodypart(assetID, File.ReadAllBytes(bodyparts[i])));
|
||||
}
|
||||
|
||||
for (int i = 0; i < sounds.Length; i++)
|
||||
{
|
||||
UUID assetID = ParseUUIDFromFilename(sounds[i]);
|
||||
StoreAsset(new AssetSound(assetID, File.ReadAllBytes(sounds[i])));
|
||||
}
|
||||
|
||||
Logger.DebugLog(String.Format("Loaded {0} assets", AssetStore.Count));
|
||||
}
|
||||
|
||||
static UUID ParseUUIDFromFilename(string filename)
|
||||
|
||||
@@ -66,39 +66,33 @@ namespace Simian.Extensions
|
||||
UUID hairAsset = new UUID("dc675529-7ba5-4976-b91d-dcb9e5e36188");
|
||||
UUID hairItem = server.Inventory.CreateItem(agent.AgentID, "Default Hair", "Default Hair",
|
||||
InventoryType.Wearable, AssetType.Bodypart, hairAsset, defaultOutfitFolder,
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0);
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0, false);
|
||||
UUID pantsAsset = new UUID("3e8ee2d6-4f21-4a55-832d-77daa505edff");
|
||||
UUID pantsItem = server.Inventory.CreateItem(agent.AgentID, "Default Pants", "Default Pants",
|
||||
InventoryType.Wearable, AssetType.Clothing, pantsAsset, defaultOutfitFolder,
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0);
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0, false);
|
||||
UUID shapeAsset = new UUID("530a2614-052e-49a2-af0e-534bb3c05af0");
|
||||
UUID shapeItem = server.Inventory.CreateItem(agent.AgentID, "Default Shape", "Default Shape",
|
||||
InventoryType.Wearable, AssetType.Clothing, shapeAsset, defaultOutfitFolder,
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0);
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0, false);
|
||||
UUID shirtAsset = new UUID("6a714f37-fe53-4230-b46f-8db384465981");
|
||||
UUID shirtItem = server.Inventory.CreateItem(agent.AgentID, "Default Shirt", "Default Shirt",
|
||||
InventoryType.Wearable, AssetType.Clothing, shirtAsset, defaultOutfitFolder,
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0);
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0, false);
|
||||
UUID skinAsset = new UUID("5f787f25-f761-4a35-9764-6418ee4774c4");
|
||||
UUID skinItem = server.Inventory.CreateItem(agent.AgentID, "Default Skin", "Default Skin",
|
||||
InventoryType.Wearable, AssetType.Clothing, skinAsset, defaultOutfitFolder,
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0);
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0, false);
|
||||
UUID eyesAsset = new UUID("78d20332-9b07-44a2-bf74-3b368605f4b5");
|
||||
UUID eyesItem = server.Inventory.CreateItem(agent.AgentID, "Default Eyes", "Default Eyes",
|
||||
InventoryType.Wearable, AssetType.Bodypart, eyesAsset, defaultOutfitFolder,
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0);
|
||||
PermissionMask.All, PermissionMask.All, agent.AgentID, agent.AgentID, UUID.Random(), 0, false);
|
||||
|
||||
agent.HairAsset = hairAsset;
|
||||
agent.HairItem = hairItem;
|
||||
agent.PantsAsset = pantsAsset;
|
||||
agent.PantsItem = pantsItem;
|
||||
agent.ShapeAsset = shapeAsset;
|
||||
agent.ShapeItem = shapeItem;
|
||||
agent.ShirtAsset = shirtAsset;
|
||||
agent.ShirtItem = shirtItem;
|
||||
agent.SkinAsset = skinAsset;
|
||||
agent.SkinItem = skinItem;
|
||||
agent.EyesAsset = eyesAsset;
|
||||
agent.EyesItem = eyesItem;
|
||||
|
||||
server.Accounts.AddAccount(agent);
|
||||
|
||||
@@ -152,23 +152,38 @@ namespace Simian.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
int CountWearables(Agent agent)
|
||||
bool TryAddWearable(UUID agentID, Dictionary<WearableType, InventoryItem> wearables, WearableType type, UUID itemID)
|
||||
{
|
||||
int wearables = 0;
|
||||
InventoryObject obj;
|
||||
if (itemID != UUID.Zero && Server.Inventory.TryGetInventory(agentID, itemID, out obj) &&
|
||||
obj is InventoryItem)
|
||||
{
|
||||
wearables.Add(type, (InventoryItem)obj);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (agent.ShapeAsset != UUID.Zero) ++wearables;
|
||||
if (agent.SkinAsset != UUID.Zero) ++wearables;
|
||||
if (agent.HairAsset != UUID.Zero) ++wearables;
|
||||
if (agent.EyesAsset != UUID.Zero) ++wearables;
|
||||
if (agent.ShirtAsset != UUID.Zero) ++wearables;
|
||||
if (agent.PantsAsset != UUID.Zero) ++wearables;
|
||||
if (agent.ShoesAsset != UUID.Zero) ++wearables;
|
||||
if (agent.SocksAsset != UUID.Zero) ++wearables;
|
||||
if (agent.JacketAsset != UUID.Zero) ++wearables;
|
||||
if (agent.GlovesAsset != UUID.Zero) ++wearables;
|
||||
if (agent.UndershirtAsset != UUID.Zero) ++wearables;
|
||||
if (agent.UnderpantsAsset != UUID.Zero) ++wearables;
|
||||
if (agent.SkirtAsset != UUID.Zero) ++wearables;
|
||||
Dictionary<WearableType, InventoryItem> GetCurrentWearables(Agent agent)
|
||||
{
|
||||
Dictionary<WearableType, InventoryItem> wearables = new Dictionary<WearableType, InventoryItem>();
|
||||
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Shape, agent.ShapeItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Skin, agent.SkinItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Hair, agent.HairItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Eyes, agent.EyesItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Shirt, agent.ShirtItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Pants, agent.PantsItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Shoes, agent.ShoesItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Socks, agent.SocksItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Jacket, agent.JacketItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Gloves, agent.GlovesItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Undershirt, agent.UndershirtItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Underpants, agent.UnderpantsItem);
|
||||
TryAddWearable(agent.AgentID, wearables, WearableType.Skirt, agent.SkirtItem);
|
||||
|
||||
return wearables;
|
||||
}
|
||||
@@ -178,126 +193,24 @@ namespace Simian.Extensions
|
||||
AgentWearablesUpdatePacket update = new AgentWearablesUpdatePacket();
|
||||
update.AgentData.AgentID = agent.AgentID;
|
||||
|
||||
// Count the number of WearableData blocks needed
|
||||
int wearableCount = CountWearables(agent);
|
||||
Dictionary<WearableType, InventoryItem> wearables = GetCurrentWearables(agent);
|
||||
update.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[wearables.Count];
|
||||
int i = 0;
|
||||
|
||||
update.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[wearableCount];
|
||||
|
||||
#region WearableData Blocks
|
||||
|
||||
if (agent.ShapeAsset != UUID.Zero)
|
||||
foreach (KeyValuePair<WearableType, InventoryItem> kvp in wearables)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.ShapeAsset;
|
||||
update.WearableData[i].ItemID = agent.ShapeItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Shape;
|
||||
update.WearableData[i].AssetID = kvp.Value.AssetID;
|
||||
update.WearableData[i].ItemID = kvp.Value.ID;
|
||||
update.WearableData[i].WearableType = (byte)kvp.Key;
|
||||
++i;
|
||||
}
|
||||
if (agent.SkinAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.SkinAsset;
|
||||
update.WearableData[i].ItemID = agent.SkinItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Skin;
|
||||
++i;
|
||||
}
|
||||
if (agent.HairAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.HairAsset;
|
||||
update.WearableData[i].ItemID = agent.HairItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Hair;
|
||||
++i;
|
||||
}
|
||||
if (agent.EyesAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.EyesAsset;
|
||||
update.WearableData[i].ItemID = agent.EyesItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Eyes;
|
||||
++i;
|
||||
}
|
||||
if (agent.ShirtAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.ShirtAsset;
|
||||
update.WearableData[i].ItemID = agent.ShirtItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Shirt;
|
||||
++i;
|
||||
}
|
||||
if (agent.PantsAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.PantsAsset;
|
||||
update.WearableData[i].ItemID = agent.PantsItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Pants;
|
||||
++i;
|
||||
}
|
||||
if (agent.ShoesAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.ShoesAsset;
|
||||
update.WearableData[i].ItemID = agent.ShoesItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Shoes;
|
||||
++i;
|
||||
}
|
||||
if (agent.SocksAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.SocksAsset;
|
||||
update.WearableData[i].ItemID = agent.SocksItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Socks;
|
||||
++i;
|
||||
}
|
||||
if (agent.JacketAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.JacketAsset;
|
||||
update.WearableData[i].ItemID = agent.JacketItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Jacket;
|
||||
++i;
|
||||
}
|
||||
if (agent.GlovesAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.GlovesAsset;
|
||||
update.WearableData[i].ItemID = agent.GlovesItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Gloves;
|
||||
++i;
|
||||
}
|
||||
if (agent.UndershirtAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.UndershirtAsset;
|
||||
update.WearableData[i].ItemID = agent.UndershirtItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Undershirt;
|
||||
++i;
|
||||
}
|
||||
if (agent.UnderpantsAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.UnderpantsAsset;
|
||||
update.WearableData[i].ItemID = agent.UnderpantsItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Underpants;
|
||||
++i;
|
||||
}
|
||||
if (agent.SkirtAsset != UUID.Zero)
|
||||
{
|
||||
update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||
update.WearableData[i].AssetID = agent.SkirtAsset;
|
||||
update.WearableData[i].ItemID = agent.SkirtItem;
|
||||
update.WearableData[i].WearableType = (byte)WearableType.Skirt;
|
||||
++i;
|
||||
}
|
||||
|
||||
#endregion WearableData Blocks
|
||||
|
||||
// Technically this should be per-agent, but if the only requirement is that it
|
||||
// increments this is easier
|
||||
update.AgentData.SerialNum = (uint)Interlocked.Increment(ref currentWearablesSerialNum);
|
||||
|
||||
Logger.DebugLog(String.Format("Sending info about {0} wearables", wearableCount));
|
||||
Logger.DebugLog(String.Format("Sending info about {0} wearables", wearables.Count));
|
||||
|
||||
Server.UDP.SendPacket(agent.AgentID, update, PacketCategory.Asset);
|
||||
}
|
||||
@@ -313,67 +226,49 @@ namespace Simian.Extensions
|
||||
|
||||
for (int i = 0; i < wearing.WearableData.Length; i++)
|
||||
{
|
||||
UUID assetID = UUID.Zero;
|
||||
UUID itemID = wearing.WearableData[i].ItemID;
|
||||
|
||||
InventoryObject invObj;
|
||||
if (Server.Inventory.TryGetInventory(agent.AgentID, itemID, out invObj) && invObj is InventoryItem)
|
||||
assetID = ((InventoryItem)invObj).AssetID;
|
||||
|
||||
#region Update Wearables
|
||||
|
||||
switch ((WearableType)wearing.WearableData[i].WearableType)
|
||||
{
|
||||
case WearableType.Shape:
|
||||
agent.ShapeAsset = assetID;
|
||||
agent.ShapeItem = itemID;
|
||||
break;
|
||||
case WearableType.Skin:
|
||||
agent.SkinAsset = assetID;
|
||||
agent.SkinItem = itemID;
|
||||
break;
|
||||
case WearableType.Hair:
|
||||
agent.HairAsset = assetID;
|
||||
agent.HairItem = itemID;
|
||||
break;
|
||||
case WearableType.Eyes:
|
||||
agent.EyesAsset = assetID;
|
||||
agent.EyesItem = itemID;
|
||||
break;
|
||||
case WearableType.Shirt:
|
||||
agent.ShirtAsset = assetID;
|
||||
agent.ShirtItem = itemID;
|
||||
break;
|
||||
case WearableType.Pants:
|
||||
agent.PantsAsset = assetID;
|
||||
agent.PantsItem = itemID;
|
||||
break;
|
||||
case WearableType.Shoes:
|
||||
agent.ShoesAsset = assetID;
|
||||
agent.ShoesItem = itemID;
|
||||
break;
|
||||
case WearableType.Socks:
|
||||
agent.SocksAsset = assetID;
|
||||
agent.SocksItem = itemID;
|
||||
break;
|
||||
case WearableType.Jacket:
|
||||
agent.JacketAsset = assetID;
|
||||
agent.JacketItem = itemID;
|
||||
break;
|
||||
case WearableType.Gloves:
|
||||
agent.GlovesAsset = assetID;
|
||||
agent.GlovesItem = itemID;
|
||||
break;
|
||||
case WearableType.Undershirt:
|
||||
agent.UndershirtAsset = assetID;
|
||||
agent.UndershirtItem = itemID;
|
||||
break;
|
||||
case WearableType.Underpants:
|
||||
agent.UnderpantsAsset = assetID;
|
||||
agent.UnderpantsItem = itemID;
|
||||
break;
|
||||
case WearableType.Skirt:
|
||||
agent.SkirtAsset = assetID;
|
||||
agent.SkirtItem = itemID;
|
||||
break;
|
||||
}
|
||||
@@ -381,7 +276,8 @@ namespace Simian.Extensions
|
||||
#endregion Update Wearables
|
||||
}
|
||||
|
||||
Logger.DebugLog("Updated agent wearables, new count: " + CountWearables(agent));
|
||||
// FIXME: GetCurrentWearables() is a very expensive call, remove it from this debug line
|
||||
Logger.DebugLog("Updated agent wearables, new count: " + GetCurrentWearables(agent).Count);
|
||||
}
|
||||
|
||||
void AgentSetAppearanceHandler(Packet packet, Agent agent)
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Simian.Extensions
|
||||
CreateItem(agent.AgentID, Utils.BytesToString(create.InventoryBlock.Name), "Created in Simian",
|
||||
(InventoryType)create.InventoryBlock.InvType, assetType, assetID, parentID,
|
||||
PermissionMask.All, (PermissionMask)create.InventoryBlock.NextOwnerMask, agent.AgentID,
|
||||
agent.AgentID, create.InventoryBlock.TransactionID, create.InventoryBlock.CallbackID);
|
||||
agent.AgentID, create.InventoryBlock.TransactionID, create.InventoryBlock.CallbackID, true);
|
||||
}
|
||||
|
||||
void CreateInventoryFolderHandler(Packet packet, Agent agent)
|
||||
@@ -137,6 +137,7 @@ namespace Simian.Extensions
|
||||
item.SalePrice = block.SalePrice;
|
||||
item.SaleType = (SaleType)block.SaleType;
|
||||
item.AssetType = (AssetType)block.Type;
|
||||
item.AssetID = UUID.Combine(block.TransactionID, agent.SecureSessionID);
|
||||
|
||||
Logger.DebugLog(String.Format(
|
||||
"UpdateInventoryItem: CallbackID: {0}, TransactionID: {1}",
|
||||
@@ -228,14 +229,7 @@ namespace Simian.Extensions
|
||||
itemBlocks[i] = new InventoryDescendentsPacket.ItemDataBlock();
|
||||
itemBlocks[i].AssetID = currentItem.AssetID;
|
||||
itemBlocks[i].BaseMask = (uint)currentItem.Permissions.BaseMask;
|
||||
itemBlocks[i].CRC = Helpers.InventoryCRC(
|
||||
(int)Utils.DateTimeToUnixTime(currentItem.CreationDate),
|
||||
(byte)currentItem.SaleType, (sbyte)currentItem.InventoryType,
|
||||
(sbyte)currentItem.AssetType, currentItem.AssetID, currentItem.GroupID,
|
||||
currentItem.SalePrice, currentItem.OwnerID, currentItem.CreatorID, currentItem.ID,
|
||||
currentItem.ParentID, (uint)currentItem.Permissions.EveryoneMask, currentItem.Flags,
|
||||
(uint)currentItem.Permissions.NextOwnerMask, (uint)currentItem.Permissions.GroupMask,
|
||||
(uint)currentItem.Permissions.OwnerMask);
|
||||
itemBlocks[i].CRC = currentItem.CRC;
|
||||
itemBlocks[i].CreationDate = (int)Utils.DateTimeToUnixTime(currentItem.CreationDate);
|
||||
itemBlocks[i].CreatorID = currentItem.CreatorID;
|
||||
itemBlocks[i].Description = Utils.StringToBytes(currentItem.Description);
|
||||
@@ -366,11 +360,7 @@ namespace Simian.Extensions
|
||||
|
||||
blocks[i].AssetID = item.AssetID;
|
||||
blocks[i].BaseMask = (uint)item.Permissions.BaseMask;
|
||||
blocks[i].CRC = Helpers.InventoryCRC((int)Utils.DateTimeToUnixTime(item.CreationDate),
|
||||
(byte)item.SaleType, (sbyte)item.InventoryType, (sbyte)item.AssetType, item.AssetID, item.GroupID,
|
||||
item.SalePrice, item.OwnerID, item.CreatorID, item.ID, item.ParentID,
|
||||
(uint)item.Permissions.EveryoneMask, item.Flags, (uint)item.Permissions.NextOwnerMask,
|
||||
(uint)item.Permissions.GroupMask, (uint)item.Permissions.OwnerMask);
|
||||
blocks[i].CRC = item.CRC;
|
||||
blocks[i].CreationDate = (int)Utils.DateTimeToUnixTime(item.CreationDate);
|
||||
blocks[i].CreatorID = item.CreatorID;
|
||||
blocks[i].Description = Utils.StringToBytes(item.Description);
|
||||
@@ -447,7 +437,7 @@ namespace Simian.Extensions
|
||||
// Create the copy
|
||||
CreateItem(agent.AgentID, newName, item.Description, item.InventoryType, item.AssetType,
|
||||
item.AssetID, folderObj.ID, item.Permissions.OwnerMask, item.Permissions.NextOwnerMask,
|
||||
agent.AgentID, item.CreatorID, UUID.Zero, block.CallbackID);
|
||||
agent.AgentID, item.CreatorID, UUID.Zero, block.CallbackID, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -477,7 +467,8 @@ namespace Simian.Extensions
|
||||
UUID newFolderID = block.FolderID;
|
||||
if (newFolderID == UUID.Zero)
|
||||
newFolderID = agent.InventoryRoot;
|
||||
MoveInventory(agentInventory, block.ItemID, newFolderID, Utils.BytesToString(block.NewName));
|
||||
MoveInventory(agent, agentInventory, block.ItemID, newFolderID, Utils.BytesToString(block.NewName),
|
||||
UUID.Zero, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,11 +485,64 @@ namespace Simian.Extensions
|
||||
UUID newFolderID = block.ParentID;
|
||||
if (newFolderID == UUID.Zero)
|
||||
newFolderID = agent.InventoryRoot;
|
||||
MoveInventory(agentInventory, block.FolderID, newFolderID, null);
|
||||
MoveInventory(agent, agentInventory, block.FolderID, newFolderID, null, UUID.Zero, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInventory(Dictionary<UUID, InventoryObject> agentInventory, UUID objectID, UUID newFolderID, string newName)
|
||||
void SendBulkUpdate(Agent agent, InventoryObject obj, UUID transactionID, uint callbackID)
|
||||
{
|
||||
BulkUpdateInventoryPacket update = new BulkUpdateInventoryPacket();
|
||||
update.AgentData.AgentID = agent.AgentID;
|
||||
update.AgentData.TransactionID = transactionID;
|
||||
|
||||
if (obj is InventoryItem)
|
||||
{
|
||||
InventoryItem item = (InventoryItem)obj;
|
||||
|
||||
update.FolderData = new BulkUpdateInventoryPacket.FolderDataBlock[0];
|
||||
update.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[1];
|
||||
update.ItemData[0] = new BulkUpdateInventoryPacket.ItemDataBlock();
|
||||
update.ItemData[0].AssetID = item.AssetID;
|
||||
update.ItemData[0].BaseMask = (uint)item.Permissions.BaseMask;
|
||||
update.ItemData[0].CallbackID = callbackID;
|
||||
update.ItemData[0].CRC = item.CRC;
|
||||
update.ItemData[0].CreationDate = (int)Utils.DateTimeToUnixTime(item.CreationDate);
|
||||
update.ItemData[0].CreatorID = item.CreatorID;
|
||||
update.ItemData[0].Description = Utils.StringToBytes(item.Description);
|
||||
update.ItemData[0].EveryoneMask = (uint)item.Permissions.EveryoneMask;
|
||||
update.ItemData[0].Flags = item.Flags;
|
||||
update.ItemData[0].FolderID = item.ParentID;
|
||||
update.ItemData[0].GroupID = item.GroupID;
|
||||
update.ItemData[0].GroupMask = (uint)item.Permissions.GroupMask;
|
||||
update.ItemData[0].GroupOwned = item.GroupOwned;
|
||||
update.ItemData[0].InvType = (sbyte)item.InventoryType;
|
||||
update.ItemData[0].ItemID = item.ID;
|
||||
update.ItemData[0].Name = Utils.StringToBytes(item.Name);
|
||||
update.ItemData[0].NextOwnerMask = (uint)item.Permissions.NextOwnerMask;
|
||||
update.ItemData[0].OwnerID = item.OwnerID;
|
||||
update.ItemData[0].OwnerMask = (uint)item.Permissions.OwnerMask;
|
||||
update.ItemData[0].SalePrice = item.SalePrice;
|
||||
update.ItemData[0].SaleType = (byte)item.SaleType;
|
||||
update.ItemData[0].Type = (sbyte)item.InventoryType;
|
||||
}
|
||||
else
|
||||
{
|
||||
InventoryFolder folder = (InventoryFolder)obj;
|
||||
|
||||
update.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[0];
|
||||
update.FolderData = new BulkUpdateInventoryPacket.FolderDataBlock[1];
|
||||
update.FolderData[0] = new BulkUpdateInventoryPacket.FolderDataBlock();
|
||||
update.FolderData[0].FolderID = folder.ID;
|
||||
update.FolderData[0].Name = Utils.StringToBytes(folder.Name);
|
||||
update.FolderData[0].ParentID = folder.ParentID;
|
||||
update.FolderData[0].Type = (sbyte)folder.PreferredType;
|
||||
}
|
||||
|
||||
Server.UDP.SendPacket(agent.AgentID, update, PacketCategory.Inventory);
|
||||
}
|
||||
|
||||
void MoveInventory(Agent agent, Dictionary<UUID, InventoryObject> agentInventory, UUID objectID,
|
||||
UUID newFolderID, string newName, UUID transactionID, uint callbackID)
|
||||
{
|
||||
InventoryObject obj;
|
||||
if (agentInventory.TryGetValue(objectID, out obj))
|
||||
@@ -531,6 +575,8 @@ namespace Simian.Extensions
|
||||
Logger.Log("MoveInventory called with an unknown destination folder " + newFolderID,
|
||||
Helpers.LogLevel.Warning);
|
||||
}
|
||||
|
||||
SendBulkUpdate(agent, obj, transactionID, callbackID);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -662,7 +708,7 @@ namespace Simian.Extensions
|
||||
|
||||
public UUID CreateItem(UUID agentID, string name, string description, InventoryType invType, AssetType type,
|
||||
UUID assetID, UUID parentID, PermissionMask ownerMask, PermissionMask nextOwnerMask, UUID ownerID,
|
||||
UUID creatorID, UUID transactionID, uint callbackID)
|
||||
UUID creatorID, UUID transactionID, uint callbackID, bool sendPacket)
|
||||
{
|
||||
Dictionary<UUID, InventoryObject> agentInventory = GetAgentInventory(agentID);
|
||||
|
||||
@@ -716,12 +762,7 @@ namespace Simian.Extensions
|
||||
update.InventoryData[0].BaseMask = (uint)PermissionMask.All;
|
||||
update.InventoryData[0].CallbackID = callbackID;
|
||||
update.InventoryData[0].CreationDate = (int)Utils.DateTimeToUnixTime(item.CreationDate);
|
||||
update.InventoryData[0].CRC =
|
||||
Helpers.InventoryCRC((int)Utils.DateTimeToUnixTime(item.CreationDate), (byte)item.SaleType,
|
||||
(sbyte)item.InventoryType, (sbyte)item.AssetType, item.AssetID, item.GroupID, item.SalePrice,
|
||||
item.OwnerID, item.CreatorID, item.ID, item.ParentID, (uint)item.Permissions.EveryoneMask,
|
||||
item.Flags, (uint)item.Permissions.NextOwnerMask, (uint)item.Permissions.GroupMask,
|
||||
(uint)item.Permissions.OwnerMask);
|
||||
update.InventoryData[0].CRC = item.CRC;
|
||||
update.InventoryData[0].CreatorID = item.CreatorID;
|
||||
update.InventoryData[0].Description = Utils.StringToBytes(item.Description);
|
||||
update.InventoryData[0].EveryoneMask = (uint)item.Permissions.EveryoneMask;
|
||||
@@ -740,7 +781,9 @@ namespace Simian.Extensions
|
||||
update.InventoryData[0].SaleType = (byte)item.SaleType;
|
||||
update.InventoryData[0].Type = (sbyte)item.AssetType;
|
||||
|
||||
Server.UDP.SendPacket(agentID, update, PacketCategory.Inventory);
|
||||
if (sendPacket)
|
||||
Server.UDP.SendPacket(agentID, update, PacketCategory.Inventory);
|
||||
|
||||
return item.ID;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -565,7 +565,7 @@ namespace Simian.Extensions
|
||||
InventoryFolder trash = (InventoryFolder)invObj;
|
||||
Server.Inventory.CreateItem(agent.AgentID, obj.Prim.Properties.Name, obj.Prim.Properties.Description, InventoryType.Object,
|
||||
AssetType.Object, obj.Prim.ID, trash.ID, PermissionMask.All, PermissionMask.All, agent.AgentID,
|
||||
obj.Prim.Properties.CreatorID, derez.AgentBlock.TransactionID, 0);
|
||||
obj.Prim.Properties.CreatorID, derez.AgentBlock.TransactionID, 0, true);
|
||||
Server.Scene.ObjectRemove(this, obj);
|
||||
|
||||
Logger.DebugLog(String.Format("Derezzed prim {0} to agent inventory trash", obj.Prim.LocalID));
|
||||
|
||||
Reference in New Issue
Block a user