aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
authorDan Lake2012-02-01 16:25:35 -0800
committerDan Lake2012-02-01 16:25:35 -0800
commitc10193c72b1f029a958f04d2f5d7ee384e693aaa (patch)
tree052ec7e973c15b158310511197affad14eb9c64f /OpenSim/Region/ClientStack/Linden
parentTrigger event when prims are scheduled for an update. This gives modules earl... (diff)
parentSmall optimization to last commit (diff)
downloadopensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.zip
opensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.gz
opensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.bz2
opensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs75
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs151
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs63
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs81
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs135
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs160
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2bin0 -> 24410 bytes
9 files changed, 616 insertions, 54 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 2347cf2..cf0c28b 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
94 private static readonly string m_notecardUpdatePath = "0004/"; 94 private static readonly string m_notecardUpdatePath = "0004/";
95 private static readonly string m_notecardTaskUpdatePath = "0005/"; 95 private static readonly string m_notecardTaskUpdatePath = "0005/";
96 // private static readonly string m_fetchInventoryPath = "0006/"; 96 // private static readonly string m_fetchInventoryPath = "0006/";
97 private static readonly string m_copyFromNotecardPath = "0007/";
97 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. 98 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
98 99
99 100
@@ -180,6 +181,7 @@ namespace OpenSim.Region.ClientStack.Linden
180 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 181 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
181 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 182 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
182 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 183 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
184 m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
183 185
184 // As of RC 1.22.9 of the Linden client this is 186 // As of RC 1.22.9 of the Linden client this is
185 // supported 187 // supported
@@ -366,7 +368,7 @@ namespace OpenSim.Region.ClientStack.Linden
366 368
367 if (mm != null) 369 if (mm != null)
368 { 370 {
369 if (!mm.UploadCovered(client, mm.UploadCharge)) 371 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
370 { 372 {
371 if (client != null) 373 if (client != null)
372 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 374 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
@@ -723,6 +725,75 @@ namespace OpenSim.Region.ClientStack.Linden
723 725
724 return LLSDHelpers.SerialiseLLSDReply(uploadResponse); 726 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
725 } 727 }
728
729 /// <summary>
730 /// Called by the CopyInventoryFromNotecard caps handler.
731 /// </summary>
732 /// <param name="request"></param>
733 /// <param name="path"></param>
734 /// <param name="param"></param>
735 public string CopyInventoryFromNotecard(string request, string path, string param,
736 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
737 {
738 Hashtable response = new Hashtable();
739 response["int_response_code"] = 404;
740 response["content_type"] = "text/plain";
741 response["keepalive"] = false;
742 response["str_response_string"] = "";
743
744 try
745 {
746 OSDMap content = (OSDMap)OSDParser.DeserializeLLSDXml(request);
747 UUID objectID = content["object-id"].AsUUID();
748 UUID notecardID = content["notecard-id"].AsUUID();
749 UUID folderID = content["folder-id"].AsUUID();
750 UUID itemID = content["item-id"].AsUUID();
751
752 // m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, FolderID:{0}, ItemID:{1}, NotecardID:{2}, ObjectID:{3}", folderID, itemID, notecardID, objectID);
753
754 if (objectID != UUID.Zero)
755 {
756 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
757 if (part != null)
758 {
759 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
760 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
761 {
762 return LLSDHelpers.SerialiseLLSDReply(response);
763 }
764 }
765 }
766
767 InventoryItemBase item = null;
768 InventoryItemBase copyItem = null;
769 IClientAPI client = null;
770
771 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
772 item = m_Scene.InventoryService.GetItem(new InventoryItemBase(itemID));
773 if (item != null)
774 {
775 copyItem = m_Scene.GiveInventoryItem(m_HostCapsObj.AgentID, item.Owner, itemID, folderID);
776 if (copyItem != null && client != null)
777 {
778 m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
779 client.SendBulkUpdateInventory(copyItem);
780 }
781 }
782 else
783 {
784 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard - Failed to retrieve item {0} from notecard {1}", itemID, notecardID);
785 if (client != null)
786 client.SendAlertMessage("Failed to retrieve item");
787 }
788 }
789 catch (Exception e)
790 {
791 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard : {0}", e.ToString());
792 }
793
794 response["int_response_code"] = 200;
795 return LLSDHelpers.SerialiseLLSDReply(response);
796 }
726 } 797 }
727 798
728 public class AssetUploader 799 public class AssetUploader
@@ -1018,4 +1089,4 @@ namespace OpenSim.Region.ClientStack.Linden
1018 fs.Close(); 1089 fs.Close();
1019 } 1090 }
1020 } 1091 }
1021} \ No newline at end of file 1092}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
new file mode 100644
index 0000000..14501c7
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
@@ -0,0 +1,151 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using Mono.Addins;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40using Caps = OpenSim.Framework.Capabilities.Caps;
41using OpenSim.Capabilities.Handlers;
42
43namespace OpenSim.Region.ClientStack.Linden
44{
45 /// <summary>
46 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class FetchInventory2Module : INonSharedRegionModule
50 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 public bool Enabled { get; private set; }
54
55 private Scene m_scene;
56
57 private IInventoryService m_inventoryService;
58
59 private string m_fetchInventory2Url;
60
61 private FetchInventory2Handler m_fetchHandler;
62
63 #region ISharedRegionModule Members
64
65 public void Initialise(IConfigSource source)
66 {
67 IConfig config = source.Configs["ClientStack.LindenCaps"];
68 if (config == null)
69 return;
70
71 m_fetchInventory2Url = config.GetString("Cap_FetchInventory2", string.Empty);
72
73 if (m_fetchInventory2Url != string.Empty)
74 Enabled = true;
75 }
76
77 public void AddRegion(Scene s)
78 {
79 if (!Enabled)
80 return;
81
82 m_scene = s;
83 }
84
85 public void RemoveRegion(Scene s)
86 {
87 if (!Enabled)
88 return;
89
90 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
91 m_scene = null;
92 }
93
94 public void RegionLoaded(Scene s)
95 {
96 if (!Enabled)
97 return;
98
99 m_inventoryService = m_scene.InventoryService;
100
101 // We'll reuse the same handler for all requests.
102 if (m_fetchInventory2Url == "localhost")
103 m_fetchHandler = new FetchInventory2Handler(m_inventoryService);
104
105 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
106 }
107
108 public void PostInitialise() {}
109
110 public void Close() {}
111
112 public string Name { get { return "FetchInventory2Module"; } }
113
114 public Type ReplaceableInterface
115 {
116 get { return null; }
117 }
118
119 #endregion
120
121 private void RegisterCaps(UUID agentID, Caps caps)
122 {
123 RegisterFetchCap(agentID, caps, "FetchInventory2", m_fetchInventory2Url);
124 }
125
126 private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url)
127 {
128 string capUrl;
129
130 if (url == "localhost")
131 {
132 capUrl = "/CAPS/" + UUID.Random();
133
134 IRequestHandler reqHandler
135 = new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest);
136
137 caps.RegisterHandler(capName, reqHandler);
138 }
139 else
140 {
141 capUrl = url;
142
143 caps.RegisterHandler(capName, capUrl);
144 }
145
146// m_log.DebugFormat(
147// "[FETCH INVENTORY2 MODULE]: Registered capability {0} at {1} in region {2} for {3}",
148// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
149 }
150 }
151}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
index b2f04f9..aed03b3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
@@ -147,7 +147,7 @@ namespace OpenSim.Region.ClientStack.Linden
147 { 147 {
148 if (m_scene.TryGetClient(agentID, out client)) 148 if (m_scene.TryGetClient(agentID, out client))
149 { 149 {
150 if (!mm.UploadCovered(client, mm.UploadCharge)) 150 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
151 { 151 {
152 if (client != null) 152 if (client != null)
153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
@@ -268,4 +268,4 @@ namespace OpenSim.Region.ClientStack.Linden
268 268
269 } 269 }
270 } 270 }
271} \ No newline at end of file 271}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index cb9692a..afbe56b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -45,6 +45,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
45 private const int IMAGE_PACKET_SIZE = 1000; 45 private const int IMAGE_PACKET_SIZE = 1000;
46 private const int FIRST_PACKET_SIZE = 600; 46 private const int FIRST_PACKET_SIZE = 600;
47 47
48 /// <summary>
49 /// If we've requested an asset but not received it in this ticks timeframe, then allow a duplicate
50 /// request from the client to trigger a fresh asset request.
51 /// </summary>
52 /// <remarks>
53 /// There are 10,000 ticks in a millisecond
54 /// </remarks>
55 private const int ASSET_REQUEST_TIMEOUT = 100000000;
56
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 58
50 public uint LastSequence; 59 public uint LastSequence;
@@ -57,8 +66,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
57 public UUID AgentID; 66 public UUID AgentID;
58 public IInventoryAccessModule InventoryAccessModule; 67 public IInventoryAccessModule InventoryAccessModule;
59 private OpenJPEG.J2KLayerInfo[] m_layers; 68 private OpenJPEG.J2KLayerInfo[] m_layers;
69
70 /// <summary>
71 /// Has this request decoded the asset data?
72 /// </summary>
60 public bool IsDecoded { get; private set; } 73 public bool IsDecoded { get; private set; }
74
75 /// <summary>
76 /// Has this request received the required asset data?
77 /// </summary>
61 public bool HasAsset { get; private set; } 78 public bool HasAsset { get; private set; }
79
80 /// <summary>
81 /// Time in milliseconds at which the asset was requested.
82 /// </summary>
83 public long AssetRequestTime { get; private set; }
84
62 public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle; 85 public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle;
63 86
64 private uint m_currentPacket; 87 private uint m_currentPacket;
@@ -82,7 +105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
82 /// <param name="packetsToSend">Maximum number of packets to send during this call</param> 105 /// <param name="packetsToSend">Maximum number of packets to send during this call</param>
83 /// <param name="packetsSent">Number of packets sent during this call</param> 106 /// <param name="packetsSent">Number of packets sent during this call</param>
84 /// <returns>True if the transfer completes at the current discard level, otherwise false</returns> 107 /// <returns>True if the transfer completes at the current discard level, otherwise false</returns>
85 public bool SendPackets(LLClientView client, int packetsToSend, out int packetsSent) 108 public bool SendPackets(IClientAPI client, int packetsToSend, out int packetsSent)
86 { 109 {
87 packetsSent = 0; 110 packetsSent = 0;
88 111
@@ -102,7 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
102 { 125 {
103 m_currentPacket = 2; 126 m_currentPacket = 2;
104 } 127 }
105 128
106 while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket) 129 while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket)
107 { 130 {
108 sendMore = SendPacket(client); 131 sendMore = SendPacket(client);
@@ -114,17 +137,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
114 return (m_currentPacket > m_stopPacket); 137 return (m_currentPacket > m_stopPacket);
115 } 138 }
116 139
140 /// <summary>
141 /// This is where we decide what we need to update
142 /// and assign the real discardLevel and packetNumber
143 /// assuming of course that the connected client might be bonkers
144 /// </summary>
117 public void RunUpdate() 145 public void RunUpdate()
118 { 146 {
119 //This is where we decide what we need to update
120 //and assign the real discardLevel and packetNumber
121 //assuming of course that the connected client might be bonkers
122
123 if (!HasAsset) 147 if (!HasAsset)
124 { 148 {
125 if (!m_assetRequested) 149 if (!m_assetRequested || DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT)
126 { 150 {
151// m_log.DebugFormat(
152// "[J2KIMAGE]: Requesting asset {0} from request in packet {1}, already requested? {2}, due to timeout? {3}",
153// TextureID, LastSequence, m_assetRequested, DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT);
154
127 m_assetRequested = true; 155 m_assetRequested = true;
156 AssetRequestTime = DateTime.UtcNow.Ticks;
157
128 AssetService.Get(TextureID.ToString(), this, AssetReceived); 158 AssetService.Get(TextureID.ToString(), this, AssetReceived);
129 } 159 }
130 } 160 }
@@ -137,6 +167,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
137 { 167 {
138 //Request decode 168 //Request decode
139 m_decodeRequested = true; 169 m_decodeRequested = true;
170
171// m_log.DebugFormat("[J2KIMAGE]: Requesting decode of asset {0}", TextureID);
172
140 // Do we have a jpeg decoder? 173 // Do we have a jpeg decoder?
141 if (J2KDecoder != null) 174 if (J2KDecoder != null)
142 { 175 {
@@ -149,7 +182,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
149 // Send it off to the jpeg decoder 182 // Send it off to the jpeg decoder
150 J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback); 183 J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
151 } 184 }
152
153 } 185 }
154 else 186 else
155 { 187 {
@@ -208,7 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
208 } 240 }
209 } 241 }
210 242
211 private bool SendFirstPacket(LLClientView client) 243 private bool SendFirstPacket(IClientAPI client)
212 { 244 {
213 if (client == null) 245 if (client == null)
214 return false; 246 return false;
@@ -243,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
243 return false; 275 return false;
244 } 276 }
245 277
246 private bool SendPacket(LLClientView client) 278 private bool SendPacket(IClientAPI client)
247 { 279 {
248 if (client == null) 280 if (client == null)
249 return false; 281 return false;
@@ -328,14 +360,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
328 { 360 {
329 if (m_currentPacket == 0) 361 if (m_currentPacket == 0)
330 return 0; 362 return 0;
363
331 if (m_currentPacket == 1) 364 if (m_currentPacket == 1)
332 return FIRST_PACKET_SIZE; 365 return FIRST_PACKET_SIZE;
333 366
334 int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE; 367 int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
368
335 if (result < 0) 369 if (result < 0)
336 {
337 result = FIRST_PACKET_SIZE; 370 result = FIRST_PACKET_SIZE;
338 } 371
339 return result; 372 return result;
340 } 373 }
341 374
@@ -372,9 +405,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
372 405
373 private void AssetReceived(string id, Object sender, AssetBase asset) 406 private void AssetReceived(string id, Object sender, AssetBase asset)
374 { 407 {
408// m_log.DebugFormat(
409// "[J2KIMAGE]: Received asset {0} ({1} bytes)", id, asset != null ? asset.Data.Length.ToString() : "n/a");
410
375 UUID assetID = UUID.Zero; 411 UUID assetID = UUID.Zero;
376 if (asset != null) 412 if (asset != null)
413 {
377 assetID = asset.FullID; 414 assetID = asset.FullID;
415 }
378 else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule)) 416 else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
379 { 417 {
380 // Unfortunately we need this here, there's no other way. 418 // Unfortunately we need this here, there's no other way.
@@ -395,7 +433,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
395 } 433 }
396 434
397 AssetDataCallback(assetID, asset); 435 AssetDataCallback(assetID, asset);
398
399 } 436 }
400 } 437 }
401} 438}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index fe28ba3..a7bf06d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -219,6 +219,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
219 public event BakeTerrain OnBakeTerrain; 219 public event BakeTerrain OnBakeTerrain;
220 public event RequestTerrain OnUploadTerrain; 220 public event RequestTerrain OnUploadTerrain;
221 public event EstateChangeInfo OnEstateChangeInfo; 221 public event EstateChangeInfo OnEstateChangeInfo;
222 public event EstateManageTelehub OnEstateManageTelehub;
222 public event EstateRestartSimRequest OnEstateRestartSimRequest; 223 public event EstateRestartSimRequest OnEstateRestartSimRequest;
223 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest; 224 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
224 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest; 225 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
@@ -304,6 +305,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
304 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 305 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
305 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients 306 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
306 307
308 /// <summary>
309 /// Handles UDP texture download.
310 /// </summary>
311 public LLImageManager ImageManager { get; private set; }
312
307 private readonly LLUDPServer m_udpServer; 313 private readonly LLUDPServer m_udpServer;
308 private readonly LLUDPClient m_udpClient; 314 private readonly LLUDPClient m_udpClient;
309 private readonly UUID m_sessionId; 315 private readonly UUID m_sessionId;
@@ -348,7 +354,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
348 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 354 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
349 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 355 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
350 protected Scene m_scene; 356 protected Scene m_scene;
351 private LLImageManager m_imageManager;
352 protected string m_firstName; 357 protected string m_firstName;
353 protected string m_lastName; 358 protected string m_lastName;
354 protected Thread m_clientThread; 359 protected Thread m_clientThread;
@@ -459,7 +464,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
459 464
460 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 465 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
461 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); 466 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
462 m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); 467 ImageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
463 m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion()); 468 m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion());
464 m_agentId = agentId; 469 m_agentId = agentId;
465 m_sessionId = sessionId; 470 m_sessionId = sessionId;
@@ -499,7 +504,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
499 IsActive = false; 504 IsActive = false;
500 505
501 // Shutdown the image manager 506 // Shutdown the image manager
502 m_imageManager.Close(); 507 ImageManager.Close();
503 508
504 // Fire the callback for this connection closing 509 // Fire the callback for this connection closing
505 if (OnConnectionClosed != null) 510 if (OnConnectionClosed != null)
@@ -577,7 +582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
577 /// Add a handler for the given packet type. 582 /// Add a handler for the given packet type.
578 /// </summary> 583 /// </summary>
579 /// <remarks> 584 /// <remarks>
580 /// The packet is handled on its own thread. If packets must be handled in the order in which thye 585 /// The packet is handled on its own thread. If packets must be handled in the order in which they
581 /// are received then please use the synchronous version of this method. 586 /// are received then please use the synchronous version of this method.
582 /// </remarks> 587 /// </remarks>
583 /// <param name="packetType"></param> 588 /// <param name="packetType"></param>
@@ -758,9 +763,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
758 OutPacket(handshake, ThrottleOutPacketType.Task); 763 OutPacket(handshake, ThrottleOutPacketType.Task);
759 } 764 }
760 765
761 /// <summary>
762 ///
763 /// </summary>
764 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 766 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
765 { 767 {
766 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); 768 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
@@ -3476,6 +3478,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3476 3478
3477 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3479 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
3478 { 3480 {
3481// m_log.DebugFormat(
3482// "[LLCLIENTVIEW]: Sending avatar appearance for {0} with {1} bytes to {2} {3}",
3483// agentID, textureEntry.Length, Name, AgentId);
3484
3479 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3485 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3480 // TODO: don't create new blocks if recycling an old packet 3486 // TODO: don't create new blocks if recycling an old packet
3481 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3487 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
@@ -3497,7 +3503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3497 3503
3498 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) 3504 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
3499 { 3505 {
3500 //m_log.DebugFormat("[CLIENT]: Sending animations to {0}", Name); 3506// m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name);
3501 3507
3502 AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation); 3508 AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation);
3503 // TODO: don't create new blocks if recycling an old packet 3509 // TODO: don't create new blocks if recycling an old packet
@@ -3532,6 +3538,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3532 /// </summary> 3538 /// </summary>
3533 public void SendAvatarDataImmediate(ISceneEntity avatar) 3539 public void SendAvatarDataImmediate(ISceneEntity avatar)
3534 { 3540 {
3541// m_log.DebugFormat(
3542// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}",
3543// avatar.Name, avatar.UUID, Name, AgentId);
3544
3535 ScenePresence presence = avatar as ScenePresence; 3545 ScenePresence presence = avatar as ScenePresence;
3536 if (presence == null) 3546 if (presence == null)
3537 return; 3547 return;
@@ -3541,7 +3551,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3541 3551
3542 objupdate.RegionData.RegionHandle = presence.RegionHandle; 3552 objupdate.RegionData.RegionHandle = presence.RegionHandle;
3543 objupdate.RegionData.TimeDilation = ushort.MaxValue; 3553 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3544 3554
3545 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3555 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3546 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); 3556 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
3547 3557
@@ -3939,7 +3949,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3939 } 3949 }
3940 3950
3941 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) 3951 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
3942 m_imageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); 3952 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
3943 } 3953 }
3944 3954
3945 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 3955 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
@@ -4473,6 +4483,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4473 OutPacket(packet, ThrottleOutPacketType.Task); 4483 OutPacket(packet, ThrottleOutPacketType.Task);
4474 } 4484 }
4475 4485
4486 public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
4487 {
4488 TelehubInfoPacket packet = (TelehubInfoPacket)PacketPool.Instance.GetPacket(PacketType.TelehubInfo);
4489 packet.TelehubBlock.ObjectID = ObjectID;
4490 packet.TelehubBlock.ObjectName = Utils.StringToBytes(ObjectName);
4491 packet.TelehubBlock.TelehubPos = ObjectPos;
4492 packet.TelehubBlock.TelehubRot = ObjectRot;
4493
4494 packet.SpawnPointBlock = new TelehubInfoPacket.SpawnPointBlockBlock[SpawnPoint.Count];
4495 for (int n = 0; n < SpawnPoint.Count; n++)
4496 {
4497 packet.SpawnPointBlock[n] = new TelehubInfoPacket.SpawnPointBlockBlock{SpawnPointPos = SpawnPoint[n]};
4498 }
4499
4500 OutPacket(packet, ThrottleOutPacketType.Task);
4501 }
4502
4476 #endregion 4503 #endregion
4477 4504
4478 #region Land Data Sending Methods 4505 #region Land Data Sending Methods
@@ -7470,7 +7497,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7470 if ((ImageType)block.Type == ImageType.Baked) 7497 if ((ImageType)block.Type == ImageType.Baked)
7471 args.Priority *= 2.0f; 7498 args.Priority *= 2.0f;
7472 7499
7473 m_imageManager.EnqueueReq(args); 7500 ImageManager.EnqueueReq(args);
7474 } 7501 }
7475 7502
7476 return true; 7503 return true;
@@ -8911,7 +8938,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8911 private bool HandleEstateOwnerMessage(IClientAPI sender, Packet Pack) 8938 private bool HandleEstateOwnerMessage(IClientAPI sender, Packet Pack)
8912 { 8939 {
8913 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack; 8940 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack;
8914 //m_log.Debug(messagePacket.ToString()); 8941 // m_log.InfoFormat("[LLCLIENTVIEW]: Packet: {0}", Utils.BytesToString(messagePacket.MethodData.Method));
8915 GodLandStatRequest handlerLandStatRequest; 8942 GodLandStatRequest handlerLandStatRequest;
8916 8943
8917 #region Packet Session and User Check 8944 #region Packet Session and User Check
@@ -9210,6 +9237,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9210 } 9237 }
9211 return true; 9238 return true;
9212 9239
9240 case "telehub":
9241 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9242 {
9243 UUID invoice = messagePacket.MethodData.Invoice;
9244 UUID SenderID = messagePacket.AgentData.AgentID;
9245 UInt32 param1 = 0u;
9246
9247 string command = (string)Utils.BytesToString(messagePacket.ParamList[0].Parameter);
9248
9249 if (command != "info ui")
9250 {
9251 try
9252 {
9253 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
9254 }
9255 catch
9256 {
9257 }
9258 }
9259
9260 EstateManageTelehub handlerEstateManageTelehub = OnEstateManageTelehub;
9261 if (handlerEstateManageTelehub != null)
9262 {
9263 handlerEstateManageTelehub(this, invoice, SenderID, command, param1);
9264 }
9265 }
9266 return true;
9267
9213 default: 9268 default:
9214 m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket); 9269 m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket);
9215 return true; 9270 return true;
@@ -9221,8 +9276,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9221 //lsrp.RequestData.ReportType; // 1 = colliders, 0 = scripts 9276 //lsrp.RequestData.ReportType; // 1 = colliders, 0 = scripts
9222 //lsrp.RequestData.RequestFlags; 9277 //lsrp.RequestData.RequestFlags;
9223 //lsrp.RequestData.Filter; 9278 //lsrp.RequestData.Filter;
9224
9225// return true;
9226 } 9279 }
9227 9280
9228 private bool HandleRequestRegionInfo(IClientAPI sender, Packet Pack) 9281 private bool HandleRequestRegionInfo(IClientAPI sender, Packet Pack)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
index e3a881f..073c357 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
@@ -55,18 +55,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 private bool m_shuttingdown; 56 private bool m_shuttingdown;
57 private AssetBase m_missingImage; 57 private AssetBase m_missingImage;
58 private LLClientView m_client; //Client we're assigned to 58 private IAssetService m_assetCache;
59 private IAssetService m_assetCache; //Asset Cache 59 private IJ2KDecoder m_j2kDecodeModule;
60 private IJ2KDecoder m_j2kDecodeModule; //Our J2K module 60
61 /// <summary>
62 /// Priority queue for determining which image to send first.
63 /// </summary>
61 private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer()); 64 private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
65
66 /// <summary>
67 /// Used to control thread access to the priority queue.
68 /// </summary>
62 private object m_syncRoot = new object(); 69 private object m_syncRoot = new object();
63 70
64 public LLClientView Client { get { return m_client; } } 71 /// <summary>
72 /// Client served by this image manager
73 /// </summary>
74 public IClientAPI Client { get; private set; }
75
65 public AssetBase MissingImage { get { return m_missingImage; } } 76 public AssetBase MissingImage { get { return m_missingImage; } }
66 77
67 public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) 78 public LLImageManager(IClientAPI client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
68 { 79 {
69 m_client = client; 80 Client = client;
70 m_assetCache = pAssetCache; 81 m_assetCache = pAssetCache;
71 82
72 if (pAssetCache != null) 83 if (pAssetCache != null)
@@ -84,7 +95,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
84 /// <param name="newRequest"></param> 95 /// <param name="newRequest"></param>
85 public void EnqueueReq(TextureRequestArgs newRequest) 96 public void EnqueueReq(TextureRequestArgs newRequest)
86 { 97 {
87 //Make sure we're not shutting down..
88 if (!m_shuttingdown) 98 if (!m_shuttingdown)
89 { 99 {
90 J2KImage imgrequest; 100 J2KImage imgrequest;
@@ -99,19 +109,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 { 109 {
100 //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID); 110 //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);
101 111
102 try 112 try
103 { 113 {
104 lock (m_syncRoot) 114 lock (m_syncRoot)
105 m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); 115 m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
106 } 116 }
107 catch (Exception) { } 117 catch (Exception) { }
108 } 118 }
109 else 119 else
110 { 120 {
111 //m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}", 121// m_log.DebugFormat(
112 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); 122// "[LL IMAGE MANAGER]: Received duplicate of existing request for {0}, start packet {1} from {2}",
123// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
124
125// m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
126// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
113 127
114 //Check the packet sequence to make sure this isn't older than 128 //Check the packet sequence to make sure this isn't older than
115 //one we've already received 129 //one we've already received
116 if (newRequest.requestSequence > imgrequest.LastSequence) 130 if (newRequest.requestSequence > imgrequest.LastSequence)
117 { 131 {
@@ -126,11 +140,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 140
127 //Update the requested priority 141 //Update the requested priority
128 imgrequest.Priority = newRequest.Priority; 142 imgrequest.Priority = newRequest.Priority;
143
129 UpdateImageInQueue(imgrequest); 144 UpdateImageInQueue(imgrequest);
130 145
131 //Run an update
132 imgrequest.RunUpdate(); 146 imgrequest.RunUpdate();
147
148// J2KImage imgrequest2 = new J2KImage(this);
149// imgrequest2.J2KDecoder = m_j2kDecodeModule;
150// imgrequest2.AssetService = m_assetCache;
151// imgrequest2.AgentID = m_client.AgentId;
152// imgrequest2.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
153// imgrequest2.DiscardLevel = newRequest.DiscardLevel;
154// imgrequest2.StartPacket = Math.Max(1, newRequest.PacketNumber);
155// imgrequest2.Priority = newRequest.Priority;
156// imgrequest2.TextureID = newRequest.RequestedAssetID;
157// imgrequest2.Priority = newRequest.Priority;
158//
159// //Add this download to the priority queue
160// AddImageToQueue(imgrequest2);
161//
162// imgrequest2.RunUpdate();
163
133 } 164 }
165// else
166// {
167// m_log.DebugFormat(
168// "[LL IMAGE MANAGER]: Ignoring duplicate of existing request for {0} (sequence {1}) from {2} as its request sequence {3} is not greater",
169// newRequest.RequestedAssetID, imgrequest.LastSequence, m_client.Name, newRequest.requestSequence);
170// }
134 } 171 }
135 } 172 }
136 else 173 else
@@ -142,14 +179,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
142 } 179 }
143 else 180 else
144 { 181 {
182// m_log.DebugFormat(
183// "[LL IMAGE MANAGER]: Received request for {0}, start packet {1} from {2}",
184// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
185
145 //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}", 186 //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
146 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); 187 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
147 188
148 imgrequest = new J2KImage(this); 189 imgrequest = new J2KImage(this);
149 imgrequest.J2KDecoder = m_j2kDecodeModule; 190 imgrequest.J2KDecoder = m_j2kDecodeModule;
150 imgrequest.AssetService = m_assetCache; 191 imgrequest.AssetService = m_assetCache;
151 imgrequest.AgentID = m_client.AgentId; 192 imgrequest.AgentID = Client.AgentId;
152 imgrequest.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>(); 193 imgrequest.InventoryAccessModule = Client.Scene.RequestModuleInterface<IInventoryAccessModule>();
153 imgrequest.DiscardLevel = newRequest.DiscardLevel; 194 imgrequest.DiscardLevel = newRequest.DiscardLevel;
154 imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber); 195 imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
155 imgrequest.Priority = newRequest.Priority; 196 imgrequest.Priority = newRequest.Priority;
@@ -159,7 +200,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 //Add this download to the priority queue 200 //Add this download to the priority queue
160 AddImageToQueue(imgrequest); 201 AddImageToQueue(imgrequest);
161 202
162 //Run an update
163 imgrequest.RunUpdate(); 203 imgrequest.RunUpdate();
164 } 204 }
165 } 205 }
@@ -176,12 +216,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
176 216
177 // If null was returned, the texture priority queue is currently empty 217 // If null was returned, the texture priority queue is currently empty
178 if (image == null) 218 if (image == null)
179 return false; 219 break;
180 220
181 if (image.IsDecoded) 221 if (image.IsDecoded)
182 { 222 {
183 int sent; 223 int sent;
184 bool imageDone = image.SendPackets(m_client, packetsToSend - packetsSent, out sent); 224 bool imageDone = image.SendPackets(Client, packetsToSend - packetsSent, out sent);
185 packetsSent += sent; 225 packetsSent += sent;
186 226
187 // If the send is complete, destroy any knowledge of this transfer 227 // If the send is complete, destroy any knowledge of this transfer
@@ -194,10 +234,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
194 // written. Undecoded textures should not be going into the priority 234 // written. Undecoded textures should not be going into the priority
195 // queue, because a high priority undecoded texture will clog up the 235 // queue, because a high priority undecoded texture will clog up the
196 // pipeline for a client 236 // pipeline for a client
197 return true; 237// m_log.DebugFormat(
238// "[LL IMAGE MANAGER]: Exiting image queue processing early on encountering undecoded image {0}",
239// image.TextureID);
240
241 break;
198 } 242 }
199 } 243 }
200 244
245// if (packetsSent != 0)
246// m_log.DebugFormat("[LL IMAGE MANAGER]: Processed {0} packets from image queue", packetsSent);
247
201 return m_priorityQueue.Count > 0; 248 return m_priorityQueue.Count > 0;
202 } 249 }
203 250
@@ -209,6 +256,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
209 m_shuttingdown = true; 256 m_shuttingdown = true;
210 } 257 }
211 258
259 /// <summary>
260 /// Clear the image queue.
261 /// </summary>
262 /// <returns>The number of requests cleared.</returns>
263 public int ClearImageQueue()
264 {
265 int requestsDeleted;
266
267 lock (m_priorityQueue)
268 {
269 requestsDeleted = m_priorityQueue.Count;
270
271 // Surprisingly, there doesn't seem to be a clear method at this time.
272 while (!m_priorityQueue.IsEmpty)
273 m_priorityQueue.DeleteMax();
274 }
275
276 return requestsDeleted;
277 }
278
279 /// <summary>
280 /// Returns an array containing all the images in the queue.
281 /// </summary>
282 /// <returns></returns>
283 public J2KImage[] GetImages()
284 {
285 lock (m_priorityQueue)
286 return m_priorityQueue.ToArray();
287 }
288
212 #region Priority Queue Helpers 289 #region Priority Queue Helpers
213 290
214 private J2KImage GetHighestPriorityImage() 291 private J2KImage GetHighestPriorityImage()
@@ -219,7 +296,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
219 { 296 {
220 if (m_priorityQueue.Count > 0) 297 if (m_priorityQueue.Count > 0)
221 { 298 {
222 try { image = m_priorityQueue.FindMax(); } 299 try
300 {
301 image = m_priorityQueue.FindMax();
302 }
223 catch (Exception) { } 303 catch (Exception) { }
224 } 304 }
225 } 305 }
@@ -232,7 +312,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
232 312
233 lock (m_syncRoot) 313 lock (m_syncRoot)
234 { 314 {
235 try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); } 315 try
316 {
317 m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
318 }
236 catch (Exception) { } 319 catch (Exception) { }
237 } 320 }
238 } 321 }
@@ -241,7 +324,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
241 { 324 {
242 lock (m_syncRoot) 325 lock (m_syncRoot)
243 { 326 {
244 try { m_priorityQueue.Delete(image.PriorityQueueHandle); } 327 try
328 {
329 m_priorityQueue.Delete(image.PriorityQueueHandle);
330 }
245 catch (Exception) { } 331 catch (Exception) { }
246 } 332 }
247 } 333 }
@@ -250,7 +336,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
250 { 336 {
251 lock (m_syncRoot) 337 lock (m_syncRoot)
252 { 338 {
253 try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } 339 try
340 {
341 m_priorityQueue.Replace(image.PriorityQueueHandle, image);
342 }
254 catch (Exception) 343 catch (Exception)
255 { 344 {
256 image.PriorityQueueHandle = null; 345 image.PriorityQueueHandle = null;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 5610c09..7b1aa2c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -492,6 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
492 if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60) 492 if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
493 { 493 {
494 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); 494 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
495 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
495 496
496 RemoveClient(udpClient); 497 RemoveClient(udpClient);
497 return; 498 return;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
new file mode 100644
index 0000000..1b68d68
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
@@ -0,0 +1,160 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Net;
31using System.Reflection;
32using log4net.Config;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Packets;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.Agent.TextureSender;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Tests.Common;
41using OpenSim.Tests.Common.Mock;
42
43namespace OpenSim.Region.ClientStack.LindenUDP.Tests
44{
45 [TestFixture]
46 public class LLImageManagerTests
47 {
48 private AssetBase m_testImageAsset;
49 private Scene scene;
50 private LLImageManager llim;
51 private TestClient tc;
52
53 [TestFixtureSetUp]
54 public void FixtureInit()
55 {
56 using (
57 Stream resource
58 = GetType().Assembly.GetManifestResourceStream(
59 "OpenSim.Region.ClientStack.LindenUDP.Tests.Resources.4-tile2.jp2"))
60 {
61 using (BinaryReader br = new BinaryReader(resource))
62 {
63 m_testImageAsset
64 = new AssetBase(
65 TestHelpers.ParseTail(0x1),
66 "Test Image",
67 (sbyte)AssetType.Texture,
68 TestHelpers.ParseTail(0x2).ToString());
69
70 m_testImageAsset.Data = br.ReadBytes(99999999);
71 }
72 }
73 }
74
75 [SetUp]
76 public void SetUp()
77 {
78 UUID userId = TestHelpers.ParseTail(0x3);
79
80 J2KDecoderModule j2kdm = new J2KDecoderModule();
81
82 scene = SceneHelpers.SetupScene();
83 SceneHelpers.SetupSceneModules(scene, j2kdm);
84
85 tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
86 llim = new LLImageManager(tc, scene.AssetService, j2kdm);
87 }
88
89 [Test]
90 public void TestSendImage()
91 {
92 TestHelpers.InMethod();
93// XmlConfigurator.Configure();
94
95 scene.AssetService.Store(m_testImageAsset);
96
97 TextureRequestArgs args = new TextureRequestArgs();
98 args.RequestedAssetID = m_testImageAsset.FullID;
99 args.DiscardLevel = 0;
100 args.PacketNumber = 1;
101 args.Priority = 5;
102 args.requestSequence = 1;
103
104 llim.EnqueueReq(args);
105 llim.ProcessImageQueue(20);
106
107 Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(1));
108 }
109
110 [Test]
111 public void TestDiscardImage()
112 {
113 TestHelpers.InMethod();
114// XmlConfigurator.Configure();
115
116 scene.AssetService.Store(m_testImageAsset);
117
118 TextureRequestArgs args = new TextureRequestArgs();
119 args.RequestedAssetID = m_testImageAsset.FullID;
120 args.DiscardLevel = 0;
121 args.PacketNumber = 1;
122 args.Priority = 5;
123 args.requestSequence = 1;
124 llim.EnqueueReq(args);
125
126 // Now create a discard request
127 TextureRequestArgs discardArgs = new TextureRequestArgs();
128 discardArgs.RequestedAssetID = m_testImageAsset.FullID;
129 discardArgs.DiscardLevel = -1;
130 discardArgs.PacketNumber = 1;
131 discardArgs.Priority = 0;
132 discardArgs.requestSequence = 2;
133 llim.EnqueueReq(discardArgs);
134
135 llim.ProcessImageQueue(20);
136
137 Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
138 }
139
140 [Test]
141 public void TestMissingImage()
142 {
143 TestHelpers.InMethod();
144// XmlConfigurator.Configure();
145
146 TextureRequestArgs args = new TextureRequestArgs();
147 args.RequestedAssetID = m_testImageAsset.FullID;
148 args.DiscardLevel = 0;
149 args.PacketNumber = 1;
150 args.Priority = 5;
151 args.requestSequence = 1;
152
153 llim.EnqueueReq(args);
154 llim.ProcessImageQueue(20);
155
156 Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
157 Assert.That(tc.SentImageNotInDatabasePackets.Count, Is.EqualTo(1));
158 }
159 }
160} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2 b/OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2
new file mode 100644
index 0000000..8c63104
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2
Binary files differ