diff options
Diffstat (limited to 'OpenSim/Region')
12 files changed, 435 insertions, 262 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 74ad485..14f923d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -79,7 +79,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
79 | public event DeRezObject OnDeRezObject; | 79 | public event DeRezObject OnDeRezObject; |
80 | public event ModifyTerrain OnModifyTerrain; | 80 | public event ModifyTerrain OnModifyTerrain; |
81 | public event Action<IClientAPI> OnRegionHandShakeReply; | 81 | public event Action<IClientAPI> OnRegionHandShakeReply; |
82 | public event GenericCall2 OnRequestWearables; | 82 | public event GenericCall1 OnRequestWearables; |
83 | public event SetAppearance OnSetAppearance; | 83 | public event SetAppearance OnSetAppearance; |
84 | public event AvatarNowWearing OnAvatarNowWearing; | 84 | public event AvatarNowWearing OnAvatarNowWearing; |
85 | public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; | 85 | public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; |
@@ -5647,11 +5647,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5647 | 5647 | ||
5648 | private bool HandlerAgentWearablesRequest(IClientAPI sender, Packet Pack) | 5648 | private bool HandlerAgentWearablesRequest(IClientAPI sender, Packet Pack) |
5649 | { | 5649 | { |
5650 | GenericCall2 handlerRequestWearables = OnRequestWearables; | 5650 | GenericCall1 handlerRequestWearables = OnRequestWearables; |
5651 | 5651 | ||
5652 | if (handlerRequestWearables != null) | 5652 | if (handlerRequestWearables != null) |
5653 | { | 5653 | { |
5654 | handlerRequestWearables(); | 5654 | handlerRequestWearables(sender); |
5655 | } | 5655 | } |
5656 | 5656 | ||
5657 | Action<IClientAPI> handlerRequestAvatarsData = OnRequestAvatarsData; | 5657 | Action<IClientAPI> handlerRequestAvatarsData = OnRequestAvatarsData; |
@@ -5694,7 +5694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5694 | if (appear.ObjectData.TextureEntry.Length > 1) | 5694 | if (appear.ObjectData.TextureEntry.Length > 1) |
5695 | te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); | 5695 | te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); |
5696 | 5696 | ||
5697 | handlerSetAppearance(te, visualparams); | 5697 | handlerSetAppearance(sender, te, visualparams); |
5698 | } | 5698 | } |
5699 | catch (Exception e) | 5699 | catch (Exception e) |
5700 | { | 5700 | { |
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); |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 268612e..f128aa2 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -82,7 +82,7 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
82 | 82 | ||
83 | public event DeRezObject OnDeRezObject; | 83 | public event DeRezObject OnDeRezObject; |
84 | public event Action<IClientAPI> OnRegionHandShakeReply; | 84 | public event Action<IClientAPI> OnRegionHandShakeReply; |
85 | public event GenericCall2 OnRequestWearables; | 85 | public event GenericCall1 OnRequestWearables; |
86 | public event GenericCall1 OnCompleteMovementToRegion; | 86 | public event GenericCall1 OnCompleteMovementToRegion; |
87 | public event UpdateAgent OnPreAgentUpdate; | 87 | public event UpdateAgent OnPreAgentUpdate; |
88 | public event UpdateAgent OnAgentUpdate; | 88 | public event UpdateAgent OnAgentUpdate; |
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs index c967f30..22795fc 100644 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs | |||
@@ -32,7 +32,8 @@ namespace OpenSim.Region.Framework.Interfaces | |||
32 | { | 32 | { |
33 | public interface IAvatarFactory | 33 | public interface IAvatarFactory |
34 | { | 34 | { |
35 | bool TryGetAvatarAppearance(UUID avatarId, out AvatarAppearance appearance); | 35 | bool ValidateBakedTextureCache(IClientAPI client); |
36 | void UpdateDatabase(UUID userID, AvatarAppearance avatAppearance); | 36 | void QueueAppearanceSend(UUID agentid); |
37 | void QueueAppearanceSave(UUID agentid); | ||
37 | } | 38 | } |
38 | } | 39 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f0ae45e..3343d08 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -403,7 +403,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
403 | { | 403 | { |
404 | get { return m_AvatarFactory; } | 404 | get { return m_AvatarFactory; } |
405 | } | 405 | } |
406 | 406 | ||
407 | public ICapabilitiesModule CapsModule | 407 | public ICapabilitiesModule CapsModule |
408 | { | 408 | { |
409 | get { return m_capsModule; } | 409 | get { return m_capsModule; } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 03aa8cf..1fc3ed6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -75,7 +75,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
75 | 75 | ||
76 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 76 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
77 | 77 | ||
78 | private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | ||
79 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 78 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
80 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 79 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
81 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 80 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
@@ -137,8 +136,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
137 | 136 | ||
138 | private SendCourseLocationsMethod m_sendCourseLocationsMethod; | 137 | private SendCourseLocationsMethod m_sendCourseLocationsMethod; |
139 | 138 | ||
140 | private bool m_startAnimationSet; | ||
141 | |||
142 | //private Vector3 m_requestedSitOffset = new Vector3(); | 139 | //private Vector3 m_requestedSitOffset = new Vector3(); |
143 | 140 | ||
144 | private Vector3 m_LastFinitePos; | 141 | private Vector3 m_LastFinitePos; |
@@ -707,19 +704,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
707 | // 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. |
708 | // Request info about all the (root) agents in this region | 705 | // Request info about all the (root) agents in this region |
709 | // 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 | ||
710 | SendInitialFullUpdateToAllClients(); | 709 | SendInitialFullUpdateToAllClients(); |
711 | 710 | ||
712 | RegisterToEvents(); | 711 | RegisterToEvents(); |
713 | SetDirectionVectors(); | 712 | SetDirectionVectors(); |
714 | } | 713 | } |
715 | 714 | ||
716 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, | ||
717 | AvatarWearable[] wearables) | ||
718 | : this(client, world, reginfo) | ||
719 | { | ||
720 | m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); | ||
721 | } | ||
722 | |||
723 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) | 715 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) |
724 | : this(client, world, reginfo) | 716 | : this(client, world, reginfo) |
725 | { | 717 | { |
@@ -733,8 +725,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
733 | 725 | ||
734 | public void RegisterToEvents() | 726 | public void RegisterToEvents() |
735 | { | 727 | { |
736 | m_controllingClient.OnRequestWearables += SendWearables; | ||
737 | m_controllingClient.OnSetAppearance += SetAppearance; | ||
738 | m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; | 728 | m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; |
739 | //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; | 729 | //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; |
740 | m_controllingClient.OnAgentUpdate += HandleAgentUpdate; | 730 | m_controllingClient.OnAgentUpdate += HandleAgentUpdate; |
@@ -1068,7 +1058,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1068 | /// <summary> | 1058 | /// <summary> |
1069 | /// Sets avatar height in the phyiscs plugin | 1059 | /// Sets avatar height in the phyiscs plugin |
1070 | /// </summary> | 1060 | /// </summary> |
1071 | internal void SetHeight(float height) | 1061 | public void SetHeight(float height) |
1072 | { | 1062 | { |
1073 | m_avHeight = height; | 1063 | m_avHeight = height; |
1074 | if (PhysicsActor != null && !IsChildAgent) | 1064 | if (PhysicsActor != null && !IsChildAgent) |
@@ -2393,15 +2383,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
2393 | // 2 stage check is needed. | 2383 | // 2 stage check is needed. |
2394 | if (remoteAvatar == null) | 2384 | if (remoteAvatar == null) |
2395 | return; | 2385 | return; |
2386 | |||
2396 | IClientAPI cl=remoteAvatar.ControllingClient; | 2387 | IClientAPI cl=remoteAvatar.ControllingClient; |
2397 | if (cl == null) | 2388 | if (cl == null) |
2398 | return; | 2389 | return; |
2390 | |||
2399 | if (m_appearance.Texture == null) | 2391 | if (m_appearance.Texture == null) |
2400 | return; | 2392 | return; |
2401 | 2393 | ||
2402 | Vector3 pos = m_pos; | 2394 | if (LocalId == remoteAvatar.LocalId) |
2403 | pos.Z += m_appearance.HipOffset; | 2395 | { |
2396 | m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); | ||
2397 | return; | ||
2398 | } | ||
2404 | 2399 | ||
2400 | if (IsChildAgent) | ||
2401 | { | ||
2402 | m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data"); | ||
2403 | return; | ||
2404 | } | ||
2405 | |||
2405 | remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); | 2406 | remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); |
2406 | m_scene.StatsReporter.AddAgentUpdates(1); | 2407 | m_scene.StatsReporter.AddAgentUpdates(1); |
2407 | } | 2408 | } |
@@ -2416,20 +2417,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
2416 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 2417 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
2417 | { | 2418 | { |
2418 | ++avUpdates; | 2419 | ++avUpdates; |
2419 | // only send if this is the root (children are only "listening posts" in a foreign region) | 2420 | |
2421 | // Don't update ourselves | ||
2422 | if (avatar.LocalId == LocalId) | ||
2423 | return; | ||
2424 | |||
2425 | // If this is a root agent, then get info about the avatar | ||
2420 | if (!IsChildAgent) | 2426 | if (!IsChildAgent) |
2421 | { | 2427 | { |
2422 | SendFullUpdateToOtherClient(avatar); | 2428 | SendFullUpdateToOtherClient(avatar); |
2423 | } | 2429 | } |
2424 | 2430 | ||
2425 | if (avatar.LocalId != LocalId) | 2431 | // If the other avatar is a root |
2432 | if (!avatar.IsChildAgent) | ||
2426 | { | 2433 | { |
2427 | if (!avatar.IsChildAgent) | 2434 | avatar.SendFullUpdateToOtherClient(this); |
2428 | { | 2435 | avatar.SendAppearanceToOtherAgent(this); |
2429 | avatar.SendFullUpdateToOtherClient(this); | 2436 | avatar.Animator.SendAnimPackToClient(ControllingClient); |
2430 | avatar.SendAppearanceToOtherAgent(this); | ||
2431 | avatar.Animator.SendAnimPackToClient(ControllingClient); | ||
2432 | } | ||
2433 | } | 2437 | } |
2434 | }); | 2438 | }); |
2435 | 2439 | ||
@@ -2444,6 +2448,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2444 | m_perfMonMS = Util.EnvironmentTickCount(); | 2448 | m_perfMonMS = Util.EnvironmentTickCount(); |
2445 | 2449 | ||
2446 | // only send update from root agents to other clients; children are only "listening posts" | 2450 | // only send update from root agents to other clients; children are only "listening posts" |
2451 | if (IsChildAgent) | ||
2452 | { | ||
2453 | m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent"); | ||
2454 | return; | ||
2455 | } | ||
2456 | |||
2447 | int count = 0; | 2457 | int count = 0; |
2448 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) | 2458 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
2449 | { | 2459 | { |
@@ -2467,29 +2477,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
2467 | // the inventory arrives | 2477 | // the inventory arrives |
2468 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); | 2478 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); |
2469 | 2479 | ||
2470 | Vector3 pos = m_pos; | ||
2471 | pos.Z += m_appearance.HipOffset; | ||
2472 | |||
2473 | m_controllingClient.SendAvatarDataImmediate(this); | 2480 | m_controllingClient.SendAvatarDataImmediate(this); |
2481 | if (m_scene.AvatarFactory != null) | ||
2482 | { | ||
2483 | if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) | ||
2484 | { | ||
2485 | m_log.WarnFormat("[SP] baked textures are in the ache for {0}",Name); | ||
2486 | m_controllingClient.SendAppearance( | ||
2487 | m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); | ||
2488 | } | ||
2489 | } | ||
2490 | else | ||
2491 | { | ||
2492 | m_log.WarnFormat("[SP] AvatarFactory not set"); | ||
2493 | } | ||
2474 | 2494 | ||
2475 | SendInitialFullUpdateToAllClients(); | 2495 | SendInitialFullUpdateToAllClients(); |
2476 | } | 2496 | } |
2477 | 2497 | ||
2478 | /// <summary> | 2498 | /// <summary> |
2479 | /// Tell the client for this scene presence what items it should be wearing now | ||
2480 | /// </summary> | ||
2481 | public void SendWearables() | ||
2482 | { | ||
2483 | m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name); | ||
2484 | |||
2485 | ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); | ||
2486 | } | ||
2487 | |||
2488 | /// <summary> | ||
2489 | /// | 2499 | /// |
2490 | /// </summary> | 2500 | /// </summary> |
2491 | public void SendAppearanceToAllOtherAgents() | 2501 | public void SendAppearanceToAllOtherAgents() |
2492 | { | 2502 | { |
2503 | // DEBUG ON | ||
2504 | m_log.WarnFormat("[SP] Send appearance from {0} to all other agents",m_uuid); | ||
2505 | // DEBUG OFF | ||
2493 | m_perfMonMS = Util.EnvironmentTickCount(); | 2506 | m_perfMonMS = Util.EnvironmentTickCount(); |
2494 | 2507 | ||
2495 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) | 2508 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) |
@@ -2509,85 +2522,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2509 | /// <param name="avatar"></param> | 2522 | /// <param name="avatar"></param> |
2510 | public void SendAppearanceToOtherAgent(ScenePresence avatar) | 2523 | public void SendAppearanceToOtherAgent(ScenePresence avatar) |
2511 | { | 2524 | { |
2512 | avatar.ControllingClient.SendAppearance( | 2525 | if (LocalId == avatar.LocalId) |
2513 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); | ||
2514 | } | ||
2515 | |||
2516 | /// <summary> | ||
2517 | /// Set appearance data (textureentry and slider settings) received from the client | ||
2518 | /// </summary> | ||
2519 | /// <param name="texture"></param> | ||
2520 | /// <param name="visualParam"></param> | ||
2521 | public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) | ||
2522 | { | ||
2523 | if (m_physicsActor != null) | ||
2524 | { | ||
2525 | if (!IsChildAgent) | ||
2526 | { | ||
2527 | // This may seem like it's redundant, remove the avatar from the physics scene | ||
2528 | // just to add it back again, but it saves us from having to update | ||
2529 | // 3 variables 10 times a second. | ||
2530 | bool flyingTemp = m_physicsActor.Flying; | ||
2531 | RemoveFromPhysicalScene(); | ||
2532 | //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); | ||
2533 | |||
2534 | //PhysicsActor = null; | ||
2535 | |||
2536 | AddToPhysicalScene(flyingTemp); | ||
2537 | } | ||
2538 | } | ||
2539 | |||
2540 | #region Bake Cache Check | ||
2541 | |||
2542 | if (textureEntry != null) | ||
2543 | { | ||
2544 | for (int i = 0; i < BAKE_INDICES.Length; i++) | ||
2545 | { | ||
2546 | int j = BAKE_INDICES[i]; | ||
2547 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; | ||
2548 | |||
2549 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
2550 | { | ||
2551 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | ||
2552 | { | ||
2553 | m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); | ||
2554 | this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); | ||
2555 | } | ||
2556 | } | ||
2557 | } | ||
2558 | |||
2559 | } | ||
2560 | |||
2561 | |||
2562 | #endregion Bake Cache Check | ||
2563 | |||
2564 | m_appearance.SetAppearance(textureEntry, visualParams); | ||
2565 | if (m_appearance.AvatarHeight > 0) | ||
2566 | SetHeight(m_appearance.AvatarHeight); | ||
2567 | |||
2568 | // This is not needed, because only the transient data changed | ||
2569 | //AvatarData adata = new AvatarData(m_appearance); | ||
2570 | //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); | ||
2571 | |||
2572 | SendAppearanceToAllOtherAgents(); | ||
2573 | if (!m_startAnimationSet) | ||
2574 | { | 2526 | { |
2575 | Animator.UpdateMovementAnimations(); | 2527 | m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); |
2576 | m_startAnimationSet = true; | 2528 | return; |
2577 | } | 2529 | } |
2578 | 2530 | ||
2579 | Vector3 pos = m_pos; | 2531 | // DEBUG ON |
2580 | pos.Z += m_appearance.HipOffset; | 2532 | // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); |
2581 | 2533 | // DEBUG OFF | |
2582 | m_controllingClient.SendAvatarDataImmediate(this); | ||
2583 | } | ||
2584 | 2534 | ||
2585 | public void SetWearable(int wearableId, AvatarWearable wearable) | 2535 | avatar.ControllingClient.SendAppearance( |
2586 | { | 2536 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); |
2587 | m_appearance.SetWearable(wearableId, wearable); | ||
2588 | AvatarData adata = new AvatarData(m_appearance); | ||
2589 | m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); | ||
2590 | m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); | ||
2591 | } | 2537 | } |
2592 | 2538 | ||
2593 | // Because appearance setting is in a module, we actually need | 2539 | // Because appearance setting is in a module, we actually need |
@@ -2983,6 +2929,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2983 | 2929 | ||
2984 | public void CopyTo(AgentData cAgent) | 2930 | public void CopyTo(AgentData cAgent) |
2985 | { | 2931 | { |
2932 | cAgent.CallbackURI = m_callbackURI; | ||
2933 | |||
2986 | cAgent.AgentID = UUID; | 2934 | cAgent.AgentID = UUID; |
2987 | cAgent.RegionID = Scene.RegionInfo.RegionID; | 2935 | cAgent.RegionID = Scene.RegionInfo.RegionID; |
2988 | 2936 | ||
@@ -3022,6 +2970,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3022 | 2970 | ||
3023 | cAgent.AlwaysRun = m_setAlwaysRun; | 2971 | cAgent.AlwaysRun = m_setAlwaysRun; |
3024 | 2972 | ||
2973 | cAgent.Appearance = new AvatarAppearance(m_appearance); | ||
2974 | |||
2975 | /* | ||
3025 | try | 2976 | try |
3026 | { | 2977 | { |
3027 | // We might not pass the Wearables in all cases... | 2978 | // We might not pass the Wearables in all cases... |
@@ -3061,14 +3012,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3061 | { | 3012 | { |
3062 | //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); | 3013 | //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); |
3063 | int i = 0; | 3014 | int i = 0; |
3064 | AttachmentData[] attachs = new AttachmentData[attPoints.Count]; | 3015 | AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count]; |
3065 | foreach (int point in attPoints) | 3016 | foreach (int point in attPoints) |
3066 | { | 3017 | { |
3067 | attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); | 3018 | attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); |
3068 | } | 3019 | } |
3069 | cAgent.Attachments = attachs; | 3020 | cAgent.Attachments = attachs; |
3070 | } | 3021 | } |
3071 | 3022 | */ | |
3072 | lock (scriptedcontrols) | 3023 | lock (scriptedcontrols) |
3073 | { | 3024 | { |
3074 | ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; | 3025 | ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; |
@@ -3095,6 +3046,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3095 | 3046 | ||
3096 | public void CopyFrom(AgentData cAgent) | 3047 | public void CopyFrom(AgentData cAgent) |
3097 | { | 3048 | { |
3049 | // DEBUG ON | ||
3050 | m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM"); | ||
3051 | // DEBUG OFF | ||
3098 | m_originRegionID = cAgent.RegionID; | 3052 | m_originRegionID = cAgent.RegionID; |
3099 | 3053 | ||
3100 | m_callbackURI = cAgent.CallbackURI; | 3054 | m_callbackURI = cAgent.CallbackURI; |
@@ -3120,6 +3074,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3120 | m_godLevel = cAgent.GodLevel; | 3074 | m_godLevel = cAgent.GodLevel; |
3121 | m_setAlwaysRun = cAgent.AlwaysRun; | 3075 | m_setAlwaysRun = cAgent.AlwaysRun; |
3122 | 3076 | ||
3077 | m_appearance = new AvatarAppearance(cAgent.Appearance); | ||
3078 | |||
3079 | /* | ||
3123 | uint i = 0; | 3080 | uint i = 0; |
3124 | try | 3081 | try |
3125 | { | 3082 | { |
@@ -3132,15 +3089,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3132 | UUID assetId = cAgent.Wearables[n + 1]; | 3089 | UUID assetId = cAgent.Wearables[n + 1]; |
3133 | wears[i++] = new AvatarWearable(itemId, assetId); | 3090 | wears[i++] = new AvatarWearable(itemId, assetId); |
3134 | } | 3091 | } |
3135 | m_appearance.Wearables = wears; | 3092 | // m_appearance.Wearables = wears; |
3136 | Primitive.TextureEntry te; | 3093 | Primitive.TextureEntry textures = null; |
3137 | if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) | 3094 | if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) |
3138 | te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); | 3095 | textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); |
3139 | else | 3096 | |
3140 | te = AvatarAppearance.GetDefaultTexture(); | 3097 | byte[] visuals = null; |
3141 | if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) | 3098 | |
3142 | cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); | 3099 | if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) |
3143 | m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); | 3100 | visuals = (byte[])cAgent.VisualParams.Clone(); |
3101 | |||
3102 | m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals); | ||
3144 | } | 3103 | } |
3145 | catch (Exception e) | 3104 | catch (Exception e) |
3146 | { | 3105 | { |
@@ -3153,14 +3112,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3153 | if (cAgent.Attachments != null) | 3112 | if (cAgent.Attachments != null) |
3154 | { | 3113 | { |
3155 | m_appearance.ClearAttachments(); | 3114 | m_appearance.ClearAttachments(); |
3156 | foreach (AttachmentData att in cAgent.Attachments) | 3115 | foreach (AvatarAttachment att in cAgent.Attachments) |
3157 | { | 3116 | { |
3158 | m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); | 3117 | m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); |
3159 | } | 3118 | } |
3160 | } | 3119 | } |
3161 | } | 3120 | } |
3162 | catch { } | 3121 | catch { } |
3163 | 3122 | */ | |
3164 | try | 3123 | try |
3165 | { | 3124 | { |
3166 | lock (scriptedcontrols) | 3125 | lock (scriptedcontrols) |
@@ -3729,15 +3688,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
3729 | return; | 3688 | return; |
3730 | } | 3689 | } |
3731 | 3690 | ||
3732 | List<int> attPoints = m_appearance.GetAttachedPoints(); | 3691 | List<AvatarAttachment> attachments = m_appearance.GetAttachments(); |
3733 | foreach (int p in attPoints) | 3692 | foreach (AvatarAttachment attach in attachments) |
3734 | { | 3693 | { |
3735 | if (m_isDeleted) | 3694 | if (m_isDeleted) |
3736 | return; | 3695 | return; |
3737 | 3696 | ||
3738 | UUID itemID = m_appearance.GetAttachedItem(p); | 3697 | int p = attach.AttachPoint; |
3698 | UUID itemID = attach.ItemID; | ||
3739 | 3699 | ||
3740 | //UUID assetID = m_appearance.GetAttachedAsset(p); | 3700 | //UUID assetID = attach.AssetID; |
3741 | // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down | 3701 | // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down |
3742 | // But they're not used anyway, the item is being looked up for now, so let's proceed. | 3702 | // But they're not used anyway, the item is being looked up for now, so let's proceed. |
3743 | //if (UUID.Zero == assetID) | 3703 | //if (UUID.Zero == assetID) |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 159af79..fc17192 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -676,7 +676,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
676 | public event TeleportLandmarkRequest OnTeleportLandmarkRequest; | 676 | public event TeleportLandmarkRequest OnTeleportLandmarkRequest; |
677 | public event DeRezObject OnDeRezObject; | 677 | public event DeRezObject OnDeRezObject; |
678 | public event Action<IClientAPI> OnRegionHandShakeReply; | 678 | public event Action<IClientAPI> OnRegionHandShakeReply; |
679 | public event GenericCall2 OnRequestWearables; | 679 | public event GenericCall1 OnRequestWearables; |
680 | public event GenericCall1 OnCompleteMovementToRegion; | 680 | public event GenericCall1 OnCompleteMovementToRegion; |
681 | public event UpdateAgent OnPreAgentUpdate; | 681 | public event UpdateAgent OnPreAgentUpdate; |
682 | public event UpdateAgent OnAgentUpdate; | 682 | public event UpdateAgent OnAgentUpdate; |
@@ -899,7 +899,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
899 | Scene scene = (Scene)Scene; | 899 | Scene scene = (Scene)Scene; |
900 | AvatarAppearance appearance; | 900 | AvatarAppearance appearance; |
901 | scene.GetAvatarAppearance(this, out appearance); | 901 | scene.GetAvatarAppearance(this, out appearance); |
902 | OnSetAppearance(appearance.Texture, (byte[])appearance.VisualParams.Clone()); | 902 | OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone()); |
903 | } | 903 | } |
904 | 904 | ||
905 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) | 905 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) |
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(); |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index fae12b6..6928c4e 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -188,7 +188,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
188 | 188 | ||
189 | public event DeRezObject OnDeRezObject; | 189 | public event DeRezObject OnDeRezObject; |
190 | public event Action<IClientAPI> OnRegionHandShakeReply; | 190 | public event Action<IClientAPI> OnRegionHandShakeReply; |
191 | public event GenericCall2 OnRequestWearables; | 191 | public event GenericCall1 OnRequestWearables; |
192 | public event GenericCall1 OnCompleteMovementToRegion; | 192 | public event GenericCall1 OnCompleteMovementToRegion; |
193 | public event UpdateAgent OnPreAgentUpdate; | 193 | public event UpdateAgent OnPreAgentUpdate; |
194 | public event UpdateAgent OnAgentUpdate; | 194 | public event UpdateAgent OnAgentUpdate; |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index ab0be77..c471636 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -64,15 +64,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
64 | if (m_appearanceCache.ContainsKey(target)) | 64 | if (m_appearanceCache.ContainsKey(target)) |
65 | return m_appearanceCache[target]; | 65 | return m_appearanceCache[target]; |
66 | 66 | ||
67 | AvatarData adata = scene.AvatarService.GetAvatar(target); | 67 | AvatarAppearance appearance = scene.AvatarService.GetAppearance(target); |
68 | if (adata != null) | 68 | if (appearance != null) |
69 | { | 69 | { |
70 | AvatarAppearance x = adata.ToAvatarAppearance(target); | 70 | m_appearanceCache.Add(target, appearance); |
71 | 71 | return appearance; | |
72 | m_appearanceCache.Add(target, x); | ||
73 | |||
74 | return x; | ||
75 | } | 72 | } |
73 | |||
76 | return new AvatarAppearance(); | 74 | return new AvatarAppearance(); |
77 | } | 75 | } |
78 | 76 | ||
@@ -169,7 +167,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
169 | { | 167 | { |
170 | AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); | 168 | AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); |
171 | 169 | ||
172 | sp.SetAppearance(x.Texture, (byte[])x.VisualParams.Clone()); | 170 | sp.Appearance.SetTextureEntries(x.Texture); |
171 | sp.Appearance.SetVisualParams((byte[])x.VisualParams.Clone()); | ||
172 | sp.SendAppearanceToAllOtherAgents(); | ||
173 | } | 173 | } |
174 | 174 | ||
175 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); | 175 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); |