diff options
author | Dan Lake | 2012-02-01 16:25:35 -0800 |
---|---|---|
committer | Dan Lake | 2012-02-01 16:25:35 -0800 |
commit | c10193c72b1f029a958f04d2f5d7ee384e693aaa (patch) | |
tree | 052ec7e973c15b158310511197affad14eb9c64f /OpenSim/Region/ClientStack/Linden | |
parent | Trigger event when prims are scheduled for an update. This gives modules earl... (diff) | |
parent | Small optimization to last commit (diff) | |
download | opensim-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 '')
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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
32 | using Nini.Config; | ||
33 | using Mono.Addins; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Services.Interfaces; | ||
40 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
41 | using OpenSim.Capabilities.Handlers; | ||
42 | |||
43 | namespace 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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Net; | ||
31 | using System.Reflection; | ||
32 | using log4net.Config; | ||
33 | using Nini.Config; | ||
34 | using NUnit.Framework; | ||
35 | using OpenMetaverse; | ||
36 | using OpenMetaverse.Packets; | ||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Region.CoreModules.Agent.TextureSender; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Tests.Common; | ||
41 | using OpenSim.Tests.Common.Mock; | ||
42 | |||
43 | namespace 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 | |||