aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs676
1 files changed, 338 insertions, 338 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 3614686..cb94021 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -1,338 +1,338 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28/* 28/*
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Threading; 31using System.Threading;
32using libsecondlife; 32using libsecondlife;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications.Cache; 35using OpenSim.Framework.Communications.Cache;
36using OpenSim.Data.MySQLMapper; 36using OpenSim.Data.MySQLMapper;
37using OpenSim.Region.Environment.Interfaces; 37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
39using OpenSim.Data.Base; 39using OpenSim.Data.Base;
40 40
41namespace OpenSim.Region.Environment.Modules 41namespace OpenSim.Region.Environment.Modules
42{ 42{
43 public class AvatarFactoryModule : IAvatarFactory 43 public class AvatarFactoryModule : IAvatarFactory
44 { 44 {
45 private Scene m_scene = null; 45 private Scene m_scene = null;
46 private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>(); 46 private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>();
47 47
48 private bool m_enablePersist = false; 48 private bool m_enablePersist = false;
49 private string m_connectionString; 49 private string m_connectionString;
50 private bool m_configured = false; 50 private bool m_configured = false;
51 private BaseDatabaseConnector m_databaseMapper; 51 private BaseDatabaseConnector m_databaseMapper;
52 private AppearanceTableMapper m_appearanceMapper; 52 private AppearanceTableMapper m_appearanceMapper;
53 53
54 private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>(); 54 private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>();
55 private object m_syncLock = new object(); 55 private object m_syncLock = new object();
56 56
57 public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) 57 public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance)
58 { 58 {
59 59
60 //should only let one thread at a time do this part 60 //should only let one thread at a time do this part
61 EventWaitHandle waitHandle = null; 61 EventWaitHandle waitHandle = null;
62 bool fetchInProgress = false; 62 bool fetchInProgress = false;
63 lock (m_syncLock) 63 lock (m_syncLock)
64 { 64 {
65 appearance = CheckCache(avatarId); 65 appearance = CheckCache(avatarId);
66 if (appearance != null) 66 if (appearance != null)
67 { 67 {
68 return true; 68 return true;
69 } 69 }
70 70
71 //not in cache so check to see if another thread is already fetching it 71 //not in cache so check to see if another thread is already fetching it
72 if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle)) 72 if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle))
73 { 73 {
74 fetchInProgress = true; 74 fetchInProgress = true;
75 } 75 }
76 else 76 else
77 { 77 {
78 fetchInProgress = false; 78 fetchInProgress = false;
79 79
80 //no thread already fetching this appearance, so add a wait handle to list 80 //no thread already fetching this appearance, so add a wait handle to list
81 //for any following threads that want the same appearance 81 //for any following threads that want the same appearance
82 waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); 82 waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
83 m_fetchesInProgress.Add(avatarId, waitHandle); 83 m_fetchesInProgress.Add(avatarId, waitHandle);
84 } 84 }
85 } 85 }
86 86
87 if (fetchInProgress) 87 if (fetchInProgress)
88 { 88 {
89 waitHandle.WaitOne(); 89 waitHandle.WaitOne();
90 appearance = CheckCache(avatarId); 90 appearance = CheckCache(avatarId);
91 if (appearance != null) 91 if (appearance != null)
92 { 92 {
93 waitHandle = null; 93 waitHandle = null;
94 return true; 94 return true;
95 } 95 }
96 else 96 else
97 { 97 {
98 waitHandle = null; 98 waitHandle = null;
99 return false; 99 return false;
100 } 100 }
101 } 101 }
102 else 102 else
103 { 103 {
104 Thread.Sleep(5000); 104 Thread.Sleep(5000);
105 105
106 //this is the first thread to request this appearance 106 //this is the first thread to request this appearance
107 //so let it check the db and if not found then create a default appearance 107 //so let it check the db and if not found then create a default appearance
108 //and add that to the cache 108 //and add that to the cache
109 appearance = CheckDatabase(avatarId); 109 appearance = CheckDatabase(avatarId);
110 if (appearance != null) 110 if (appearance != null)
111 { 111 {
112 //appearance has now been added to cache so lets pulse any waiting threads 112 //appearance has now been added to cache so lets pulse any waiting threads
113 lock (m_syncLock) 113 lock (m_syncLock)
114 { 114 {
115 m_fetchesInProgress.Remove(avatarId); 115 m_fetchesInProgress.Remove(avatarId);
116 waitHandle.Set(); 116 waitHandle.Set();
117 } 117 }
118 // waitHandle.Close(); 118 // waitHandle.Close();
119 waitHandle = null; 119 waitHandle = null;
120 return true; 120 return true;
121 } 121 }
122 122
123 //not found a appearance for the user, so create a new default one 123 //not found a appearance for the user, so create a new default one
124 appearance = CreateDefault(avatarId); 124 appearance = CreateDefault(avatarId);
125 if (appearance != null) 125 if (appearance != null)
126 { 126 {
127 //update database 127 //update database
128 if (m_enablePersist) 128 if (m_enablePersist)
129 { 129 {
130 m_appearanceMapper.Add(avatarId.UUID, appearance); 130 m_appearanceMapper.Add(avatarId.UUID, appearance);
131 } 131 }
132 132
133 //add appearance to dictionary cache 133 //add appearance to dictionary cache
134 lock (m_avatarsAppearance) 134 lock (m_avatarsAppearance)
135 { 135 {
136 m_avatarsAppearance[avatarId] = appearance; 136 m_avatarsAppearance[avatarId] = appearance;
137 } 137 }
138 138
139 //appearance has now been added to cache so lets pulse any waiting threads 139 //appearance has now been added to cache so lets pulse any waiting threads
140 lock (m_syncLock) 140 lock (m_syncLock)
141 { 141 {
142 m_fetchesInProgress.Remove(avatarId); 142 m_fetchesInProgress.Remove(avatarId);
143 waitHandle.Set(); 143 waitHandle.Set();
144 } 144 }
145 // waitHandle.Close(); 145 // waitHandle.Close();
146 waitHandle = null; 146 waitHandle = null;
147 return true; 147 return true;
148 } 148 }
149 else 149 else
150 { 150 {
151 //something went wrong, so release the wait handle and remove it 151 //something went wrong, so release the wait handle and remove it
152 //all waiting threads will fail to find cached appearance 152 //all waiting threads will fail to find cached appearance
153 //but its better for them to fail than wait for ever 153 //but its better for them to fail than wait for ever
154 lock (m_syncLock) 154 lock (m_syncLock)
155 { 155 {
156 m_fetchesInProgress.Remove(avatarId); 156 m_fetchesInProgress.Remove(avatarId);
157 waitHandle.Set(); 157 waitHandle.Set();
158 } 158 }
159 //waitHandle.Close(); 159 //waitHandle.Close();
160 waitHandle = null; 160 waitHandle = null;
161 return false; 161 return false;
162 } 162 }
163 } 163 }
164 } 164 }
165 165
166 private AvatarAppearance CreateDefault(LLUUID avatarId) 166 private AvatarAppearance CreateDefault(LLUUID avatarId)
167 { 167 {
168 AvatarAppearance appearance = null; 168 AvatarAppearance appearance = null;
169 AvatarWearable[] wearables; 169 AvatarWearable[] wearables;
170 byte[] visualParams; 170 byte[] visualParams;
171 GetDefaultAvatarAppearance(out wearables, out visualParams); 171 GetDefaultAvatarAppearance(out wearables, out visualParams);
172 appearance = new AvatarAppearance(avatarId, wearables, visualParams); 172 appearance = new AvatarAppearance(avatarId, wearables, visualParams);
173 173
174 return appearance; 174 return appearance;
175 } 175 }
176 176
177 private AvatarAppearance CheckDatabase(LLUUID avatarId) 177 private AvatarAppearance CheckDatabase(LLUUID avatarId)
178 { 178 {
179 AvatarAppearance appearance = null; 179 AvatarAppearance appearance = null;
180 if (m_enablePersist) 180 if (m_enablePersist)
181 { 181 {
182 if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance)) 182 if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance))
183 { 183 {
184 appearance.VisualParams = GetDefaultVisualParams(); 184 appearance.VisualParams = GetDefaultVisualParams();
185 appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry(); 185 appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry();
186 lock (m_avatarsAppearance) 186 lock (m_avatarsAppearance)
187 { 187 {
188 m_avatarsAppearance[avatarId] = appearance; 188 m_avatarsAppearance[avatarId] = appearance;
189 } 189 }
190 } 190 }
191 } 191 }
192 return appearance; 192 return appearance;
193 } 193 }
194 194
195 private AvatarAppearance CheckCache(LLUUID avatarId) 195 private AvatarAppearance CheckCache(LLUUID avatarId)
196 { 196 {
197 AvatarAppearance appearance = null; 197 AvatarAppearance appearance = null;
198 lock (m_avatarsAppearance) 198 lock (m_avatarsAppearance)
199 { 199 {
200 if (m_avatarsAppearance.ContainsKey(avatarId)) 200 if (m_avatarsAppearance.ContainsKey(avatarId))
201 { 201 {
202 appearance = m_avatarsAppearance[avatarId]; 202 appearance = m_avatarsAppearance[avatarId];
203 } 203 }
204 } 204 }
205 return appearance; 205 return appearance;
206 } 206 }
207 207
208 public void Initialise(Scene scene, IConfigSource source) 208 public void Initialise(Scene scene, IConfigSource source)
209 { 209 {
210 scene.RegisterModuleInterface<IAvatarFactory>(this); 210 scene.RegisterModuleInterface<IAvatarFactory>(this);
211 scene.EventManager.OnNewClient += NewClient; 211 scene.EventManager.OnNewClient += NewClient;
212 212
213 if (m_scene == null) 213 if (m_scene == null)
214 { 214 {
215 m_scene = scene; 215 m_scene = scene;
216 } 216 }
217 217
218 if (!m_configured) 218 if (!m_configured)
219 { 219 {
220 m_configured = true; 220 m_configured = true;
221 try 221 try
222 { 222 {
223 m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false); 223 m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false);
224 m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", ""); 224 m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", "");
225 } 225 }
226 catch (Exception) 226 catch (Exception)
227 { 227 {
228 } 228 }
229 if (m_enablePersist) 229 if (m_enablePersist)
230 { 230 {
231 m_databaseMapper = new MySQLDatabaseMapper(m_connectionString); 231 m_databaseMapper = new MySQLDatabaseMapper(m_connectionString);
232 m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance"); 232 m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance");
233 } 233 }
234 } 234 }
235 } 235 }
236 236
237 public void PostInitialise() 237 public void PostInitialise()
238 { 238 {
239 } 239 }
240 240
241 public void Close() 241 public void Close()
242 { 242 {
243 } 243 }
244 244
245 public string Name 245 public string Name
246 { 246 {
247 get { return "Default Avatar Factory"; } 247 get { return "Default Avatar Factory"; }
248 } 248 }
249 249
250 public bool IsSharedModule 250 public bool IsSharedModule
251 { 251 {
252 get { return true; } 252 get { return true; }
253 } 253 }
254 254
255 public void NewClient(IClientAPI client) 255 public void NewClient(IClientAPI client)
256 { 256 {
257 client.OnAvatarNowWearing += AvatarIsWearing; 257 client.OnAvatarNowWearing += AvatarIsWearing;
258 } 258 }
259 259
260 public void RemoveClient(IClientAPI client) 260 public void RemoveClient(IClientAPI client)
261 { 261 {
262 // client.OnAvatarNowWearing -= AvatarIsWearing; 262 // client.OnAvatarNowWearing -= AvatarIsWearing;
263 } 263 }
264 264
265 public void AvatarIsWearing(Object sender, AvatarWearingArgs e) 265 public void AvatarIsWearing(Object sender, AvatarWearingArgs e)
266 { 266 {
267 IClientAPI clientView = (IClientAPI)sender; 267 IClientAPI clientView = (IClientAPI)sender;
268 CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId); 268 CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId);
269 if (profile != null) 269 if (profile != null)
270 { 270 {
271 if (profile.RootFolder != null) 271 if (profile.RootFolder != null)
272 { 272 {
273 if (m_avatarsAppearance.ContainsKey(clientView.AgentId)) 273 if (m_avatarsAppearance.ContainsKey(clientView.AgentId))
274 { 274 {
275 AvatarAppearance avatAppearance = null; 275 AvatarAppearance avatAppearance = null;
276 lock (m_avatarsAppearance) 276 lock (m_avatarsAppearance)
277 { 277 {
278 avatAppearance = m_avatarsAppearance[clientView.AgentId]; 278 avatAppearance = m_avatarsAppearance[clientView.AgentId];
279 } 279 }
280 280
281 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 281 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
282 { 282 {
283 if (wear.Type < 13) 283 if (wear.Type < 13)
284 { 284 {
285 if (wear.ItemID == LLUUID.Zero) 285 if (wear.ItemID == LLUUID.Zero)
286 { 286 {
287 avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero; 287 avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero;
288 avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero; 288 avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero;
289 289
290 UpdateDatabase(clientView.AgentId, avatAppearance); 290 UpdateDatabase(clientView.AgentId, avatAppearance);
291 } 291 }
292 else 292 else
293 { 293 {
294 LLUUID assetId; 294 LLUUID assetId;
295 295
296 InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID); 296 InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID);
297 if (baseItem != null) 297 if (baseItem != null)
298 { 298 {
299 assetId = baseItem.assetID; 299 assetId = baseItem.assetID;
300 avatAppearance.Wearables[wear.Type].AssetID = assetId; 300 avatAppearance.Wearables[wear.Type].AssetID = assetId;
301 avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; 301 avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID;
302 302
303 UpdateDatabase(clientView.AgentId, avatAppearance); 303 UpdateDatabase(clientView.AgentId, avatAppearance);
304 } 304 }
305 } 305 }
306 } 306 }
307 } 307 }
308 } 308 }
309 } 309 }
310 } 310 }
311 } 311 }
312 312
313 public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance) 313 public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance)
314 { 314 {
315 if (m_enablePersist) 315 if (m_enablePersist)
316 { 316 {
317 m_appearanceMapper.Update(userID.UUID, avatAppearance); 317 m_appearanceMapper.Update(userID.UUID, avatAppearance);
318 } 318 }
319 } 319 }
320 320
321 public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) 321 public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
322 { 322 {
323 visualParams = GetDefaultVisualParams(); 323 visualParams = GetDefaultVisualParams();
324 wearables = AvatarWearable.DefaultWearables; 324 wearables = AvatarWearable.DefaultWearables;
325 } 325 }
326 326
327 private static byte[] GetDefaultVisualParams() 327 private static byte[] GetDefaultVisualParams()
328 { 328 {
329 byte[] visualParams; 329 byte[] visualParams;
330 visualParams = new byte[218]; 330 visualParams = new byte[218];
331 for (int i = 0; i < 218; i++) 331 for (int i = 0; i < 218; i++)
332 { 332 {
333 visualParams[i] = 100; 333 visualParams[i] = 100;
334 } 334 }
335 return visualParams; 335 return visualParams;
336 } 336 }
337 } 337 }
338}*/ 338}*/