From 49c722fef8d67f05f5db563264eb002e2aa7927b Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 22 Feb 2007 12:36:31 +0000 Subject: [PATCH] * Cleaned up the GroupManager example program and converted it to use Utilities.AssetManager for more reliable image downloads * Cleaned up the locking code in the image downloading portion of Utilities.AssetManager * Added another common CAPS error to the ignore list git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1001 52acb1d6-8a22-11de-b505-999d5b087335 --- libsecondlife-cs/AssetSystem/AssetManager.cs | 3 +- libsecondlife-cs/NetworkManager.cs | 5 +- .../examples/groupmanager/frmGroupInfo.cs | 136 +++++++++------- .../examples/groupmanager/frmGroupManager.cs | 1 + .../examples/groupmanager/groupmanager.csproj | 4 + .../libsecondlife.Utilities/Assets.cs | 151 ++++++++---------- 6 files changed, 155 insertions(+), 145 deletions(-) diff --git a/libsecondlife-cs/AssetSystem/AssetManager.cs b/libsecondlife-cs/AssetSystem/AssetManager.cs index f0ce322a..abf39278 100644 --- a/libsecondlife-cs/AssetSystem/AssetManager.cs +++ b/libsecondlife-cs/AssetSystem/AssetManager.cs @@ -383,7 +383,8 @@ namespace libsecondlife.AssetSystem // Lookup the request for this packet if (!htDownloadRequests.ContainsKey(TransferID)) { - slClient.Log("Received unexpected TransferPacket packet." + Environment.NewLine + packet.ToString(), Helpers.LogLevel.Warning); + //slClient.Log("Received unexpected TransferPacket packet." + Environment.NewLine + packet.ToString(), + // Helpers.LogLevel.Warning); return; } AssetRequestDownload request = htDownloadRequests[TransferID]; diff --git a/libsecondlife-cs/NetworkManager.cs b/libsecondlife-cs/NetworkManager.cs index 006bdf5f..06a55fb1 100644 --- a/libsecondlife-cs/NetworkManager.cs +++ b/libsecondlife-cs/NetworkManager.cs @@ -207,10 +207,11 @@ namespace libsecondlife case WebExceptionStatus.ProtocolError: case WebExceptionStatus.Timeout: case WebExceptionStatus.ConnectFailure: - Client.DebugLog("CAPS error: " + e.Status.ToString()); + case WebExceptionStatus.ReceiveFailure: + Client.DebugLog("CAPS error, " + e.Status.ToString()); goto Start; default: - Client.Log("CAPS error, " + e.Status.ToString(), Helpers.LogLevel.Warning); + Client.Log("Unhandled CAPS error, " + e.Status.ToString(), Helpers.LogLevel.Warning); return null; } } diff --git a/libsecondlife-cs/examples/groupmanager/frmGroupInfo.cs b/libsecondlife-cs/examples/groupmanager/frmGroupInfo.cs index 2ab1ba33..1f2f6bde 100644 --- a/libsecondlife-cs/examples/groupmanager/frmGroupInfo.cs +++ b/libsecondlife-cs/examples/groupmanager/frmGroupInfo.cs @@ -8,20 +8,10 @@ using System.Windows.Forms; using System.IO; using libsecondlife; using libsecondlife.AssetSystem; +using libsecondlife.Utilities.Assets; namespace groupmanager { - public class GroupMemberData - { - public LLUUID ID; - public string Name; - public string Title; - public string LastOnline; - public ulong Powers; - public bool IsOwner; - public int Contribution; - } - public partial class frmGroupInfo : Form { Group Group; @@ -31,6 +21,7 @@ namespace groupmanager Dictionary Titles = new Dictionary(); Dictionary MemberData = new Dictionary(); Dictionary Names = new Dictionary(); + libsecondlife.Utilities.Assets.AssetManager Assets; public frmGroupInfo(Group group, SecondLife client) { @@ -44,6 +35,8 @@ namespace groupmanager Group = group; Client = client; + Assets = new libsecondlife.Utilities.Assets.AssetManager(Client); + Assets.OnImageReceived += new libsecondlife.Utilities.Assets.AssetManager.ImageReceivedCallback(Assets_OnImageReceived); Client.Avatars.OnAvatarNames += new AvatarManager.AvatarNamesCallback(AvatarNamesHandler); @@ -65,19 +58,18 @@ namespace groupmanager Invoke(new MethodInvoker(UpdateProfile)); - byte[] j2cdata; if (Group.InsigniaID != null) { - j2cdata = Client.Images.RequestImage(Group.InsigniaID); - } - else - { - // ??? - j2cdata = Client.Images.RequestImage("c77a1c21-e604-7d2c-2c89-5539ce853466"); + Assets.RequestImage(Group.InsigniaID, ImageType.Normal, 113000.0f, 0); } + } - Image image = OpenJPEGNet.OpenJPEG.DecodeToImage(j2cdata); - picInsignia.Image = image; + void Assets_OnImageReceived(ImageDownload image) + { + if (image.Success) + { + picInsignia.Image = OpenJPEGNet.OpenJPEG.DecodeToImage(image.AssetData); + } } private void UpdateProfile() @@ -104,33 +96,40 @@ namespace groupmanager } } - Invoke(new MethodInvoker(UpdateNames)); + UpdateNames(); } private void UpdateNames() { - lock (Names) + if (this.InvokeRequired) { - if (Profile.FounderID != null && Names.ContainsKey(Profile.FounderID)) + Invoke(new MethodInvoker(UpdateNames)); + } + else + { + lock (Names) { - lblFoundedBy.Text = "Founded by " + Names[Profile.FounderID]; - } - - lock (MemberData) - { - foreach (KeyValuePair name in Names) + if (Profile.FounderID != null && Names.ContainsKey(Profile.FounderID)) { - if (!MemberData.ContainsKey(name.Key)) - { - MemberData[name.Key] = new GroupMemberData(); - } + lblFoundedBy.Text = "Founded by " + Names[Profile.FounderID]; + } - MemberData[name.Key].Name = name.Value; + lock (MemberData) + { + foreach (KeyValuePair name in Names) + { + if (!MemberData.ContainsKey(name.Key)) + { + MemberData[name.Key] = new GroupMemberData(); + } + + MemberData[name.Key].Name = name.Value; + } } } - } - UpdateMemberList(); + UpdateMemberList(); + } } private void UpdateMemberList() @@ -184,48 +183,73 @@ namespace groupmanager { Members = members; - Invoke(new MethodInvoker(UpdateMembers)); + UpdateMembers(); } private void UpdateMembers() { - List requestids = new List(); - - lock (Members) + if (this.InvokeRequired) { - lock (MemberData) + Invoke(new MethodInvoker(UpdateMembers)); + } + else + { + List requestids = new List(); + + lock (Members) { - foreach (GroupMember member in Members.Values) + lock (MemberData) { - GroupMemberData memberData = new GroupMemberData(); - memberData.ID = member.ID; - memberData.IsOwner = member.IsOwner; - memberData.LastOnline = member.OnlineStatus; - memberData.Powers = member.Powers; - memberData.Title = member.Title; - memberData.Contribution = member.Contribution; + foreach (GroupMember member in Members.Values) + { + GroupMemberData memberData = new GroupMemberData(); + memberData.ID = member.ID; + memberData.IsOwner = member.IsOwner; + memberData.LastOnline = member.OnlineStatus; + memberData.Powers = member.Powers; + memberData.Title = member.Title; + memberData.Contribution = member.Contribution; - MemberData[member.ID] = memberData; + MemberData[member.ID] = memberData; - // Add this ID to the name request batch - requestids.Add(member.ID); + // Add this ID to the name request batch + requestids.Add(member.ID); + } } } - } - Client.Avatars.RequestAvatarNames(requestids); + Client.Avatars.RequestAvatarNames(requestids); + } } private void GroupTitlesHandler(Dictionary titles) { Titles = titles; - Invoke(new MethodInvoker(UpdateTitles)); + UpdateTitles(); } private void UpdateTitles() { - ; + if (this.InvokeRequired) + { + Invoke(new MethodInvoker(UpdateTitles)); + } + else + { + // TODO: Finish this + } } } + + public class GroupMemberData + { + public LLUUID ID; + public string Name; + public string Title; + public string LastOnline; + public ulong Powers; + public bool IsOwner; + public int Contribution; + } } diff --git a/libsecondlife-cs/examples/groupmanager/frmGroupManager.cs b/libsecondlife-cs/examples/groupmanager/frmGroupManager.cs index 19f1750d..555dd578 100644 --- a/libsecondlife-cs/examples/groupmanager/frmGroupManager.cs +++ b/libsecondlife-cs/examples/groupmanager/frmGroupManager.cs @@ -64,6 +64,7 @@ namespace groupmanager { groupBox.Enabled = true; + Client.Throttle.Set(); Client.Groups.BeginGetCurrentGroups(new GroupManager.CurrentGroupsCallback(GroupsUpdatedHandler)); } else diff --git a/libsecondlife-cs/examples/groupmanager/groupmanager.csproj b/libsecondlife-cs/examples/groupmanager/groupmanager.csproj index 66a2c615..380c5c4b 100644 --- a/libsecondlife-cs/examples/groupmanager/groupmanager.csproj +++ b/libsecondlife-cs/examples/groupmanager/groupmanager.csproj @@ -98,6 +98,10 @@ {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} False + + {CE5E06C2-2428-416B-ADC1-F1FE16A0FB27} + libsecondlife.Utilities + diff --git a/libsecondlife-cs/libsecondlife.Utilities/Assets.cs b/libsecondlife-cs/libsecondlife.Utilities/Assets.cs index 295815ff..75906855 100644 --- a/libsecondlife-cs/libsecondlife.Utilities/Assets.cs +++ b/libsecondlife-cs/libsecondlife.Utilities/Assets.cs @@ -596,11 +596,6 @@ namespace libsecondlife.Utilities.Assets lock (Transfers) Transfers[transferID] = upload; SendNextUploadPacket(upload); } - else - { - Client.Log("Received an unrecognized RequestXfer packet:" + Environment.NewLine + request.ToString(), - Helpers.LogLevel.Warning); - } } private void ConfirmXferPacketHandler(Packet packet, Simulator simulator) @@ -614,11 +609,6 @@ namespace libsecondlife.Utilities.Assets { SendNextUploadPacket((AssetUpload)Transfers[transferID]); } - else - { - Client.Log("Received a ConfirmXfer packet for an unknown transfer " + confirm.XferID.ID + - ", packet number " + confirm.XferID.Packet, Helpers.LogLevel.Warning); - } } private void AssetUploadCompleteHandler(Packet packet, Simulator simulator) @@ -658,11 +648,6 @@ namespace libsecondlife.Utilities.Assets try { OnAssetUploaded((AssetUpload)foundTransfer.Value); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } - else - { - Client.Log("Got an AssetUploadComplete packet for an unknown AssetID " + - complete.AssetBlock.UUID.ToStringHyphenated(), Helpers.LogLevel.Warning); - } } } @@ -674,41 +659,43 @@ namespace libsecondlife.Utilities.Assets public void ImageDataHandler(Packet packet, Simulator simulator) { ImageDataPacket data = (ImageDataPacket)packet; + ImageDownload transfer = null; Client.DebugLog("Received first " + data.ImageData.Data.Length + " bytes for image " + data.ImageID.ID.ToStringHyphenated()); - if (Transfers.ContainsKey(data.ImageID.ID)) + lock (Transfers) { - ImageDownload transfer = (ImageDownload)Transfers[data.ImageID.ID]; - - transfer.Codec = data.ImageID.Codec; - transfer.PacketCount = data.ImageID.Packets; - transfer.Size = (int)data.ImageID.Size; - transfer.AssetData = new byte[transfer.Size]; - Array.Copy(data.ImageData.Data, transfer.AssetData, data.ImageData.Data.Length); - transfer.InitialDataSize = data.ImageData.Data.Length; - transfer.Transferred += data.ImageData.Data.Length; - - transfer.HeaderReceivedEvent.Set(); - - // Check if we downloaded the full image - if (transfer.Transferred >= transfer.Size) + if (Transfers.ContainsKey(data.ImageID.ID)) { - lock (Transfers) Transfers.Remove(transfer.ID); - transfer.Success = true; + transfer = (ImageDownload)Transfers[data.ImageID.ID]; - if (OnImageReceived != null) + transfer.Codec = data.ImageID.Codec; + transfer.PacketCount = data.ImageID.Packets; + transfer.Size = (int)data.ImageID.Size; + transfer.AssetData = new byte[transfer.Size]; + Array.Copy(data.ImageData.Data, transfer.AssetData, data.ImageData.Data.Length); + transfer.InitialDataSize = data.ImageData.Data.Length; + transfer.Transferred += data.ImageData.Data.Length; + + // Check if we downloaded the full image + if (transfer.Transferred >= transfer.Size) { - try { OnImageReceived(transfer); } - catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } + Transfers.Remove(transfer.ID); + transfer.Success = true; } } } - else + + if (transfer != null) { - Client.Log("Received an ImageData packet for an image we didn't request, ID: " + data.ImageID.ID, - Helpers.LogLevel.Warning); + if (OnImageReceived != null && transfer.Transferred >= transfer.Size) + { + try { OnImageReceived(transfer); } + catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } + } + + transfer.HeaderReceivedEvent.Set(); } } @@ -718,59 +705,53 @@ namespace libsecondlife.Utilities.Assets public void ImagePacketHandler(Packet packet, Simulator simulator) { ImagePacketPacket image = (ImagePacketPacket)packet; + ImageDownload transfer = null; - if (Transfers.ContainsKey(image.ImageID.ID)) + lock (Transfers) { - ImageDownload transfer = (ImageDownload)Transfers[image.ImageID.ID]; - - if (transfer.Size == 0) + if (Transfers.ContainsKey(image.ImageID.ID)) { - // We haven't received the header yet, block until it's received or times out - transfer.HeaderReceivedEvent.WaitOne(1000 * 20, false); + transfer = (ImageDownload)Transfers[image.ImageID.ID]; if (transfer.Size == 0) { + // We haven't received the header yet, block until it's received or times out + transfer.HeaderReceivedEvent.WaitOne(1000 * 20, false); - Client.Log("Timed out while waiting for the image header to download for " + - transfer.ID.ToStringHyphenated(), Helpers.LogLevel.Warning); - - lock (Transfers) Transfers.Remove(transfer.ID); - - // Fire the event with our transfer that contains Success = false; - if (OnImageReceived != null) + if (transfer.Size == 0) { - try { OnImageReceived(transfer); } - catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } + Client.Log("Timed out while waiting for the image header to download for " + + transfer.ID.ToStringHyphenated(), Helpers.LogLevel.Warning); + + transfer.Success = false; + Transfers.Remove(transfer.ID); + goto Callback; } - - return; } - } - // The header is downloaded, we can insert this data in to the proper position - Array.Copy(image.ImageData.Data, 0, transfer.AssetData, transfer.InitialDataSize + (1000 * (image.ImageID.Packet - 1)), image.ImageData.Data.Length); - transfer.Transferred += image.ImageData.Data.Length; + // The header is downloaded, we can insert this data in to the proper position + Array.Copy(image.ImageData.Data, 0, transfer.AssetData, transfer.InitialDataSize + + (1000 * (image.ImageID.Packet - 1)), image.ImageData.Data.Length); + transfer.Transferred += image.ImageData.Data.Length; - Client.DebugLog("Received " + image.ImageData.Data.Length + "/" + transfer.Transferred + - "/" + transfer.Size + " bytes for image " + image.ImageID.ID.ToStringHyphenated()); + Client.DebugLog("Received " + image.ImageData.Data.Length + "/" + transfer.Transferred + + "/" + transfer.Size + " bytes for image " + image.ImageID.ID.ToStringHyphenated()); - // Check if we downloaded the full image - if (transfer.Transferred >= transfer.Size) - { - transfer.Success = true; - lock (Transfers) Transfers.Remove(transfer.ID); - - if (OnImageReceived != null) + // Check if we downloaded the full image + if (transfer.Transferred >= transfer.Size) { - try { OnImageReceived(transfer); } - catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } + transfer.Success = true; + Transfers.Remove(transfer.ID); } } } - else + + Callback: + + if (transfer != null && OnImageReceived != null && (transfer.Transferred >= transfer.Size || transfer.Size == 0)) { - Client.Log("Received an ImagePacket packet for an image we didn't request, ID: " + image.ImageID.ID, - Helpers.LogLevel.Warning); + try { OnImageReceived(transfer); } + catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } } @@ -780,25 +761,23 @@ namespace libsecondlife.Utilities.Assets public void ImageNotInDatabaseHandler(Packet packet, Simulator simulator) { ImageNotInDatabasePacket notin = (ImageNotInDatabasePacket)packet; + ImageDownload transfer = null; - if (Transfers.ContainsKey(notin.ImageID.ID)) + lock (Transfers) { - ImageDownload transfer = (ImageDownload)Transfers[notin.ImageID.ID]; - - transfer.NotFound = true; - lock (Transfers) Transfers.Remove(transfer.ID); - - // Fire the event with our transfer that contains Success = false; - if (OnImageReceived != null) + if (Transfers.ContainsKey(notin.ImageID.ID)) { - try { OnImageReceived(transfer); } - catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } + transfer = (ImageDownload)Transfers[notin.ImageID.ID]; + transfer.NotFound = true; + Transfers.Remove(transfer.ID); } } - else + + // Fire the event with our transfer that contains Success = false; + if (transfer != null && OnImageReceived != null) { - Client.Log("Received an ImageNotInDatabase packet for an image we didn't request, ID: " + - notin.ImageID.ID, Helpers.LogLevel.Warning); + try { OnImageReceived(transfer); } + catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } } }