aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorMelanie Thielker2014-08-07 16:55:00 +0200
committerMelanie Thielker2014-08-07 16:55:00 +0200
commita06d66b70b7eb6c76b4dbbf915a1b02ca21db17f (patch)
tree39219012afb0e847debf29fe0c9170b445bc4056 /OpenSim/Region/ClientStack
parentMerge branch 'ubitworkmaster' (diff)
parentminor clean, dont check for cache if we aren't using it.. (diff)
downloadopensim-SC_OLD-a06d66b70b7eb6c76b4dbbf915a1b02ca21db17f.zip
opensim-SC_OLD-a06d66b70b7eb6c76b4dbbf915a1b02ca21db17f.tar.gz
opensim-SC_OLD-a06d66b70b7eb6c76b4dbbf915a1b02ca21db17f.tar.bz2
opensim-SC_OLD-a06d66b70b7eb6c76b4dbbf915a1b02ca21db17f.tar.xz
Merge branch 'ubitworkmaster'
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs122
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs153
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs34
3 files changed, 112 insertions, 197 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
index 47988dd..50e9275 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
@@ -96,9 +96,7 @@ namespace OpenSim.Region.ClientStack.Linden
96 s.EventManager.OnRemovePresence -= DeRegisterPresence; 96 s.EventManager.OnRemovePresence -= DeRegisterPresence;
97 m_BakedTextureModule = null; 97 m_BakedTextureModule = null;
98 m_scene = null; 98 m_scene = null;
99 } 99 }
100
101
102 100
103 public void RegionLoaded(Scene s) 101 public void RegionLoaded(Scene s)
104 { 102 {
@@ -110,44 +108,58 @@ namespace OpenSim.Region.ClientStack.Linden
110 108
111 private void DeRegisterPresence(UUID agentId) 109 private void DeRegisterPresence(UUID agentId)
112 { 110 {
113 ScenePresence presence = null; 111// ScenePresence presence = null;
114 if (m_scene.TryGetScenePresence(agentId, out presence)) 112// if (m_scene.TryGetScenePresence(agentId, out presence))
115 { 113 {
116 presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings; 114// presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings;
117 } 115 }
118 116
119 } 117 }
120 118
121 private void RegisterNewPresence(ScenePresence presence) 119 private void RegisterNewPresence(ScenePresence presence)
122 { 120 {
123 presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings; 121// presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings;
124
125 } 122 }
126 123
127 private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) 124/* not in use. work done in AvatarFactoryModule ValidateBakedTextureCache() and UpdateBakedTextureCache()
128 { 125 private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
129 int maxCacheitemsLoop = cacheItems.Length;
130 if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES)
131 {
132 maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
133 m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
134 }
135
136 m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
137 if (cacheItems.Length > 0)
138 {
139 m_log.Debug("[Cacheitems]: " + cacheItems.Length);
140 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
141 {
142 m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
143 cacheItems[iter].TextureID);
144 }
145
146 ScenePresence p = null;
147 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
148 { 126 {
127 // if cacheItems.Length > 0 viewer is giving us current textures information.
128 // baked ones should had been uploaded and in assets cache as local itens
129
130
131 if (cacheItems.Length == 0)
132 return; // no textures information, nothing to do
133
134 ScenePresence p = null;
135 if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
136 return; // what are we doing if there is no presence to cache for?
137
138 if (p.IsDeleted)
139 return; // does this really work?
140
141 int maxCacheitemsLoop = cacheItems.Length;
142 if (maxCacheitemsLoop > 20)
143 {
144 maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
145 m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
146 }
147
148 m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
149
150
151 // some nice debug
152 m_log.Debug("[Cacheitems]: " + cacheItems.Length);
153 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
154 {
155 m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
156 cacheItems[iter].TextureID);
157 }
158
159 // p.Appearance.WearableCacheItems is in memory primary cashID to textures mapper
149 160
150 WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; 161 WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems;
162
151 if (existingitems == null) 163 if (existingitems == null)
152 { 164 {
153 if (m_BakedTextureModule != null) 165 if (m_BakedTextureModule != null)
@@ -161,38 +173,22 @@ namespace OpenSim.Region.ClientStack.Linden
161 p.Appearance.WearableCacheItems = savedcache; 173 p.Appearance.WearableCacheItems = savedcache;
162 p.Appearance.WearableCacheItemsDirty = false; 174 p.Appearance.WearableCacheItemsDirty = false;
163 } 175 }
164
165 } 176 }
166 /* 177
167 * The following Catch types DO NOT WORK with m_BakedTextureModule.Get
168 * it jumps to the General Packet Exception Handler if you don't catch Exception!
169 *
170 catch (System.Net.Sockets.SocketException)
171 {
172 cacheItems = null;
173 }
174 catch (WebException)
175 {
176 cacheItems = null;
177 }
178 catch (InvalidOperationException)
179 {
180 cacheItems = null;
181 } */
182 catch (Exception) 178 catch (Exception)
183 { 179 {
184 // The service logs a sufficient error message. 180 // The service logs a sufficient error message.
185 } 181 }
186 182
187 183
188 if (savedcache != null) 184 if (savedcache != null)
189 existingitems = savedcache; 185 existingitems = savedcache;
190 } 186 }
191 } 187 }
188
192 // Existing items null means it's a fully new appearance 189 // Existing items null means it's a fully new appearance
193 if (existingitems == null) 190 if (existingitems == null)
194 { 191 {
195
196 for (int i = 0; i < maxCacheitemsLoop; i++) 192 for (int i = 0; i < maxCacheitemsLoop; i++)
197 { 193 {
198 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) 194 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
@@ -205,7 +201,7 @@ namespace OpenSim.Region.ClientStack.Linden
205 AppearanceManager.DEFAULT_AVATAR_TEXTURE; 201 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
206 continue; 202 continue;
207 } 203 }
208 cacheItems[i].TextureID =face.TextureID; 204 cacheItems[i].TextureID = face.TextureID;
209 if (m_scene.AssetService != null) 205 if (m_scene.AssetService != null)
210 cacheItems[i].TextureAsset = 206 cacheItems[i].TextureAsset =
211 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); 207 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
@@ -214,15 +210,10 @@ namespace OpenSim.Region.ClientStack.Linden
214 { 210 {
215 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); 211 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
216 } 212 }
217
218
219 } 213 }
220 } 214 }
221 else 215 else
222 216 {
223
224 {
225 // for each uploaded baked texture
226 for (int i = 0; i < maxCacheitemsLoop; i++) 217 for (int i = 0; i < maxCacheitemsLoop; i++)
227 { 218 {
228 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) 219 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
@@ -253,23 +244,24 @@ namespace OpenSim.Region.ClientStack.Linden
253 } 244 }
254 } 245 }
255 } 246 }
256
257
258
259 p.Appearance.WearableCacheItems = cacheItems; 247 p.Appearance.WearableCacheItems = cacheItems;
260
261
262 248
263 if (m_BakedTextureModule != null) 249 if (m_BakedTextureModule != null)
264 { 250 {
265 m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); 251 m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems);
266 p.Appearance.WearableCacheItemsDirty = true; 252 p.Appearance.WearableCacheItemsDirty = true;
267 253
268 } 254 }
269 } 255 else
270 } 256 p.Appearance.WearableCacheItemsDirty = false;
271 }
272 257
258 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
259 {
260 m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
261 cacheItems[iter].TextureID);
262 }
263 }
264 */
273 public void PostInitialise() 265 public void PostInitialise()
274 { 266 {
275 } 267 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 34a2797..e9a087b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -3684,6 +3684,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3684 avp.Sender.IsTrial = false; 3684 avp.Sender.IsTrial = false;
3685 avp.Sender.ID = agentID; 3685 avp.Sender.ID = agentID;
3686 avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; 3686 avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0];
3687
3688 // this need be use in future
3689 // avp.AppearanceData[0].AppearanceVersion = 0;
3690 // avp.AppearanceData[0].CofVersion = 0;
3691
3687 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3692 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3688 OutPacket(avp, ThrottleOutPacketType.Task); 3693 OutPacket(avp, ThrottleOutPacketType.Task);
3689 } 3694 }
@@ -6535,7 +6540,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6535 6540
6536 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length]; 6541 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6537 for (int i=0; i<appear.WearableData.Length;i++) 6542 for (int i=0; i<appear.WearableData.Length;i++)
6538 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)}; 6543 cacheitems[i] = new WearableCacheItem(){
6544 CacheId = appear.WearableData[i].CacheID,
6545 TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)
6546 };
6539 6547
6540 6548
6541 6549
@@ -12004,150 +12012,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12004 12012
12005 if (cachedtex.AgentData.SessionID != SessionId) 12013 if (cachedtex.AgentData.SessionID != SessionId)
12006 return false; 12014 return false;
12007
12008 12015
12009 // TODO: don't create new blocks if recycling an old packet 12016 // TODO: don't create new blocks if recycling an old packet
12010 cachedresp.AgentData.AgentID = AgentId; 12017 cachedresp.AgentData.AgentID = AgentId;
12011 cachedresp.AgentData.SessionID = m_sessionId; 12018 cachedresp.AgentData.SessionID = m_sessionId;
12012 cachedresp.AgentData.SerialNum = m_cachedTextureSerial; 12019 cachedresp.AgentData.SerialNum = cachedtex.AgentData.SerialNum;
12013 m_cachedTextureSerial++;
12014 cachedresp.WearableData = 12020 cachedresp.WearableData =
12015 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 12021 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
12016 12022
12017 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
12018 // var item = fac.GetBakedTextureFaces(AgentId);
12019 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
12020
12021 IAssetService cache = m_scene.AssetService;
12022 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
12023 //bakedTextureModule = null;
12024 int maxWearablesLoop = cachedtex.WearableData.Length; 12023 int maxWearablesLoop = cachedtex.WearableData.Length;
12025 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) 12024 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
12026 maxWearablesLoop = AvatarWearable.MAX_WEARABLES; 12025 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
12027 12026
12028 if (bakedTextureModule != null && cache != null) 12027 int cacheHits = 0;
12029 {
12030 // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
12031 12028
12032 WearableCacheItem[] cacheItems = null; 12029 // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
12033 ScenePresence p = m_scene.GetScenePresence(AgentId);
12034 if (p.Appearance != null)
12035 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
12036 {
12037 try
12038 {
12039 cacheItems = bakedTextureModule.Get(AgentId);
12040 p.Appearance.WearableCacheItems = cacheItems;
12041 p.Appearance.WearableCacheItemsDirty = false;
12042 }
12043 12030
12044 /* 12031 WearableCacheItem[] cacheItems = null;
12045 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
12046 *
12047 catch (System.Net.Sockets.SocketException)
12048 {
12049 cacheItems = null;
12050 }
12051 catch (WebException)
12052 {
12053 cacheItems = null;
12054 }
12055 catch (InvalidOperationException)
12056 {
12057 cacheItems = null;
12058 } */
12059 catch (Exception)
12060 {
12061 cacheItems = null;
12062 }
12063
12064 }
12065 else if (p.Appearance.WearableCacheItems != null)
12066 {
12067 cacheItems = p.Appearance.WearableCacheItems;
12068 }
12069 12032
12070 if (cache != null && cacheItems != null) 12033 ScenePresence p = m_scene.GetScenePresence(AgentId);
12071 {
12072 foreach (WearableCacheItem item in cacheItems)
12073 {
12074
12075 if (cache.GetCached(item.TextureID.ToString()) == null)
12076 {
12077 item.TextureAsset.Temporary = true;
12078 cache.Store(item.TextureAsset);
12079 }
12080 12034
12035 if (p != null && p.Appearance != null)
12036 {
12037 cacheItems = p.Appearance.WearableCacheItems;
12038 }
12081 12039
12082 } 12040 if (cacheItems != null)
12083 } 12041 {
12084 12042 for (int i = 0; i < maxWearablesLoop; i++)
12085 if (cacheItems != null)
12086 { 12043 {
12087 12044 int idx = cachedtex.WearableData[i].TextureIndex;
12088 for (int i = 0; i < maxWearablesLoop; i++)
12089 {
12090 WearableCacheItem item =
12091 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
12092 12045
12093 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 12046 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12094 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; 12047 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12095 cachedresp.WearableData[i].HostName = new byte[0]; 12048 cachedresp.WearableData[i].HostName = new byte[0];
12096 if (item != null && cachedtex.WearableData[i].ID == item.CacheId) 12049 if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId)
12097 { 12050 {
12098 12051 cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID;
12099 cachedresp.WearableData[i].TextureID = item.TextureID; 12052 cacheHits++;
12100 }
12101 else
12102 {
12103 cachedresp.WearableData[i].TextureID = UUID.Zero;
12104 }
12105 } 12053 }
12106 } 12054 else
12107 else
12108 {
12109 for (int i = 0; i < maxWearablesLoop; i++)
12110 { 12055 {
12111 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12112 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12113 cachedresp.WearableData[i].TextureID = UUID.Zero; 12056 cachedresp.WearableData[i].TextureID = UUID.Zero;
12114 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12115 cachedresp.WearableData[i].HostName = new byte[0];
12116 } 12057 }
12117 } 12058 }
12118 } 12059 }
12119 else 12060 else
12120 { 12061 {
12121 if (cache == null) 12062 for (int i = 0; i < maxWearablesLoop; i++)
12122 { 12063 {
12123 for (int i = 0; i < maxWearablesLoop; i++) 12064 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12124 { 12065 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12125 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 12066 cachedresp.WearableData[i].TextureID = UUID.Zero;
12126 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 12067 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12127 cachedresp.WearableData[i].TextureID = UUID.Zero; 12068 cachedresp.WearableData[i].HostName = new byte[0];
12128 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12129 cachedresp.WearableData[i].HostName = new byte[0];
12130 }
12131 } 12069 }
12132 else 12070 }
12133 {
12134 for (int i = 0; i < maxWearablesLoop; i++)
12135 {
12136 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12137 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
12138
12139 12071
12072 m_log.DebugFormat("texture cached: hits {0}", cacheHits);
12140 12073
12141 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
12142 cachedresp.WearableData[i].TextureID = UUID.Zero;
12143 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12144 else
12145 cachedresp.WearableData[i].TextureID = UUID.Zero;
12146 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
12147 cachedresp.WearableData[i].HostName = new byte[0];
12148 }
12149 }
12150 }
12151 cachedresp.Header.Zerocoded = true; 12074 cachedresp.Header.Zerocoded = true;
12152 OutPacket(cachedresp, ThrottleOutPacketType.Task); 12075 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12153 12076
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index b7c8594..a3fdae1 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1750,25 +1750,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1750 endPoint, 1750 endPoint,
1751 sessionInfo); 1751 sessionInfo);
1752 1752
1753 // Send ack straight away to let the viewer know that the connection is active.
1754 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use
1755 // circuit code to the existing child agent. This is not particularly obvious.
1756 SendAckImmediate(endPoint, uccp.Header.Sequence);
1757
1758 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1759 if (client != null)
1760 {
1761 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1762 bool tp = (aCircuit.teleportFlags > 0);
1763 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
1764 if (!tp)
1765 client.SceneAgent.SendInitialDataToMe();
1766 }
1767
1768 // Now we know we can handle more data 1753 // Now we know we can handle more data
1769 Thread.Sleep(200); 1754// Thread.Sleep(200);
1770 1755
1771 // Obtain the queue and remove it from the cache 1756 // Obtain the pending queue and remove it from the cache
1772 Queue<UDPPacketBuffer> queue = null; 1757 Queue<UDPPacketBuffer> queue = null;
1773 1758
1774 lock (m_pendingCache) 1759 lock (m_pendingCache)
@@ -1790,6 +1775,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1790 PacketReceived(buf); 1775 PacketReceived(buf);
1791 } 1776 }
1792 queue = null; 1777 queue = null;
1778
1779 // Send ack straight away to let the viewer know that the connection is active.
1780 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use
1781 // circuit code to the existing child agent. This is not particularly obvious.
1782 SendAckImmediate(endPoint, uccp.Header.Sequence);
1783
1784 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1785 if (client != null)
1786 {
1787 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1788 bool tp = (aCircuit.teleportFlags > 0);
1789 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
1790 if (!tp)
1791 client.SceneAgent.SendInitialDataToMe();
1792 }
1793 } 1793 }
1794 else 1794 else
1795 { 1795 {