diff options
Diffstat (limited to 'OpenSim/Region/CoreModules')
3 files changed, 321 insertions, 106 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2a0c0b1..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.AvatarFactory != 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.AvatarFactory.UpdateDatabase(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) |
@@ -383,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
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.AvatarFactory != null) | 382 | if (m_scene.AvatarFactory != null) |
386 | m_scene.AvatarFactory.UpdateDatabase(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 |
405 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); | ||
408 | if (m_scene.AvatarFactory != null) | 406 | if (m_scene.AvatarFactory != null) |
409 | { | 407 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
410 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); | ||
411 | m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
412 | } | ||
413 | } | 408 | } |
414 | 409 | ||
415 | DetachSingleAttachmentToInv(itemID, remoteClient); | 410 | DetachSingleAttachmentToInv(itemID, remoteClient); |
@@ -436,9 +431,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
436 | presence.Appearance.DetachAttachment(itemID); | 431 | presence.Appearance.DetachAttachment(itemID); |
437 | 432 | ||
438 | if (m_scene.AvatarFactory != null) | 433 | if (m_scene.AvatarFactory != null) |
439 | { | 434 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
440 | m_scene.AvatarFactory.UpdateDatabase(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 22c8937..bfbbcf8 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -32,6 +32,10 @@ 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; |
@@ -42,48 +46,42 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
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 Scene m_scene = null; | 48 | private Scene m_scene = null; |
45 | private static readonly AvatarAppearance def = new AvatarAppearance(); | ||
46 | |||
47 | public bool TryGetAvatarAppearance(UUID avatarId, out AvatarAppearance appearance) | ||
48 | { | ||
49 | AvatarData avatar = m_scene.AvatarService.GetAvatar(avatarId); | ||
50 | //if ((profile != null) && (profile.RootFolder != null)) | ||
51 | if (avatar != null) | ||
52 | { | ||
53 | appearance = avatar.ToAvatarAppearance(avatarId); | ||
54 | return true; | ||
55 | } | ||
56 | 49 | ||
57 | m_log.ErrorFormat("[APPEARANCE]: Appearance not found for {0}, creating default", avatarId); | 50 | private int m_savetime = 5; // seconds to wait before saving changed appearance |
58 | appearance = CreateDefault(avatarId); | 51 | private int m_sendtime = 2; // seconds to wait before sending changed appearance |
59 | return false; | ||
60 | } | ||
61 | 52 | ||
62 | private AvatarAppearance CreateDefault(UUID avatarId) | 53 | private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates |
63 | { | 54 | private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); |
64 | AvatarAppearance appearance = null; | 55 | private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>(); |
65 | AvatarWearable[] wearables; | 56 | private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>(); |
66 | byte[] visualParams; | ||
67 | GetDefaultAvatarAppearance(out wearables, out visualParams); | ||
68 | appearance = new AvatarAppearance(avatarId, wearables, visualParams); | ||
69 | 57 | ||
70 | return appearance; | 58 | #region RegionModule Members |
71 | } | ||
72 | 59 | ||
73 | public void Initialise(Scene scene, IConfigSource source) | 60 | public void Initialise(Scene scene, IConfigSource config) |
74 | { | 61 | { |
75 | scene.RegisterModuleInterface<IAvatarFactory>(this); | 62 | scene.RegisterModuleInterface<IAvatarFactory>(this); |
76 | scene.EventManager.OnNewClient += NewClient; | 63 | scene.EventManager.OnNewClient += NewClient; |
77 | 64 | ||
78 | if (m_scene == null) | 65 | if (config != null) |
79 | { | 66 | { |
80 | m_scene = scene; | 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 | } | ||
81 | } | 73 | } |
82 | 74 | ||
75 | if (m_scene == null) | ||
76 | m_scene = scene; | ||
83 | } | 77 | } |
84 | 78 | ||
85 | public void PostInitialise() | 79 | public void PostInitialise() |
86 | { | 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); | ||
87 | } | 85 | } |
88 | 86 | ||
89 | public void Close() | 87 | public void Close() |
@@ -102,6 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
102 | 100 | ||
103 | public void NewClient(IClientAPI client) | 101 | public void NewClient(IClientAPI client) |
104 | { | 102 | { |
103 | client.OnRequestWearables += SendWearables; | ||
104 | client.OnSetAppearance += SetAppearance; | ||
105 | client.OnAvatarNowWearing += AvatarIsWearing; | 105 | client.OnAvatarNowWearing += AvatarIsWearing; |
106 | } | 106 | } |
107 | 107 | ||
@@ -110,42 +110,243 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
110 | // client.OnAvatarNowWearing -= AvatarIsWearing; | 110 | // client.OnAvatarNowWearing -= AvatarIsWearing; |
111 | } | 111 | } |
112 | 112 | ||
113 | public void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) | 113 | #endregion |
114 | |||
115 | public bool ValidateBakedTextureCache(IClientAPI client) | ||
114 | { | 116 | { |
115 | IInventoryService invService = m_scene.InventoryService; | 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 | } | ||
116 | 123 | ||
117 | if (invService.GetRootFolder(userID) != null) | 124 | bool cached = true; |
125 | |||
126 | // Process the texture entry | ||
127 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | ||
118 | { | 128 | { |
119 | for (int i = 0; i < 13; i++) | 129 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
120 | { | 130 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; |
121 | if (appearance.Wearables[i].ItemID == UUID.Zero) | 131 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) |
132 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) | ||
122 | { | 133 | { |
123 | appearance.Wearables[i].AssetID = UUID.Zero; | 134 | sp.Appearance.Texture.FaceTextures[idx] = null; |
135 | cached = false; | ||
124 | } | 136 | } |
125 | else | 137 | } |
138 | |||
139 | return cached; | ||
140 | } | ||
141 | |||
142 | |||
143 | /// <summary> | ||
144 | /// Set appearance data (textureentry and slider settings) received from the client | ||
145 | /// </summary> | ||
146 | /// <param name="texture"></param> | ||
147 | /// <param name="visualParam"></param> | ||
148 | public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) | ||
149 | { | ||
150 | // DEBUG ON | ||
151 | m_log.WarnFormat("[AVFACTORY] SetAppearance for {0}",client.AgentId); | ||
152 | // DEBUG OFF | ||
153 | |||
154 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | ||
155 | if (sp == null) | ||
156 | { | ||
157 | m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId); | ||
158 | return; | ||
159 | } | ||
160 | |||
161 | bool changed = false; | ||
162 | |||
163 | // Process the texture entry | ||
164 | if (textureEntry != null) | ||
165 | { | ||
166 | changed = sp.Appearance.SetTextureEntries(textureEntry); | ||
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]; | ||
172 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
173 | Util.FireAndForget(delegate(object o) { | ||
174 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) | ||
175 | client.SendRebakeAvatarTextures(face.TextureID); | ||
176 | }); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | // Process the visual params, this may change height as well | ||
181 | if (visualParams != null) | ||
182 | { | ||
183 | if (sp.Appearance.SetVisualParams(visualParams)) | ||
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 | ||
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) | ||
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 | { | ||
226 | // DEBUG ON | ||
227 | m_log.WarnFormat("[AVFACTORY] Queue appearance send for {0}",agentid); | ||
228 | // DEBUG OFF | ||
229 | |||
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(); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | public void QueueAppearanceSave(UUID agentid) | ||
240 | { | ||
241 | // DEBUG ON | ||
242 | m_log.WarnFormat("[AVFACTORY] Queue appearance save for {0}",agentid); | ||
243 | // DEBUG OFF | ||
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 | ||
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 | ||
278 | if (!m_startAnimationSet) | ||
279 | { | ||
280 | sp.Animator.UpdateMovementAnimations(); | ||
281 | m_startAnimationSet = true; | ||
282 | } | ||
283 | */ | ||
284 | } | ||
285 | |||
286 | private void HandleAppearanceSave(UUID agentid) | ||
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); | ||
296 | } | ||
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) | ||
126 | { | 308 | { |
127 | InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i].ItemID, userID); | 309 | Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); |
128 | baseItem = invService.GetItem(baseItem); | 310 | m_sendqueue.Remove(kvp.Key); |
311 | } | ||
312 | } | ||
313 | } | ||
129 | 314 | ||
130 | if (baseItem != null) | 315 | lock (m_savequeue) |
131 | { | 316 | { |
132 | appearance.Wearables[i].AssetID = baseItem.AssetID; | 317 | Dictionary<UUID,long> saves = new Dictionary<UUID,long>(m_savequeue); |
133 | } | 318 | foreach (KeyValuePair<UUID,long> kvp in saves) |
134 | else | 319 | { |
135 | { | 320 | if (kvp.Value < now) |
136 | m_log.ErrorFormat( | 321 | { |
137 | "[APPEARANCE]: Can't find inventory item {0} for {1}, setting to default", | 322 | Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); |
138 | appearance.Wearables[i].ItemID, (WearableType)i); | 323 | m_savequeue.Remove(kvp.Key); |
139 | |||
140 | appearance.Wearables[i].AssetID = def.Wearables[i].AssetID; | ||
141 | } | ||
142 | } | 324 | } |
143 | } | 325 | } |
144 | } | 326 | } |
145 | else | 327 | |
328 | if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) | ||
329 | m_updateTimer.Stop(); | ||
330 | } | ||
331 | |||
332 | #endregion | ||
333 | |||
334 | /// <summary> | ||
335 | /// Tell the client for this scene presence what items it should be wearing now | ||
336 | /// </summary> | ||
337 | public void SendWearables(IClientAPI client) | ||
338 | { | ||
339 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | ||
340 | if (sp == null) | ||
146 | { | 341 | { |
147 | m_log.WarnFormat("[APPEARANCE]: user {0} has no inventory, appearance isn't going to work", userID); | 342 | m_log.WarnFormat("[AVFACTORY] SendWearables unable to find presence for {0}",client.AgentId); |
343 | return; | ||
148 | } | 344 | } |
345 | |||
346 | // DEBUG ON | ||
347 | m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId); | ||
348 | // DEBUG OFF | ||
349 | client.SendWearables(sp.Appearance.Wearables,sp.Appearance.Serial++); | ||
149 | } | 350 | } |
150 | 351 | ||
151 | /// <summary> | 352 | /// <summary> |
@@ -153,65 +354,74 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
153 | /// </summary> | 354 | /// </summary> |
154 | /// <param name="sender"></param> | 355 | /// <param name="sender"></param> |
155 | /// <param name="e"></param> | 356 | /// <param name="e"></param> |
156 | public void AvatarIsWearing(Object sender, AvatarWearingArgs e) | 357 | public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e) |
157 | { | 358 | { |
158 | m_log.DebugFormat("[APPEARANCE]: AvatarIsWearing"); | 359 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
159 | 360 | if (sp == null) | |
160 | IClientAPI clientView = (IClientAPI)sender; | ||
161 | ScenePresence sp = m_scene.GetScenePresence(clientView.AgentId); | ||
162 | |||
163 | if (sp == null) | ||
164 | { | 361 | { |
165 | m_log.Error("[APPEARANCE]: Avatar is child agent, ignoring AvatarIsWearing event"); | 362 | m_log.WarnFormat("[AVFACTORY] AvatarIsWearing unable to find presence for {0}",client.AgentId); |
166 | return; | 363 | return; |
167 | } | 364 | } |
168 | |||
169 | AvatarAppearance avatAppearance = sp.Appearance; | ||
170 | //if (!TryGetAvatarAppearance(clientView.AgentId, out avatAppearance)) | ||
171 | //{ | ||
172 | // m_log.Warn("[APPEARANCE]: We didn't seem to find the appearance, falling back to ScenePresence"); | ||
173 | // avatAppearance = sp.Appearance; | ||
174 | //} | ||
175 | |||
176 | //m_log.DebugFormat("[APPEARANCE]: Received wearables for {0}", clientView.Name); | ||
177 | 365 | ||
366 | // DEBUG ON | ||
367 | m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}",client.AgentId); | ||
368 | // DEBUG OFF | ||
369 | |||
370 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance); | ||
371 | |||
178 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) | 372 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) |
179 | { | 373 | { |
180 | if (wear.Type < 13) | 374 | if (wear.Type < AvatarWearable.MAX_WEARABLES) |
181 | { | 375 | { |
182 | avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; | 376 | AvatarWearable newWearable = new AvatarWearable(wear.ItemID,UUID.Zero); |
377 | avatAppearance.SetWearable(wear.Type, newWearable); | ||
183 | } | 378 | } |
184 | } | 379 | } |
185 | 380 | ||
381 | // This could take awhile since it needs to pull inventory | ||
186 | SetAppearanceAssets(sp.UUID, ref avatAppearance); | 382 | SetAppearanceAssets(sp.UUID, ref avatAppearance); |
187 | AvatarData adata = new AvatarData(avatAppearance); | ||
188 | m_scene.AvatarService.SetAvatar(clientView.AgentId, adata); | ||
189 | 383 | ||
190 | sp.Appearance = avatAppearance; | 384 | sp.Appearance = avatAppearance; |
385 | m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); | ||
191 | } | 386 | } |
192 | 387 | ||
193 | public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) | 388 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) |
194 | { | 389 | { |
195 | visualParams = GetDefaultVisualParams(); | 390 | IInventoryService invService = m_scene.InventoryService; |
196 | wearables = AvatarWearable.DefaultWearables; | ||
197 | } | ||
198 | 391 | ||
199 | public void UpdateDatabase(UUID user, AvatarAppearance appearance) | 392 | if (invService.GetRootFolder(userID) != null) |
200 | { | 393 | { |
201 | //m_log.DebugFormat("[APPEARANCE]: UpdateDatabase"); | 394 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) |
202 | AvatarData adata = new AvatarData(appearance); | 395 | { |
203 | m_scene.AvatarService.SetAvatar(user, adata); | 396 | if (appearance.Wearables[i].ItemID == UUID.Zero) |
204 | } | 397 | { |
398 | appearance.Wearables[i].AssetID = UUID.Zero; | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i].ItemID, userID); | ||
403 | baseItem = invService.GetItem(baseItem); | ||
205 | 404 | ||
206 | private static byte[] GetDefaultVisualParams() | 405 | if (baseItem != null) |
207 | { | 406 | { |
208 | byte[] visualParams; | 407 | appearance.Wearables[i].AssetID = baseItem.AssetID; |
209 | visualParams = new byte[218]; | 408 | } |
210 | for (int i = 0; i < 218; i++) | 409 | else |
410 | { | ||
411 | m_log.ErrorFormat( | ||
412 | "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", | ||
413 | appearance.Wearables[i].ItemID, (WearableType)i); | ||
414 | |||
415 | appearance.Wearables[i].ItemID = UUID.Zero; | ||
416 | appearance.Wearables[i].AssetID = UUID.Zero; | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | else | ||
211 | { | 422 | { |
212 | visualParams[i] = 100; | 423 | m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); |
213 | } | 424 | } |
214 | return visualParams; | ||
215 | } | 425 | } |
216 | } | 426 | } |
217 | } | 427 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs index 47f19a3..9ee19f8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs | |||
@@ -30,6 +30,7 @@ using System.Collections.Generic; | |||
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
34 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
35 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
@@ -137,6 +138,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar | |||
137 | 138 | ||
138 | #region IAvatarService | 139 | #region IAvatarService |
139 | 140 | ||
141 | public AvatarAppearance GetAppearance(UUID userID) | ||
142 | { | ||
143 | return m_AvatarService.GetAppearance(userID); | ||
144 | } | ||
145 | |||
146 | public bool SetAppearance(UUID userID, AvatarAppearance appearance) | ||
147 | { | ||
148 | return m_AvatarService.SetAppearance(userID,appearance); | ||
149 | } | ||
150 | |||
140 | public AvatarData GetAvatar(UUID userID) | 151 | public AvatarData GetAvatar(UUID userID) |
141 | { | 152 | { |
142 | return m_AvatarService.GetAvatar(userID); | 153 | return m_AvatarService.GetAvatar(userID); |