diff options
Diffstat (limited to 'OpenSim/Region')
6 files changed, 327 insertions, 116 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ad6b1de..e89368a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -123,15 +123,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
123 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | 123 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
124 | 124 | ||
125 | // Save avatar attachment information | 125 | // Save avatar attachment information |
126 | ScenePresence presence; | 126 | m_log.Info( |
127 | if (m_scene.AvatarService != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 127 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId |
128 | { | 128 | + ", AttachmentPoint: " + AttachmentPt); |
129 | m_log.Info( | ||
130 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
131 | + ", AttachmentPoint: " + AttachmentPt); | ||
132 | 129 | ||
133 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | 130 | if (m_scene.AvatarFactory != null) |
134 | } | 131 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
135 | } | 132 | } |
136 | } | 133 | } |
137 | catch (Exception e) | 134 | catch (Exception e) |
@@ -382,8 +379,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
382 | item = m_scene.InventoryService.GetItem(item); | 379 | item = m_scene.InventoryService.GetItem(item); |
383 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); | 380 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); |
384 | 381 | ||
385 | if (m_scene.AvatarService != null) | 382 | if (m_scene.AvatarFactory != null) |
386 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | 383 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
387 | } | 384 | } |
388 | } | 385 | } |
389 | 386 | ||
@@ -405,11 +402,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
405 | presence.Appearance.DetachAttachment(itemID); | 402 | presence.Appearance.DetachAttachment(itemID); |
406 | 403 | ||
407 | // Save avatar attachment information | 404 | // Save avatar attachment information |
408 | if (m_scene.AvatarService != null) | 405 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); |
409 | { | 406 | if (m_scene.AvatarFactory != null) |
410 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); | 407 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
411 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | ||
412 | } | ||
413 | } | 408 | } |
414 | 409 | ||
415 | DetachSingleAttachmentToInv(itemID, remoteClient); | 410 | DetachSingleAttachmentToInv(itemID, remoteClient); |
@@ -435,10 +430,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
435 | 430 | ||
436 | presence.Appearance.DetachAttachment(itemID); | 431 | presence.Appearance.DetachAttachment(itemID); |
437 | 432 | ||
438 | if (m_scene.AvatarService != null) | 433 | if (m_scene.AvatarFactory != null) |
439 | { | 434 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
440 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | 435 | |
441 | } | ||
442 | part.ParentGroup.DetachToGround(); | 436 | part.ParentGroup.DetachToGround(); |
443 | 437 | ||
444 | List<UUID> uuids = new List<UUID>(); | 438 | List<UUID> uuids = new List<UUID>(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 9f7ff7f..bfbbcf8 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -32,23 +32,45 @@ using Nini.Config; | |||
32 | using OpenMetaverse; | 32 | using OpenMetaverse; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | 34 | ||
35 | using System.Threading; | ||
36 | using System.Timers; | ||
37 | using System.Collections.Generic; | ||
38 | |||
35 | using OpenSim.Region.Framework.Interfaces; | 39 | using OpenSim.Region.Framework.Interfaces; |
36 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
38 | 42 | ||
39 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | 43 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory |
40 | { | 44 | { |
41 | public class AvatarFactoryModule : IRegionModule | 45 | public class AvatarFactoryModule : IAvatarFactory, IRegionModule |
42 | { | 46 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | ||
45 | private Scene m_scene = null; | 48 | private Scene m_scene = null; |
46 | 49 | ||
47 | private bool m_startAnimationSet = false; | 50 | private int m_savetime = 5; // seconds to wait before saving changed appearance |
51 | private int m_sendtime = 2; // seconds to wait before sending changed appearance | ||
52 | |||
53 | private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates | ||
54 | private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); | ||
55 | private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>(); | ||
56 | private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>(); | ||
48 | 57 | ||
49 | public void Initialise(Scene scene, IConfigSource source) | 58 | #region RegionModule Members |
59 | |||
60 | public void Initialise(Scene scene, IConfigSource config) | ||
50 | { | 61 | { |
62 | scene.RegisterModuleInterface<IAvatarFactory>(this); | ||
51 | scene.EventManager.OnNewClient += NewClient; | 63 | scene.EventManager.OnNewClient += NewClient; |
64 | |||
65 | if (config != null) | ||
66 | { | ||
67 | IConfig sconfig = config.Configs["Startup"]; | ||
68 | if (sconfig != null) | ||
69 | { | ||
70 | m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); | ||
71 | m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); | ||
72 | } | ||
73 | } | ||
52 | 74 | ||
53 | if (m_scene == null) | 75 | if (m_scene == null) |
54 | m_scene = scene; | 76 | m_scene = scene; |
@@ -56,6 +78,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
56 | 78 | ||
57 | public void PostInitialise() | 79 | public void PostInitialise() |
58 | { | 80 | { |
81 | m_updateTimer.Enabled = false; | ||
82 | m_updateTimer.AutoReset = true; | ||
83 | m_updateTimer.Interval = m_checkTime; // 500 milliseconds wait to start async ops | ||
84 | m_updateTimer.Elapsed += new ElapsedEventHandler(HandleAppearanceUpdateTimer); | ||
59 | } | 85 | } |
60 | 86 | ||
61 | public void Close() | 87 | public void Close() |
@@ -84,6 +110,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
84 | // client.OnAvatarNowWearing -= AvatarIsWearing; | 110 | // client.OnAvatarNowWearing -= AvatarIsWearing; |
85 | } | 111 | } |
86 | 112 | ||
113 | #endregion | ||
114 | |||
115 | public bool ValidateBakedTextureCache(IClientAPI client) | ||
116 | { | ||
117 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | ||
118 | if (sp == null) | ||
119 | { | ||
120 | m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId); | ||
121 | return false; | ||
122 | } | ||
123 | |||
124 | bool cached = true; | ||
125 | |||
126 | // Process the texture entry | ||
127 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | ||
128 | { | ||
129 | int idx = AvatarAppearance.BAKE_INDICES[i]; | ||
130 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
131 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
132 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) | ||
133 | { | ||
134 | sp.Appearance.Texture.FaceTextures[idx] = null; | ||
135 | cached = false; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | return cached; | ||
140 | } | ||
141 | |||
142 | |||
87 | /// <summary> | 143 | /// <summary> |
88 | /// Set appearance data (textureentry and slider settings) received from the client | 144 | /// Set appearance data (textureentry and slider settings) received from the client |
89 | /// </summary> | 145 | /// </summary> |
@@ -91,6 +147,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
91 | /// <param name="visualParam"></param> | 147 | /// <param name="visualParam"></param> |
92 | public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) | 148 | public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) |
93 | { | 149 | { |
150 | // DEBUG ON | ||
151 | m_log.WarnFormat("[AVFACTORY] SetAppearance for {0}",client.AgentId); | ||
152 | // DEBUG OFF | ||
153 | |||
94 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 154 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
95 | if (sp == null) | 155 | if (sp == null) |
96 | { | 156 | { |
@@ -98,85 +158,179 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
98 | return; | 158 | return; |
99 | } | 159 | } |
100 | 160 | ||
101 | // DEBUG ON | ||
102 | m_log.WarnFormat("[AVFACTORY] SetAppearance for {0}",client.AgentId); | ||
103 | // DEBUG OFF | ||
104 | |||
105 | /* | ||
106 | if (m_physicsActor != null) | ||
107 | { | ||
108 | if (!IsChildAgent) | ||
109 | { | ||
110 | // This may seem like it's redundant, remove the avatar from the physics scene | ||
111 | // just to add it back again, but it saves us from having to update | ||
112 | // 3 variables 10 times a second. | ||
113 | bool flyingTemp = m_physicsActor.Flying; | ||
114 | RemoveFromPhysicalScene(); | ||
115 | //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); | ||
116 | |||
117 | //PhysicsActor = null; | ||
118 | |||
119 | AddToPhysicalScene(flyingTemp); | ||
120 | } | ||
121 | } | ||
122 | */ | ||
123 | #region Bake Cache Check | ||
124 | |||
125 | bool changed = false; | 161 | bool changed = false; |
126 | 162 | ||
127 | // Process the texture entry | 163 | // Process the texture entry |
128 | if (textureEntry != null) | 164 | if (textureEntry != null) |
129 | { | 165 | { |
130 | for (int i = 0; i < BAKE_INDICES.Length; i++) | 166 | changed = sp.Appearance.SetTextureEntries(textureEntry); |
131 | { | ||
132 | int j = BAKE_INDICES[i]; | ||
133 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; | ||
134 | 167 | ||
168 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | ||
169 | { | ||
170 | int idx = AvatarAppearance.BAKE_INDICES[i]; | ||
171 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
135 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | 172 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) |
136 | { | 173 | Util.FireAndForget(delegate(object o) { |
137 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | 174 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) |
138 | { | 175 | client.SendRebakeAvatarTextures(face.TextureID); |
139 | m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",face.TextureID,j,this.Name); | 176 | }); |
140 | client.SendRebakeAvatarTextures(face.TextureID); | ||
141 | } | ||
142 | } | ||
143 | } | 177 | } |
144 | changed = sp.Appearance.SetTextureEntries(textureEntry); | ||
145 | |||
146 | } | 178 | } |
147 | 179 | ||
148 | #endregion Bake Cache Check | 180 | // Process the visual params, this may change height as well |
149 | 181 | if (visualParams != null) | |
150 | changed = sp.Appearance.SetVisualParams(visualParams) || changed; | 182 | { |
151 | 183 | if (sp.Appearance.SetVisualParams(visualParams)) | |
152 | // If nothing changed (this happens frequently) just return | 184 | { |
185 | changed = true; | ||
186 | if (sp.Appearance.AvatarHeight > 0) | ||
187 | sp.SetHeight(sp.Appearance.AvatarHeight); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | // If something changed in the appearance then queue an appearance save | ||
153 | if (changed) | 192 | if (changed) |
193 | QueueAppearanceSave(client.AgentId); | ||
194 | |||
195 | // And always queue up an appearance update to send out | ||
196 | QueueAppearanceSend(client.AgentId); | ||
197 | |||
198 | // Send the appearance back to the avatar | ||
199 | // AvatarAppearance avp = sp.Appearance; | ||
200 | // sp.ControllingClient.SendAvatarDataImmediate(sp); | ||
201 | // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); | ||
202 | } | ||
203 | |||
204 | /// <summary> | ||
205 | /// Checks for the existance of a baked texture asset and | ||
206 | /// requests the viewer rebake if the asset is not found | ||
207 | /// </summary> | ||
208 | /// <param name="client"></param> | ||
209 | /// <param name="textureID"></param> | ||
210 | /// <param name="idx"></param> | ||
211 | private bool CheckBakedTextureAsset(IClientAPI client, UUID textureID, int idx) | ||
212 | { | ||
213 | if (m_scene.AssetService.Get(textureID.ToString()) == null) | ||
154 | { | 214 | { |
215 | m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}", | ||
216 | textureID,idx,client.Name); | ||
217 | return false; | ||
218 | } | ||
219 | return true; | ||
220 | } | ||
221 | |||
222 | #region UpdateAppearanceTimer | ||
223 | |||
224 | public void QueueAppearanceSend(UUID agentid) | ||
225 | { | ||
155 | // DEBUG ON | 226 | // DEBUG ON |
156 | m_log.Warn("[AVFACTORY] Appearance changed"); | 227 | m_log.WarnFormat("[AVFACTORY] Queue appearance send for {0}",agentid); |
157 | // DEBUG OFF | 228 | // DEBUG OFF |
158 | sp.Appearance.SetAppearance(textureEntry, visualParams); | ||
159 | if (sp.Appearance.AvatarHeight > 0) | ||
160 | sp.SetHeight(sp.Appearance.AvatarHeight); | ||
161 | 229 | ||
162 | m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); | 230 | // 100 nanoseconds (ticks) we should wait |
231 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000); | ||
232 | lock (m_sendqueue) | ||
233 | { | ||
234 | m_sendqueue[agentid] = timestamp; | ||
235 | m_updateTimer.Start(); | ||
163 | } | 236 | } |
237 | } | ||
238 | |||
239 | public void QueueAppearanceSave(UUID agentid) | ||
240 | { | ||
164 | // DEBUG ON | 241 | // DEBUG ON |
165 | else | 242 | m_log.WarnFormat("[AVFACTORY] Queue appearance save for {0}",agentid); |
166 | m_log.Warn("[AVFACTORY] Appearance did not change"); | 243 | // DEBUG OFF |
167 | // DEBUG OFF | ||
168 | 244 | ||
245 | // 100 nanoseconds (ticks) we should wait | ||
246 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000); | ||
247 | lock (m_savequeue) | ||
248 | { | ||
249 | m_savequeue[agentid] = timestamp; | ||
250 | m_updateTimer.Start(); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | private void HandleAppearanceSend(UUID agentid) | ||
255 | { | ||
256 | ScenePresence sp = m_scene.GetScenePresence(agentid); | ||
257 | if (sp == null) | ||
258 | { | ||
259 | m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid); | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | // DEBUG ON | ||
264 | m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}",agentid); | ||
265 | // DEBUG OFF | ||
266 | |||
267 | // Send the appearance to everyone in the scene | ||
169 | sp.SendAppearanceToAllOtherAgents(); | 268 | sp.SendAppearanceToAllOtherAgents(); |
269 | sp.ControllingClient.SendAvatarDataImmediate(sp); | ||
270 | |||
271 | // Send the appearance back to the avatar | ||
272 | // AvatarAppearance avp = sp.Appearance; | ||
273 | // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); | ||
274 | |||
275 | /* | ||
276 | // this needs to be fixed, the flag should be on scene presence not the region module | ||
277 | // Start the animations if necessary | ||
170 | if (!m_startAnimationSet) | 278 | if (!m_startAnimationSet) |
171 | { | 279 | { |
172 | sp.Animator.UpdateMovementAnimations(); | 280 | sp.Animator.UpdateMovementAnimations(); |
173 | m_startAnimationSet = true; | 281 | m_startAnimationSet = true; |
174 | } | 282 | } |
283 | */ | ||
284 | } | ||
175 | 285 | ||
176 | client.SendAvatarDataImmediate(sp); | 286 | private void HandleAppearanceSave(UUID agentid) |
177 | client.SendAppearance(sp.Appearance.Owner,sp.Appearance.VisualParams,sp.Appearance.Texture.GetBytes()); | 287 | { |
288 | ScenePresence sp = m_scene.GetScenePresence(agentid); | ||
289 | if (sp == null) | ||
290 | { | ||
291 | m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid); | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); | ||
178 | } | 296 | } |
179 | 297 | ||
298 | private void HandleAppearanceUpdateTimer(object sender, EventArgs ea) | ||
299 | { | ||
300 | long now = DateTime.Now.Ticks; | ||
301 | |||
302 | lock (m_sendqueue) | ||
303 | { | ||
304 | Dictionary<UUID,long> sends = new Dictionary<UUID,long>(m_sendqueue); | ||
305 | foreach (KeyValuePair<UUID,long> kvp in sends) | ||
306 | { | ||
307 | if (kvp.Value < now) | ||
308 | { | ||
309 | Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); | ||
310 | m_sendqueue.Remove(kvp.Key); | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | |||
315 | lock (m_savequeue) | ||
316 | { | ||
317 | Dictionary<UUID,long> saves = new Dictionary<UUID,long>(m_savequeue); | ||
318 | foreach (KeyValuePair<UUID,long> kvp in saves) | ||
319 | { | ||
320 | if (kvp.Value < now) | ||
321 | { | ||
322 | Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); | ||
323 | m_savequeue.Remove(kvp.Key); | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | |||
328 | if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) | ||
329 | m_updateTimer.Stop(); | ||
330 | } | ||
331 | |||
332 | #endregion | ||
333 | |||
180 | /// <summary> | 334 | /// <summary> |
181 | /// Tell the client for this scene presence what items it should be wearing now | 335 | /// Tell the client for this scene presence what items it should be wearing now |
182 | /// </summary> | 336 | /// </summary> |
@@ -215,14 +369,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
215 | 369 | ||
216 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance); | 370 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance); |
217 | 371 | ||
218 | //if (!TryGetAvatarAppearance(client.AgentId, out avatAppearance)) | ||
219 | //{ | ||
220 | // m_log.Warn("[AVFACTORY]: We didn't seem to find the appearance, falling back to ScenePresence"); | ||
221 | // avatAppearance = sp.Appearance; | ||
222 | //} | ||
223 | |||
224 | //m_log.DebugFormat("[AVFACTORY]: Received wearables for {0}", client.Name); | ||
225 | |||
226 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) | 372 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) |
227 | { | 373 | { |
228 | if (wear.Type < AvatarWearable.MAX_WEARABLES) | 374 | if (wear.Type < AvatarWearable.MAX_WEARABLES) |
@@ -232,10 +378,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
232 | } | 378 | } |
233 | } | 379 | } |
234 | 380 | ||
381 | // This could take awhile since it needs to pull inventory | ||
235 | SetAppearanceAssets(sp.UUID, ref avatAppearance); | 382 | SetAppearanceAssets(sp.UUID, ref avatAppearance); |
236 | 383 | ||
237 | m_scene.AvatarService.SetAppearance(client.AgentId, avatAppearance); | ||
238 | sp.Appearance = avatAppearance; | 384 | sp.Appearance = avatAppearance; |
385 | m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); | ||
239 | } | 386 | } |
240 | 387 | ||
241 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) | 388 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) |
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs new file mode 100644 index 0000000..22795fc --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs | |||
@@ -0,0 +1,39 @@ | |||
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 OpenMetaverse; | ||
29 | using OpenSim.Framework; | ||
30 | |||
31 | namespace OpenSim.Region.Framework.Interfaces | ||
32 | { | ||
33 | public interface IAvatarFactory | ||
34 | { | ||
35 | bool ValidateBakedTextureCache(IClientAPI client); | ||
36 | void QueueAppearanceSend(UUID agentid); | ||
37 | void QueueAppearanceSave(UUID agentid); | ||
38 | } | ||
39 | } | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6367fcf..3343d08 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -119,6 +119,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
119 | 119 | ||
120 | protected IXMLRPC m_xmlrpcModule; | 120 | protected IXMLRPC m_xmlrpcModule; |
121 | protected IWorldComm m_worldCommModule; | 121 | protected IWorldComm m_worldCommModule; |
122 | protected IAvatarFactory m_AvatarFactory; | ||
122 | protected IConfigSource m_config; | 123 | protected IConfigSource m_config; |
123 | protected IRegionSerialiserModule m_serialiser; | 124 | protected IRegionSerialiserModule m_serialiser; |
124 | protected IDialogModule m_dialogModule; | 125 | protected IDialogModule m_dialogModule; |
@@ -398,6 +399,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
398 | 399 | ||
399 | public IAttachmentsModule AttachmentsModule { get; set; } | 400 | public IAttachmentsModule AttachmentsModule { get; set; } |
400 | 401 | ||
402 | public IAvatarFactory AvatarFactory | ||
403 | { | ||
404 | get { return m_AvatarFactory; } | ||
405 | } | ||
406 | |||
401 | public ICapabilitiesModule CapsModule | 407 | public ICapabilitiesModule CapsModule |
402 | { | 408 | { |
403 | get { return m_capsModule; } | 409 | get { return m_capsModule; } |
@@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1153 | m_xmlrpcModule = RequestModuleInterface<IXMLRPC>(); | 1159 | m_xmlrpcModule = RequestModuleInterface<IXMLRPC>(); |
1154 | m_worldCommModule = RequestModuleInterface<IWorldComm>(); | 1160 | m_worldCommModule = RequestModuleInterface<IWorldComm>(); |
1155 | XferManager = RequestModuleInterface<IXfer>(); | 1161 | XferManager = RequestModuleInterface<IXfer>(); |
1162 | m_AvatarFactory = RequestModuleInterface<IAvatarFactory>(); | ||
1156 | AttachmentsModule = RequestModuleInterface<IAttachmentsModule>(); | 1163 | AttachmentsModule = RequestModuleInterface<IAttachmentsModule>(); |
1157 | m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); | 1164 | m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); |
1158 | m_dialogModule = RequestModuleInterface<IDialogModule>(); | 1165 | m_dialogModule = RequestModuleInterface<IDialogModule>(); |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6576e64..9402f8b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -704,20 +704,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
704 | // we created a new ScenePresence (a new child agent) in a fresh region. | 704 | // we created a new ScenePresence (a new child agent) in a fresh region. |
705 | // Request info about all the (root) agents in this region | 705 | // Request info about all the (root) agents in this region |
706 | // Note: This won't send data *to* other clients in that region (children don't send) | 706 | // Note: This won't send data *to* other clients in that region (children don't send) |
707 | |||
708 | // MIC: This gets called again in CompleteMovement | ||
707 | SendInitialFullUpdateToAllClients(); | 709 | SendInitialFullUpdateToAllClients(); |
708 | 710 | ||
709 | RegisterToEvents(); | 711 | RegisterToEvents(); |
710 | SetDirectionVectors(); | 712 | SetDirectionVectors(); |
711 | } | 713 | } |
712 | 714 | ||
713 | /* | ||
714 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, | ||
715 | AvatarWearable[] wearables) | ||
716 | : this(client, world, reginfo) | ||
717 | { | ||
718 | m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); | ||
719 | } | ||
720 | */ | ||
721 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) | 715 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) |
722 | : this(client, world, reginfo) | 716 | : this(client, world, reginfo) |
723 | { | 717 | { |
@@ -1081,7 +1075,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1081 | /// </summary> | 1075 | /// </summary> |
1082 | public void CompleteMovement(IClientAPI client) | 1076 | public void CompleteMovement(IClientAPI client) |
1083 | { | 1077 | { |
1084 | //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); | 1078 | // DEBUG ON |
1079 | m_log.WarnFormat("[SCENE PRESENCE]: CompleteMovement for {0}",UUID); | ||
1080 | // DEBUG OFF | ||
1085 | 1081 | ||
1086 | Vector3 look = Velocity; | 1082 | Vector3 look = Velocity; |
1087 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1083 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) |
@@ -2381,12 +2377,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
2381 | // 2 stage check is needed. | 2377 | // 2 stage check is needed. |
2382 | if (remoteAvatar == null) | 2378 | if (remoteAvatar == null) |
2383 | return; | 2379 | return; |
2380 | |||
2384 | IClientAPI cl=remoteAvatar.ControllingClient; | 2381 | IClientAPI cl=remoteAvatar.ControllingClient; |
2385 | if (cl == null) | 2382 | if (cl == null) |
2386 | return; | 2383 | return; |
2384 | |||
2387 | if (m_appearance.Texture == null) | 2385 | if (m_appearance.Texture == null) |
2388 | return; | 2386 | return; |
2389 | 2387 | ||
2388 | if (LocalId == remoteAvatar.LocalId) | ||
2389 | { | ||
2390 | m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); | ||
2391 | return; | ||
2392 | } | ||
2393 | |||
2390 | if (IsChildAgent) | 2394 | if (IsChildAgent) |
2391 | { | 2395 | { |
2392 | m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data"); | 2396 | m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data"); |
@@ -2407,20 +2411,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
2407 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 2411 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
2408 | { | 2412 | { |
2409 | ++avUpdates; | 2413 | ++avUpdates; |
2410 | // only send if this is the root (children are only "listening posts" in a foreign region) | 2414 | |
2415 | // Don't update ourselves | ||
2416 | if (avatar.LocalId == LocalId) | ||
2417 | return; | ||
2418 | |||
2419 | // If this is a root agent, then get info about the avatar | ||
2411 | if (!IsChildAgent) | 2420 | if (!IsChildAgent) |
2412 | { | 2421 | { |
2413 | SendFullUpdateToOtherClient(avatar); | 2422 | SendFullUpdateToOtherClient(avatar); |
2414 | } | 2423 | } |
2415 | 2424 | ||
2416 | if (avatar.LocalId != LocalId) | 2425 | // If the other avatar is a root |
2426 | if (!avatar.IsChildAgent) | ||
2417 | { | 2427 | { |
2418 | if (!avatar.IsChildAgent) | 2428 | avatar.SendFullUpdateToOtherClient(this); |
2419 | { | 2429 | avatar.SendAppearanceToOtherAgent(this); |
2420 | avatar.SendFullUpdateToOtherClient(this); | 2430 | avatar.Animator.SendAnimPackToClient(ControllingClient); |
2421 | avatar.SendAppearanceToOtherAgent(this); | ||
2422 | avatar.Animator.SendAnimPackToClient(ControllingClient); | ||
2423 | } | ||
2424 | } | 2431 | } |
2425 | }); | 2432 | }); |
2426 | 2433 | ||
@@ -2465,7 +2472,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2465 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); | 2472 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); |
2466 | 2473 | ||
2467 | m_controllingClient.SendAvatarDataImmediate(this); | 2474 | m_controllingClient.SendAvatarDataImmediate(this); |
2468 | m_controllingClient.SendAppearance(m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); | 2475 | if (m_scene.AvatarFactory != null) |
2476 | { | ||
2477 | if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) | ||
2478 | { | ||
2479 | m_log.WarnFormat("[SP] baked textures are in the ache for {0}",Name); | ||
2480 | m_controllingClient.SendAppearance( | ||
2481 | m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); | ||
2482 | } | ||
2483 | } | ||
2484 | else | ||
2485 | { | ||
2486 | m_log.WarnFormat("[SP] AvatarFactory not set"); | ||
2487 | } | ||
2469 | 2488 | ||
2470 | SendInitialFullUpdateToAllClients(); | 2489 | SendInitialFullUpdateToAllClients(); |
2471 | } | 2490 | } |
@@ -2497,9 +2516,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2497 | /// <param name="avatar"></param> | 2516 | /// <param name="avatar"></param> |
2498 | public void SendAppearanceToOtherAgent(ScenePresence avatar) | 2517 | public void SendAppearanceToOtherAgent(ScenePresence avatar) |
2499 | { | 2518 | { |
2519 | if (LocalId == avatar.LocalId) | ||
2520 | { | ||
2521 | m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); | ||
2522 | return; | ||
2523 | } | ||
2524 | |||
2500 | // DEBUG ON | 2525 | // DEBUG ON |
2501 | m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); | 2526 | // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); |
2502 | // DEBUG OFF | 2527 | // DEBUG OFF |
2528 | |||
2503 | avatar.ControllingClient.SendAppearance( | 2529 | avatar.ControllingClient.SendAppearance( |
2504 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); | 2530 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); |
2505 | } | 2531 | } |
@@ -3656,15 +3682,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
3656 | return; | 3682 | return; |
3657 | } | 3683 | } |
3658 | 3684 | ||
3659 | List<int> attPoints = m_appearance.GetAttachedPoints(); | 3685 | List<AvatarAttachment> attachments = m_appearance.GetAttachments(); |
3660 | foreach (int p in attPoints) | 3686 | foreach (AvatarAttachment attach in attachments) |
3661 | { | 3687 | { |
3662 | if (m_isDeleted) | 3688 | if (m_isDeleted) |
3663 | return; | 3689 | return; |
3664 | 3690 | ||
3665 | UUID itemID = m_appearance.GetAttachedItem(p); | 3691 | int p = attach.AttachPoint; |
3692 | UUID itemID = attach.ItemID; | ||
3666 | 3693 | ||
3667 | //UUID assetID = m_appearance.GetAttachedAsset(p); | 3694 | //UUID assetID = attach.AssetID; |
3668 | // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down | 3695 | // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down |
3669 | // But they're not used anyway, the item is being looked up for now, so let's proceed. | 3696 | // But they're not used anyway, the item is being looked up for now, so let's proceed. |
3670 | //if (UUID.Zero == assetID) | 3697 | //if (UUID.Zero == assetID) |
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs index 0786bd9..922eaaf 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs | |||
@@ -29,6 +29,7 @@ using System.Collections; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Security; | 30 | using System.Security; |
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using OpenSim.Framework; | ||
32 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
33 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
34 | 35 | ||
@@ -81,16 +82,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
81 | get { | 82 | get { |
82 | List<IAvatarAttachment> attachments = new List<IAvatarAttachment>(); | 83 | List<IAvatarAttachment> attachments = new List<IAvatarAttachment>(); |
83 | 84 | ||
84 | Hashtable internalAttachments = GetSP().Appearance.GetAttachments(); | 85 | List<AvatarAttachment> internalAttachments = GetSP().Appearance.GetAttachments(); |
85 | if (internalAttachments != null) | 86 | foreach (AvatarAttachment attach in internalAttachments) |
86 | { | 87 | { |
87 | foreach (DictionaryEntry element in internalAttachments) | 88 | attachments.Add(new SPAvatarAttachment(m_rootScene, this, attach.AttachPoint, |
88 | { | 89 | new UUID(attach.ItemID), |
89 | Hashtable attachInfo = (Hashtable)element.Value; | 90 | new UUID(attach.AssetID), m_security)); |
90 | attachments.Add(new SPAvatarAttachment(m_rootScene, this, (int) element.Key, | ||
91 | new UUID((string) attachInfo["item"]), | ||
92 | new UUID((string) attachInfo["asset"]), m_security)); | ||
93 | } | ||
94 | } | 91 | } |
95 | 92 | ||
96 | return attachments.ToArray(); | 93 | return attachments.ToArray(); |